diff options
Diffstat (limited to 'servers')
185 files changed, 7059 insertions, 6612 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index ed67e8902a..ff0d2cad65 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -34,17 +34,16 @@ #include "core/project_settings.h" Error AudioDriverDummy::init() { - active = false; thread_exited = false; exit_thread = false; samples_in = nullptr; - mix_rate = DEFAULT_MIX_RATE; + mix_rate = GLOBAL_GET("audio/mix_rate"); speaker_mode = SPEAKER_MODE_STEREO; channels = 2; - int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + int latency = GLOBAL_GET("audio/output_latency"); buffer_frames = closest_power_of_2(latency * mix_rate / 1000); samples_in = memnew_arr(int32_t, buffer_frames * channels); @@ -55,15 +54,12 @@ Error AudioDriverDummy::init() { }; void AudioDriverDummy::thread_func(void *p_udata) { - AudioDriverDummy *ad = (AudioDriverDummy *)p_udata; uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000; while (!ad->exit_thread) { - if (ad->active) { - ad->lock(); ad->audio_server_process(ad->buffer_frames, ad->samples_in); @@ -78,38 +74,35 @@ void AudioDriverDummy::thread_func(void *p_udata) { }; void AudioDriverDummy::start() { - active = true; }; int AudioDriverDummy::get_mix_rate() const { - return mix_rate; }; AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const { - return speaker_mode; }; void AudioDriverDummy::lock() { - - if (!thread) + if (!thread) { return; + } mutex.lock(); }; void AudioDriverDummy::unlock() { - - if (!thread) + if (!thread) { return; + } mutex.unlock(); }; void AudioDriverDummy::finish() { - - if (!thread) + if (!thread) { return; + } exit_thread = true; Thread::wait_to_finish(thread); @@ -121,12 +114,3 @@ void AudioDriverDummy::finish() { memdelete(thread); thread = nullptr; }; - -AudioDriverDummy::AudioDriverDummy() { - - thread = nullptr; -}; - -AudioDriverDummy::~AudioDriverDummy(){ - -}; diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index a2cd9b2dc6..84a566e420 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -37,8 +37,7 @@ #include "core/os/thread.h" class AudioDriverDummy : public AudioDriver { - - Thread *thread; + Thread *thread = nullptr; Mutex mutex; int32_t *samples_in; @@ -68,8 +67,8 @@ public: virtual void unlock(); virtual void finish(); - AudioDriverDummy(); - ~AudioDriverDummy(); + AudioDriverDummy() {} + ~AudioDriverDummy() {} }; #endif diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp index 2771fc177b..f5eafb7e60 100644 --- a/servers/audio/audio_filter_sw.cpp +++ b/servers/audio/audio_filter_sw.cpp @@ -31,34 +31,32 @@ #include "audio_filter_sw.h" void AudioFilterSW::set_mode(Mode p_mode) { - mode = p_mode; } -void AudioFilterSW::set_cutoff(float p_cutoff) { +void AudioFilterSW::set_cutoff(float p_cutoff) { cutoff = p_cutoff; } -void AudioFilterSW::set_resonance(float p_resonance) { +void AudioFilterSW::set_resonance(float p_resonance) { resonance = p_resonance; } void AudioFilterSW::set_gain(float p_gain) { - gain = p_gain; } void AudioFilterSW::set_sampling_rate(float p_srate) { - sampling_rate = p_srate; } void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { - int sr_limit = (sampling_rate / 2) + 512; double final_cutoff = (cutoff > sr_limit) ? sr_limit : cutoff; - if (final_cutoff < 1) final_cutoff = 1; //don't allow less than this + if (final_cutoff < 1) { + final_cutoff = 1; //don't allow less than this + } double omega = 2.0 * Math_PI * final_cutoff / sampling_rate; @@ -70,18 +68,19 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { Q = 0.0001; } - if (mode == BANDPASS) + if (mode == BANDPASS) { Q *= 2.0; - else if (mode == PEAK) + } else if (mode == PEAK) { Q *= 3.0; + } double tmpgain = gain; - if (tmpgain < 0.001) + if (tmpgain < 0.001) { tmpgain = 0.001; + } if (stages > 1) { - Q = (Q > 1.0 ? Math::pow(Q, 1.0 / stages) : Q); tmpgain = Math::pow(tmpgain, 1.0 / (stages + 1)); } @@ -90,9 +89,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { double a0 = 1.0 + alpha; switch (mode) { - case LOWPASS: { - p_coeffs->b0 = (1.0 - cos_v) / 2.0; p_coeffs->b1 = 1.0 - cos_v; p_coeffs->b2 = (1.0 - cos_v) / 2.0; @@ -101,7 +98,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { } break; case HIGHPASS: { - p_coeffs->b0 = (1.0 + cos_v) / 2.0; p_coeffs->b1 = -(1.0 + cos_v); p_coeffs->b2 = (1.0 + cos_v) / 2.0; @@ -110,7 +106,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { } break; case BANDPASS: { - p_coeffs->b0 = alpha * sqrt(Q + 1); p_coeffs->b1 = 0.0; p_coeffs->b2 = -alpha * sqrt(Q + 1); @@ -119,7 +114,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { } break; case NOTCH: { - p_coeffs->b0 = 1.0; p_coeffs->b1 = -2.0 * cos_v; p_coeffs->b2 = 1.0; @@ -150,10 +144,10 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { } break; case LOWSHELF: { - double tmpq = Math::sqrt(Q); - if (tmpq <= 0) + if (tmpq <= 0) { tmpq = 0.001; + } double beta = Math::sqrt(tmpgain) / tmpq; a0 = (tmpgain + 1.0) + (tmpgain - 1.0) * cos_v + beta * sin_v; @@ -166,8 +160,9 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) { } break; case HIGHSHELF: { double tmpq = Math::sqrt(Q); - if (tmpq <= 0) + if (tmpq <= 0) { tmpq = 0.001; + } double beta = Math::sqrt(tmpgain) / tmpq; a0 = (tmpgain + 1.0) - (tmpgain - 1.0) * cos_v + beta * sin_v; @@ -202,7 +197,6 @@ void AudioFilterSW::set_stages(int p_stages) { //adjust for multiple stages /* Fouriertransform kernel to obtain response */ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) { - float freq = p_freq / sampling_rate * Math_PI * 2.0f; float cx = p_coeffs->b0, cy = 0.0; @@ -226,7 +220,6 @@ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) { } AudioFilterSW::AudioFilterSW() { - sampling_rate = 44100; resonance = 0.5; cutoff = 5000; @@ -236,12 +229,10 @@ AudioFilterSW::AudioFilterSW() { } AudioFilterSW::Processor::Processor() { - set_filter(nullptr); } void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_history) { - if (p_clear_history) { ha1 = ha2 = hb1 = hb2 = 0; } @@ -249,9 +240,9 @@ void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_ } void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) { - - if (!filter) + if (!filter) { return; + } if (p_interp_buffer_len) { //interpolate Coeffs old_coeffs = coeffs; @@ -268,19 +259,17 @@ void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) { } void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride, bool p_interpolate) { - - if (!filter) + if (!filter) { return; + } if (p_interpolate) { for (int i = 0; i < p_amount; i++) { - process_one_interp(*p_samples); p_samples += p_stride; } } else { for (int i = 0; i < p_amount; i++) { - process_one(*p_samples); p_samples += p_stride; } diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h index 61088eec55..a7f570fbb4 100644 --- a/servers/audio/audio_filter_sw.h +++ b/servers/audio/audio_filter_sw.h @@ -36,7 +36,6 @@ class AudioFilterSW { public: struct Coeffs { - float a1, a2; float b0, b1, b2; @@ -99,7 +98,6 @@ public: /* inline methods */ void AudioFilterSW::Processor::process_one(float &p_sample) { - float pre = p_sample; p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2); ha2 = ha1; @@ -109,7 +107,6 @@ void AudioFilterSW::Processor::process_one(float &p_sample) { } void AudioFilterSW::Processor::process_one_interp(float &p_sample) { - float pre = p_sample; p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2); ha2 = ha1; diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index 0ac7ddc7a9..7613e70e64 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -34,9 +34,9 @@ #include "servers/audio_server.h" int AudioRBResampler::get_channel_count() const { - - if (!rb) + if (!rb) { return 0; + } return channels; } @@ -46,11 +46,9 @@ int AudioRBResampler::get_channel_count() const { // but it wasn't obvious to integrate that with VideoPlayer template <int C> uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) { - uint32_t read = offset & MIX_FRAC_MASK; for (int i = 0; i < p_todo; i++) { - offset = (offset + p_increment) & (((1 << (rb_bits + MIX_FRAC_BITS)) - 1)); read += p_increment; uint32_t pos = offset >> MIX_FRAC_BITS; @@ -60,7 +58,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i // since this is a template with a known compile time value (C), conditionals go away when compiling. if (C == 1) { - float v0 = rb[pos]; float v0n = rb[pos_next]; v0 += (v0n - v0) * frac; @@ -68,7 +65,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i } if (C == 2) { - float v0 = rb[(pos << 1) + 0]; float v1 = rb[(pos << 1) + 1]; float v0n = rb[(pos_next << 1) + 0]; @@ -81,7 +77,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i // 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 v0n = rb[(pos_next << 2) + 0]; @@ -92,7 +87,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i } if (C == 6) { - float v0 = rb[(pos * 6) + 0]; float v1 = rb[(pos * 6) + 1]; float v0n = rb[(pos_next * 6) + 0]; @@ -108,9 +102,9 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i } bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) { - - if (!rb) + if (!rb) { return false; + } int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate; int read_space = get_reader_space(); @@ -119,14 +113,23 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) { { int src_read = 0; switch (channels) { - case 1: src_read = _resample<1>(p_dest, target_todo, increment); break; - case 2: src_read = _resample<2>(p_dest, target_todo, increment); break; - case 4: src_read = _resample<4>(p_dest, target_todo, increment); break; - case 6: src_read = _resample<6>(p_dest, target_todo, increment); break; + case 1: + src_read = _resample<1>(p_dest, target_todo, increment); + break; + case 2: + src_read = _resample<2>(p_dest, target_todo, increment); + break; + case 4: + src_read = _resample<4>(p_dest, target_todo, increment); + break; + case 6: + src_read = _resample<6>(p_dest, target_todo, increment); + break; } - if (src_read > read_space) + if (src_read > read_space) { src_read = read_space; + } rb_read_pos = (rb_read_pos + src_read) & rb_mask; @@ -147,15 +150,15 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) { } int AudioRBResampler::get_num_of_ready_frames() { - if (!is_ready()) + if (!is_ready()) { return 0; + } int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate; int read_space = get_reader_space(); return (int64_t(read_space) << MIX_FRAC_BITS) / increment; } Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) { - ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6, ERR_INVALID_PARAMETER); int desired_rb_bits = nearest_shift(MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed)); @@ -163,14 +166,12 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m bool recreate = !rb; if (rb && (uint32_t(desired_rb_bits) != rb_bits || channels != uint32_t(p_channels))) { - memdelete_arr(rb); memdelete_arr(read_buf); recreate = true; } if (recreate) { - channels = p_channels; rb_bits = desired_rb_bits; rb_len = (1 << rb_bits); @@ -187,7 +188,6 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m //avoid maybe strange noises upon load for (unsigned int i = 0; i < (rb_len * channels); i++) { - rb[i] = 0; read_buf[i] = 0; } @@ -196,9 +196,9 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m } void AudioRBResampler::clear() { - - if (!rb) + if (!rb) { return; + } //should be stopped at this point but just in case memdelete_arr(rb); @@ -211,7 +211,6 @@ void AudioRBResampler::clear() { } AudioRBResampler::AudioRBResampler() { - rb = nullptr; offset = 0; read_buf = nullptr; @@ -228,7 +227,6 @@ AudioRBResampler::AudioRBResampler() { } AudioRBResampler::~AudioRBResampler() { - if (rb) { memdelete_arr(rb); memdelete_arr(read_buf); diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h index 40cf3e4cd7..12ec526adb 100644 --- a/servers/audio/audio_rb_resampler.h +++ b/servers/audio/audio_rb_resampler.h @@ -36,7 +36,6 @@ #include "servers/audio_server.h" struct AudioRBResampler { - uint32_t rb_bits; uint32_t rb_len; uint32_t rb_mask; @@ -116,31 +115,24 @@ public: _FORCE_INLINE_ float *get_write_buffer() { return read_buf; } _FORCE_INLINE_ void write(uint32_t p_frames) { - ERR_FAIL_COND(p_frames >= rb_len); switch (channels) { case 1: { - for (uint32_t i = 0; i < p_frames; i++) { - rb[rb_write_pos] = read_buf[i]; rb_write_pos = (rb_write_pos + 1) & rb_mask; } } break; case 2: { - for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos << 1) + 0] = read_buf[(i << 1) + 0]; rb[(rb_write_pos << 1) + 1] = read_buf[(i << 1) + 1]; rb_write_pos = (rb_write_pos + 1) & rb_mask; } } break; case 4: { - for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos << 2) + 0] = read_buf[(i << 2) + 0]; rb[(rb_write_pos << 2) + 1] = read_buf[(i << 2) + 1]; rb[(rb_write_pos << 2) + 2] = read_buf[(i << 2) + 2]; @@ -149,9 +141,7 @@ public: } } break; case 6: { - for (uint32_t i = 0; i < p_frames; i++) { - rb[(rb_write_pos * 6) + 0] = read_buf[(i * 6) + 0]; rb[(rb_write_pos * 6) + 1] = read_buf[(i * 6) + 1]; rb[(rb_write_pos * 6) + 2] = read_buf[(i * 6) + 2]; diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 46e674fd9b..2cc2f5c291 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -36,7 +36,6 @@ ////////////////////////////// void AudioStreamPlaybackResampled::_begin_resample() { - //clear cubic interpolation history internal_buffer[0] = AudioFrame(0.0, 0.0); internal_buffer[1] = AudioFrame(0.0, 0.0); @@ -48,14 +47,12 @@ void AudioStreamPlaybackResampled::_begin_resample() { } void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { - float target_rate = AudioServer::get_singleton()->get_mix_rate(); float global_rate_scale = AudioServer::get_singleton()->get_global_rate_scale(); uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale) / double(target_rate * global_rate_scale)) * double(FP_LEN)); for (int i = 0; i < p_frames; i++) { - uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS); //standard cubic interpolation (great quality/performance ratio) //this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory. @@ -76,7 +73,6 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, mix_offset += mix_increment; while ((mix_offset >> FP_BITS) >= INTERNAL_BUFFER_LEN) { - internal_buffer[0] = internal_buffer[INTERNAL_BUFFER_LEN + 0]; internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1]; internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2]; @@ -97,7 +93,6 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, //////////////////////////////// void AudioStream::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length); } @@ -116,7 +111,6 @@ Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() { } String AudioStreamMicrophone::get_stream_name() const { - //if (audio_stream.is_valid()) { //return "Random: " + audio_stream->get_name(); //} @@ -134,7 +128,6 @@ AudioStreamMicrophone::AudioStreamMicrophone() { } void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) { - AudioDriver::get_singleton()->lock(); Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer(); @@ -187,7 +180,6 @@ float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() { } void AudioStreamPlaybackMicrophone::start(float p_from_pos) { - if (active) { return; } @@ -239,7 +231,6 @@ AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() { //////////////////////////////// void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) { - audio_stream = p_audio_stream; if (audio_stream.is_valid()) { for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) { @@ -249,14 +240,13 @@ void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_st } Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const { - return audio_stream; } void AudioStreamRandomPitch::set_random_pitch(float p_pitch) { - - if (p_pitch < 1) + if (p_pitch < 1) { p_pitch = 1; + } random_pitch = p_pitch; } @@ -267,8 +257,9 @@ float AudioStreamRandomPitch::get_random_pitch() const { Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() { Ref<AudioStreamPlaybackRandomPitch> playback; playback.instance(); - if (audio_stream.is_valid()) + if (audio_stream.is_valid()) { playback->playback = audio_stream->instance_playback(); + } playbacks.insert(playback.ptr()); playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this); @@ -276,7 +267,6 @@ Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() { } String AudioStreamRandomPitch::get_stream_name() const { - if (audio_stream.is_valid()) { return "Random: " + audio_stream->get_name(); } @@ -292,7 +282,6 @@ float AudioStreamRandomPitch::get_length() const { } void AudioStreamRandomPitch::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream); ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream); @@ -325,6 +314,7 @@ void AudioStreamPlaybackRandomPitch::stop() { ; } } + bool AudioStreamPlaybackRandomPitch::is_playing() const { if (playing.is_valid()) { return playing->is_playing(); @@ -348,6 +338,7 @@ float AudioStreamPlaybackRandomPitch::get_playback_position() const { return 0; } + void AudioStreamPlaybackRandomPitch::seek(float p_time) { if (playing.is_valid()) { playing->seek(p_time); diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 155b683d7d..fc66fd1ff7 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -37,7 +37,6 @@ #include "servers/audio_server.h" class AudioStreamPlayback : public Reference { - GDCLASS(AudioStreamPlayback, Reference); public: @@ -54,7 +53,6 @@ public: }; class AudioStreamPlaybackResampled : public AudioStreamPlayback { - GDCLASS(AudioStreamPlaybackResampled, AudioStreamPlayback); enum { @@ -80,7 +78,6 @@ public: }; class AudioStream : public Resource { - GDCLASS(AudioStream, Resource); OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged. @@ -99,7 +96,6 @@ public: class AudioStreamPlaybackMicrophone; class AudioStreamMicrophone : public AudioStream { - GDCLASS(AudioStreamMicrophone, AudioStream); friend class AudioStreamPlaybackMicrophone; @@ -118,7 +114,6 @@ public: }; class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled { - GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlaybackResampled); friend class AudioStreamMicrophone; @@ -152,7 +147,6 @@ public: class AudioStreamPlaybackRandomPitch; class AudioStreamRandomPitch : public AudioStream { - GDCLASS(AudioStreamRandomPitch, AudioStream); friend class AudioStreamPlaybackRandomPitch; @@ -179,7 +173,6 @@ public: }; class AudioStreamPlaybackRandomPitch : public AudioStreamPlayback { - GDCLASS(AudioStreamPlaybackRandomPitch, AudioStreamPlayback); friend class AudioStreamRandomPitch; diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp index 8ad2ecc5ce..74fdcbc67a 100644 --- a/servers/audio/effects/audio_effect_amplify.cpp +++ b/servers/audio/effects/audio_effect_amplify.cpp @@ -31,7 +31,6 @@ #include "audio_effect_amplify.h" void AudioEffectAmplifyInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - //multiply volume interpolating to avoid clicks if this changes float volume_db = base->volume_db; float vol = Math::db2linear(mix_volume_db); @@ -58,12 +57,10 @@ void AudioEffectAmplify::set_volume_db(float p_volume) { } float AudioEffectAmplify::get_volume_db() const { - return volume_db; } void AudioEffectAmplify::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_volume_db", "volume"), &AudioEffectAmplify::set_volume_db); ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioEffectAmplify::get_volume_db); diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp index 34c03dca8d..2b530475f0 100644 --- a/servers/audio/effects/audio_effect_chorus.cpp +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -33,11 +33,9 @@ #include "servers/audio_server.h" void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - int todo = p_frame_count; while (todo) { - int to_mix = MIN(todo, 256); //can't mix too much _process_chunk(p_src_frames, p_dst_frames, to_mix); @@ -50,7 +48,6 @@ void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames, AudioFra } void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - //fill ringbuffer for (int i = 0; i < p_frame_count; i++) { audio_buffer.write[(buffer_pos + i) & buffer_mask] = p_src_frames[i]; @@ -61,7 +58,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A /* process voices */ for (int vc = 0; vc < base->voice_count; vc++) { - AudioEffectChorus::Voice &v = base->voice[vc]; double time_to_mix = (float)p_frame_count / mix_rate; @@ -85,8 +81,9 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A } //low pass filter - if (v.cutoff == 0) + if (v.cutoff == 0) { continue; + } float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate); float c1 = 1.0 - auxlp; float c2 = auxlp; @@ -103,7 +100,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A vol_modifier.r *= CLAMP(1.0 + v.pan, 0, 1); for (int i = 0; i < p_frame_count; i++) { - /** COMPUTE WAVEFORM **/ float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC); @@ -146,7 +142,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A } Ref<AudioEffectInstance> AudioEffectChorus::instance() { - Ref<AudioEffectChorusInstance> ins; ins.instance(); ins->base = Ref<AudioEffectChorus>(this); @@ -182,24 +177,21 @@ Ref<AudioEffectInstance> AudioEffectChorus::instance() { } void AudioEffectChorus::set_voice_count(int p_voices) { - ERR_FAIL_COND(p_voices < 1 || p_voices > MAX_VOICES); voice_count = p_voices; } int AudioEffectChorus::get_voice_count() const { - return voice_count; } void AudioEffectChorus::set_voice_delay_ms(int p_voice, float p_delay_ms) { - ERR_FAIL_INDEX(p_voice, MAX_VOICES); voice[p_voice].delay = p_delay_ms; } -float AudioEffectChorus::get_voice_delay_ms(int p_voice) const { +float AudioEffectChorus::get_voice_delay_ms(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].delay; } @@ -209,85 +201,78 @@ void AudioEffectChorus::set_voice_rate_hz(int p_voice, float p_rate_hz) { voice[p_voice].rate = p_rate_hz; } -float AudioEffectChorus::get_voice_rate_hz(int p_voice) const { +float AudioEffectChorus::get_voice_rate_hz(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].rate; } void AudioEffectChorus::set_voice_depth_ms(int p_voice, float p_depth_ms) { - ERR_FAIL_INDEX(p_voice, MAX_VOICES); voice[p_voice].depth = p_depth_ms; } -float AudioEffectChorus::get_voice_depth_ms(int p_voice) const { +float AudioEffectChorus::get_voice_depth_ms(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].depth; } void AudioEffectChorus::set_voice_level_db(int p_voice, float p_level_db) { - ERR_FAIL_INDEX(p_voice, MAX_VOICES); voice[p_voice].level = p_level_db; } -float AudioEffectChorus::get_voice_level_db(int p_voice) const { +float AudioEffectChorus::get_voice_level_db(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].level; } void AudioEffectChorus::set_voice_cutoff_hz(int p_voice, float p_cutoff_hz) { - ERR_FAIL_INDEX(p_voice, MAX_VOICES); voice[p_voice].cutoff = p_cutoff_hz; } -float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const { +float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].cutoff; } void AudioEffectChorus::set_voice_pan(int p_voice, float p_pan) { - ERR_FAIL_INDEX(p_voice, MAX_VOICES); voice[p_voice].pan = p_pan; } -float AudioEffectChorus::get_voice_pan(int p_voice) const { +float AudioEffectChorus::get_voice_pan(int p_voice) const { ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0); return voice[p_voice].pan; } void AudioEffectChorus::set_wet(float amount) { - wet = amount; } -float AudioEffectChorus::get_wet() const { +float AudioEffectChorus::get_wet() const { return wet; } void AudioEffectChorus::set_dry(float amount) { - dry = amount; } -float AudioEffectChorus::get_dry() const { +float AudioEffectChorus::get_dry() const { return dry; } void AudioEffectChorus::_validate_property(PropertyInfo &property) const { - if (property.name.begins_with("voice/")) { int voice_idx = property.name.get_slice("/", 1).to_int(); if (voice_idx > voice_count) { @@ -297,7 +282,6 @@ void AudioEffectChorus::_validate_property(PropertyInfo &property) const { } void AudioEffectChorus::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_voice_count", "voices"), &AudioEffectChorus::set_voice_count); ClassDB::bind_method(D_METHOD("get_voice_count"), &AudioEffectChorus::get_voice_count); diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h index ab5053b919..4d15c518d6 100644 --- a/servers/audio/effects/audio_effect_chorus.h +++ b/servers/audio/effects/audio_effect_chorus.h @@ -73,7 +73,6 @@ public: private: struct Voice { - float delay; float rate; float depth; @@ -82,7 +81,6 @@ private: float pan; Voice() { - delay = 12.0; rate = 1; depth = 0; diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp index 8d54bd8e36..4b0b4dabea 100644 --- a/servers/audio/effects/audio_effect_compressor.cpp +++ b/servers/audio/effects/audio_effect_compressor.cpp @@ -32,7 +32,6 @@ #include "servers/audio_server.h" void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float threshold = Math::db2linear(base->threshold); float sample_rate = AudioServer::get_singleton()->get_mix_rate(); @@ -51,7 +50,6 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi const AudioFrame *src = p_src_frames; if (base->sidechain != StringName() && current_channel != -1) { - int bus = AudioServer::get_singleton()->thread_find_bus_index(base->sidechain); if (bus >= 0) { src = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus, current_channel); @@ -59,7 +57,6 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi } for (int i = 0; i < p_frame_count; i++) { - AudioFrame s = src[i]; //convert to positive s.l = Math::abs(s.l); @@ -69,11 +66,13 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi float overdb = 2.08136898f * Math::linear2db(peak / threshold); - if (overdb < 0.0) //we only care about what goes over to compress + if (overdb < 0.0) { //we only care about what goes over to compress overdb = 0.0; + } - if (overdb - rundb > 5) // diffeence is too large + if (overdb - rundb > 5) { // diffeence is too large averatio = 4; + } if (overdb > rundb) { rundb = overdb + atcoef * (rundb - overdb); @@ -104,8 +103,9 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi gr_meter = grv; } else { gr_meter *= gr_meter_decay; - if (gr_meter > 1) + if (gr_meter > 1) { gr_meter = 1; + } } p_dst_frames[i] = p_src_frames[i] * grv * makeup * mix + p_src_frames[i] * (1.0 - mix); @@ -127,76 +127,65 @@ Ref<AudioEffectInstance> AudioEffectCompressor::instance() { } void AudioEffectCompressor::set_threshold(float p_threshold) { - threshold = p_threshold; } float AudioEffectCompressor::get_threshold() const { - return threshold; } void AudioEffectCompressor::set_ratio(float p_ratio) { - ratio = p_ratio; } -float AudioEffectCompressor::get_ratio() const { +float AudioEffectCompressor::get_ratio() const { return ratio; } void AudioEffectCompressor::set_gain(float p_gain) { - gain = p_gain; } -float AudioEffectCompressor::get_gain() const { +float AudioEffectCompressor::get_gain() const { return gain; } void AudioEffectCompressor::set_attack_us(float p_attack_us) { - attack_us = p_attack_us; } -float AudioEffectCompressor::get_attack_us() const { +float AudioEffectCompressor::get_attack_us() const { return attack_us; } void AudioEffectCompressor::set_release_ms(float p_release_ms) { - release_ms = p_release_ms; } -float AudioEffectCompressor::get_release_ms() const { +float AudioEffectCompressor::get_release_ms() const { return release_ms; } void AudioEffectCompressor::set_mix(float p_mix) { - mix = p_mix; } -float AudioEffectCompressor::get_mix() const { +float AudioEffectCompressor::get_mix() const { return mix; } void AudioEffectCompressor::set_sidechain(const StringName &p_sidechain) { - AudioServer::get_singleton()->lock(); sidechain = p_sidechain; AudioServer::get_singleton()->unlock(); } StringName AudioEffectCompressor::get_sidechain() const { - return sidechain; } void AudioEffectCompressor::_validate_property(PropertyInfo &property) const { - if (property.name == "sidechain") { - String buses = ""; for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { buses += ","; @@ -208,7 +197,6 @@ void AudioEffectCompressor::_validate_property(PropertyInfo &property) const { } void AudioEffectCompressor::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_threshold", "threshold"), &AudioEffectCompressor::set_threshold); ClassDB::bind_method(D_METHOD("get_threshold"), &AudioEffectCompressor::get_threshold); diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp index fa57a94977..d6ab14be89 100644 --- a/servers/audio/effects/audio_effect_delay.cpp +++ b/servers/audio/effects/audio_effect_delay.cpp @@ -33,11 +33,9 @@ #include "servers/audio_server.h" void AudioEffectDelayInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - int todo = p_frame_count; while (todo) { - int to_mix = MIN(todo, 256); //can't mix too much _process_chunk(p_src_frames, p_dst_frames, to_mix); @@ -50,7 +48,6 @@ void AudioEffectDelayInstance::process(const AudioFrame *p_src_frames, AudioFram } void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float main_level_f = base->dry; float mix_rate = AudioServer::get_singleton()->get_mix_rate(); @@ -87,7 +84,6 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au AudioFrame *fb_buf = feedback_buffer.ptrw(); for (int i = 0; i < p_frame_count; i++) { - rb_buf[ring_buffer_pos & ring_buffer_mask] = src[i]; AudioFrame main_val = src[i] * main_level_f; @@ -109,8 +105,9 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au ring_buffer_pos++; - if ((++feedback_buffer_pos) >= feedback_delay_frames) + if ((++feedback_buffer_pos) >= feedback_delay_frames) { feedback_buffer_pos = 0; + } } } @@ -147,125 +144,110 @@ Ref<AudioEffectInstance> AudioEffectDelay::instance() { } void AudioEffectDelay::set_dry(float p_dry) { - dry = p_dry; } float AudioEffectDelay::get_dry() { - return dry; } void AudioEffectDelay::set_tap1_active(bool p_active) { - tap_1_active = p_active; } -bool AudioEffectDelay::is_tap1_active() const { +bool AudioEffectDelay::is_tap1_active() const { return tap_1_active; } void AudioEffectDelay::set_tap1_delay_ms(float p_delay_ms) { - tap_1_delay_ms = p_delay_ms; } -float AudioEffectDelay::get_tap1_delay_ms() const { +float AudioEffectDelay::get_tap1_delay_ms() const { return tap_1_delay_ms; } void AudioEffectDelay::set_tap1_level_db(float p_level_db) { - tap_1_level = p_level_db; } -float AudioEffectDelay::get_tap1_level_db() const { +float AudioEffectDelay::get_tap1_level_db() const { return tap_1_level; } void AudioEffectDelay::set_tap1_pan(float p_pan) { - tap_1_pan = p_pan; } -float AudioEffectDelay::get_tap1_pan() const { +float AudioEffectDelay::get_tap1_pan() const { return tap_1_pan; } void AudioEffectDelay::set_tap2_active(bool p_active) { - tap_2_active = p_active; } -bool AudioEffectDelay::is_tap2_active() const { +bool AudioEffectDelay::is_tap2_active() const { return tap_2_active; } void AudioEffectDelay::set_tap2_delay_ms(float p_delay_ms) { - tap_2_delay_ms = p_delay_ms; } -float AudioEffectDelay::get_tap2_delay_ms() const { +float AudioEffectDelay::get_tap2_delay_ms() const { return tap_2_delay_ms; } void AudioEffectDelay::set_tap2_level_db(float p_level_db) { - tap_2_level = p_level_db; } -float AudioEffectDelay::get_tap2_level_db() const { +float AudioEffectDelay::get_tap2_level_db() const { return tap_2_level; } void AudioEffectDelay::set_tap2_pan(float p_pan) { - tap_2_pan = p_pan; } -float AudioEffectDelay::get_tap2_pan() const { +float AudioEffectDelay::get_tap2_pan() const { return tap_2_pan; } void AudioEffectDelay::set_feedback_active(bool p_active) { - feedback_active = p_active; } -bool AudioEffectDelay::is_feedback_active() const { +bool AudioEffectDelay::is_feedback_active() const { return feedback_active; } void AudioEffectDelay::set_feedback_delay_ms(float p_delay_ms) { - feedback_delay_ms = p_delay_ms; } -float AudioEffectDelay::get_feedback_delay_ms() const { +float AudioEffectDelay::get_feedback_delay_ms() const { return feedback_delay_ms; } void AudioEffectDelay::set_feedback_level_db(float p_level_db) { - feedback_level = p_level_db; } -float AudioEffectDelay::get_feedback_level_db() const { +float AudioEffectDelay::get_feedback_level_db() const { return feedback_level; } void AudioEffectDelay::set_feedback_lowpass(float p_lowpass) { - feedback_lowpass = p_lowpass; } -float AudioEffectDelay::get_feedback_lowpass() const { +float AudioEffectDelay::get_feedback_lowpass() const { return feedback_lowpass; } void AudioEffectDelay::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_dry", "amount"), &AudioEffectDelay::set_dry); ClassDB::bind_method(D_METHOD("get_dry"), &AudioEffectDelay::get_dry); diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index bc4fc7ecd6..dc5c2cc16f 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -33,7 +33,6 @@ #include "servers/audio_server.h" void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - const float *src = (const float *)p_src_frames; float *dst = (float *)p_dst_frames; @@ -51,7 +50,6 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi float lofi_mult = powf(2.0, 2.0 + (1.0 - drive_f) * 14); //goes from 16 to 2 bits for (int i = 0; i < p_frame_count * 2; i++) { - float out = undenormalise(src[i] * lpf_ic + lpf_c * h[i & 1]); h[i & 1] = out; float a = out; @@ -59,28 +57,24 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi a *= pregain_f; switch (base->mode) { - case AudioEffectDistortion::MODE_CLIP: { - a = powf(a, 1.0001 - drive_f); - if (a > 1.0) + if (a > 1.0) { a = 1.0; - else if (a < (-1.0)) + } else if (a < (-1.0)) { a = -1.0; + } } break; case AudioEffectDistortion::MODE_ATAN: { - a = atanf(a * atan_mult) * atan_div; } break; case AudioEffectDistortion::MODE_LOFI: { - a = floorf(a * lofi_mult + 0.5) / lofi_mult; } break; case AudioEffectDistortion::MODE_OVERDRIVE: { - const double x = a * 0.686306; const double z = 1 + exp(sqrt(fabs(x)) * -0.75); a = (expf(x) - expf(-x * z)) / (expf(x) + expf(-x)); @@ -109,53 +103,46 @@ Ref<AudioEffectInstance> AudioEffectDistortion::instance() { } void AudioEffectDistortion::set_mode(Mode p_mode) { - mode = p_mode; } AudioEffectDistortion::Mode AudioEffectDistortion::get_mode() const { - return mode; } void AudioEffectDistortion::set_pre_gain(float p_pre_gain) { - pre_gain = p_pre_gain; } -float AudioEffectDistortion::get_pre_gain() const { +float AudioEffectDistortion::get_pre_gain() const { return pre_gain; } void AudioEffectDistortion::set_keep_hf_hz(float p_keep_hf_hz) { - keep_hf_hz = p_keep_hf_hz; } -float AudioEffectDistortion::get_keep_hf_hz() const { +float AudioEffectDistortion::get_keep_hf_hz() const { return keep_hf_hz; } void AudioEffectDistortion::set_drive(float p_drive) { - drive = p_drive; } -float AudioEffectDistortion::get_drive() const { +float AudioEffectDistortion::get_drive() const { return drive; } void AudioEffectDistortion::set_post_gain(float p_post_gain) { - post_gain = p_post_gain; } -float AudioEffectDistortion::get_post_gain() const { +float AudioEffectDistortion::get_post_gain() const { return post_gain; } void AudioEffectDistortion::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mode", "mode"), &AudioEffectDistortion::set_mode); ClassDB::bind_method(D_METHOD("get_mode"), &AudioEffectDistortion::get_mode); diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp index b315fdc3bb..ed4e7122b5 100644 --- a/servers/audio/effects/audio_effect_eq.cpp +++ b/servers/audio/effects/audio_effect_eq.cpp @@ -32,7 +32,6 @@ #include "servers/audio_server.h" void AudioEffectEQInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - int band_count = bands[0].size(); EQ::BandProcess *proc_l = bands[0].ptrw(); EQ::BandProcess *proc_r = bands[1].ptrw(); @@ -42,12 +41,10 @@ void AudioEffectEQInstance::process(const AudioFrame *p_src_frames, AudioFrame * } for (int i = 0; i < p_frame_count; i++) { - AudioFrame src = p_src_frames[i]; AudioFrame dst = AudioFrame(0, 0); for (int j = 0; j < band_count; j++) { - float l = src.l; float r = src.r; @@ -87,12 +84,12 @@ float AudioEffectEQ::get_band_gain_db(int p_band) const { return gain[p_band]; } + int AudioEffectEQ::get_band_count() const { return gain.size(); } bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) { - const Map<StringName, int>::Element *E = prop_band_map.find(p_name); if (E) { set_band_gain_db(E->get(), p_value); @@ -103,7 +100,6 @@ bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) { } bool AudioEffectEQ::_get(const StringName &p_name, Variant &r_ret) const { - const Map<StringName, int>::Element *E = prop_band_map.find(p_name); if (E) { r_ret = get_band_gain_db(E->get()); @@ -114,22 +110,18 @@ bool AudioEffectEQ::_get(const StringName &p_name, Variant &r_ret) const { } void AudioEffectEQ::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < band_names.size(); i++) { - p_list->push_back(PropertyInfo(Variant::FLOAT, band_names[i], PROPERTY_HINT_RANGE, "-60,24,0.1")); } } void AudioEffectEQ::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_band_gain_db", "band_idx", "volume_db"), &AudioEffectEQ::set_band_gain_db); ClassDB::bind_method(D_METHOD("get_band_gain_db", "band_idx"), &AudioEffectEQ::get_band_gain_db); ClassDB::bind_method(D_METHOD("get_band_count"), &AudioEffectEQ::get_band_count); } AudioEffectEQ::AudioEffectEQ(EQ::Preset p_preset) { - eq.set_mix_rate(AudioServer::get_singleton()->get_mix_rate()); eq.set_preset_band_mode(p_preset); gain.resize(eq.get_band_count()); diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp index 18047bc99e..a5135ee1a6 100644 --- a/servers/audio/effects/audio_effect_filter.cpp +++ b/servers/audio/effects/audio_effect_filter.cpp @@ -33,16 +33,18 @@ template <int S> void AudioEffectFilterInstance::_process_filter(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - for (int i = 0; i < p_frame_count; i++) { float f = p_src_frames[i].l; filter_process[0][0].process_one(f); - if (S > 1) + if (S > 1) { filter_process[0][1].process_one(f); - if (S > 2) + } + if (S > 2) { filter_process[0][2].process_one(f); - if (S > 3) + } + if (S > 3) { filter_process[0][3].process_one(f); + } p_dst_frames[i].l = f; } @@ -50,19 +52,21 @@ void AudioEffectFilterInstance::_process_filter(const AudioFrame *p_src_frames, for (int i = 0; i < p_frame_count; i++) { float f = p_src_frames[i].r; filter_process[1][0].process_one(f); - if (S > 1) + if (S > 1) { filter_process[1][1].process_one(f); - if (S > 2) + } + if (S > 2) { filter_process[1][2].process_one(f); - if (S > 3) + } + if (S > 3) { filter_process[1][3].process_one(f); + } p_dst_frames[i].r = f; } } void AudioEffectFilterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - filter.set_cutoff(base->cutoff); filter.set_gain(base->gain); filter.set_resonance(base->resonance); @@ -89,7 +93,6 @@ void AudioEffectFilterInstance::process(const AudioFrame *p_src_frames, AudioFra } AudioEffectFilterInstance::AudioEffectFilterInstance() { - for (int i = 0; i < 2; i++) { for (int j = 0; j < 4; j++) { filter_process[i][j].set_filter(&filter); @@ -106,30 +109,26 @@ Ref<AudioEffectInstance> AudioEffectFilter::instance() { } void AudioEffectFilter::set_cutoff(float p_freq) { - cutoff = p_freq; } float AudioEffectFilter::get_cutoff() const { - return cutoff; } void AudioEffectFilter::set_resonance(float p_amount) { - resonance = p_amount; } -float AudioEffectFilter::get_resonance() const { +float AudioEffectFilter::get_resonance() const { return resonance; } void AudioEffectFilter::set_gain(float p_amount) { - gain = p_amount; } -float AudioEffectFilter::get_gain() const { +float AudioEffectFilter::get_gain() const { return gain; } @@ -138,12 +137,10 @@ void AudioEffectFilter::set_db(FilterDB p_db) { } AudioEffectFilter::FilterDB AudioEffectFilter::get_db() const { - return db; } void AudioEffectFilter::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_cutoff", "freq"), &AudioEffectFilter::set_cutoff); ClassDB::bind_method(D_METHOD("get_cutoff"), &AudioEffectFilter::get_cutoff); @@ -168,7 +165,6 @@ void AudioEffectFilter::_bind_methods() { } AudioEffectFilter::AudioEffectFilter(AudioFilterSW::Mode p_mode) { - mode = p_mode; cutoff = 2000; resonance = 0.5; diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h index 0088118d8c..b11a4e3623 100644 --- a/servers/audio/effects/audio_effect_filter.h +++ b/servers/audio/effects/audio_effect_filter.h @@ -99,7 +99,9 @@ class AudioEffectLowPassFilter : public AudioEffectFilter { GDCLASS(AudioEffectLowPassFilter, AudioEffectFilter); void _validate_property(PropertyInfo &property) const { - if (property.name == "gain") property.usage = 0; + if (property.name == "gain") { + property.usage = 0; + } } public: @@ -110,7 +112,9 @@ public: class AudioEffectHighPassFilter : public AudioEffectFilter { GDCLASS(AudioEffectHighPassFilter, AudioEffectFilter); void _validate_property(PropertyInfo &property) const { - if (property.name == "gain") property.usage = 0; + if (property.name == "gain") { + property.usage = 0; + } } public: @@ -121,7 +125,9 @@ public: class AudioEffectBandPassFilter : public AudioEffectFilter { GDCLASS(AudioEffectBandPassFilter, AudioEffectFilter); void _validate_property(PropertyInfo &property) const { - if (property.name == "gain") property.usage = 0; + if (property.name == "gain") { + property.usage = 0; + } } public: diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp index 40a4243168..27f1aaf71f 100644 --- a/servers/audio/effects/audio_effect_limiter.cpp +++ b/servers/audio/effects/audio_effect_limiter.cpp @@ -31,7 +31,6 @@ #include "audio_effect_limiter.h" void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float threshdb = base->threshold; float ceiling = Math::db2linear(base->ceiling); float ceildb = base->ceiling; @@ -42,7 +41,6 @@ void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFr float scmult = Math::abs((ceildb - sc) / (peakdb - sc)); for (int i = 0; i < p_frame_count; i++) { - float spl0 = p_src_frames[i].l; float spl1 = p_src_frames[i].r; spl0 = spl0 * makeup; @@ -78,44 +76,38 @@ Ref<AudioEffectInstance> AudioEffectLimiter::instance() { } void AudioEffectLimiter::set_threshold_db(float p_threshold) { - threshold = p_threshold; } float AudioEffectLimiter::get_threshold_db() const { - return threshold; } void AudioEffectLimiter::set_ceiling_db(float p_ceiling) { - ceiling = p_ceiling; } -float AudioEffectLimiter::get_ceiling_db() const { +float AudioEffectLimiter::get_ceiling_db() const { return ceiling; } void AudioEffectLimiter::set_soft_clip_db(float p_soft_clip) { - soft_clip = p_soft_clip; } -float AudioEffectLimiter::get_soft_clip_db() const { +float AudioEffectLimiter::get_soft_clip_db() const { return soft_clip; } void AudioEffectLimiter::set_soft_clip_ratio(float p_soft_clip) { - soft_clip_ratio = p_soft_clip; } -float AudioEffectLimiter::get_soft_clip_ratio() const { +float AudioEffectLimiter::get_soft_clip_ratio() const { return soft_clip_ratio; } void AudioEffectLimiter::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_ceiling_db", "ceiling"), &AudioEffectLimiter::set_ceiling_db); ClassDB::bind_method(D_METHOD("get_ceiling_db"), &AudioEffectLimiter::get_ceiling_db); diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp index 10724175e5..32b7921d1f 100644 --- a/servers/audio/effects/audio_effect_panner.cpp +++ b/servers/audio/effects/audio_effect_panner.cpp @@ -31,12 +31,10 @@ #include "audio_effect_panner.h" void AudioEffectPannerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float lvol = CLAMP(1.0 - base->pan, 0, 1); float rvol = CLAMP(1.0 + base->pan, 0, 1); for (int i = 0; i < p_frame_count; i++) { - p_dst_frames[i].l = p_src_frames[i].l * lvol + p_src_frames[i].r * (1.0 - rvol); p_dst_frames[i].r = p_src_frames[i].r * rvol + p_src_frames[i].l * (1.0 - lvol); } @@ -54,12 +52,10 @@ void AudioEffectPanner::set_pan(float p_cpanume) { } float AudioEffectPanner::get_pan() const { - return pan; } void AudioEffectPanner::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_pan", "cpanume"), &AudioEffectPanner::set_pan); ClassDB::bind_method(D_METHOD("get_pan"), &AudioEffectPanner::get_pan); diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp index 3709b69d45..ffeaa7d25e 100644 --- a/servers/audio/effects/audio_effect_phaser.cpp +++ b/servers/audio/effects/audio_effect_phaser.cpp @@ -33,7 +33,6 @@ #include "servers/audio_server.h" void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float sampling_rate = AudioServer::get_singleton()->get_mix_rate(); float dmin = base->range_min / (sampling_rate / 2.0); @@ -42,7 +41,6 @@ void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFra float increment = 2.f * Math_PI * (base->rate / sampling_rate); for (int i = 0; i < p_frame_count; i++) { - phase += increment; while (phase >= Math_PI * 2.f) { @@ -91,54 +89,46 @@ Ref<AudioEffectInstance> AudioEffectPhaser::instance() { } void AudioEffectPhaser::set_range_min_hz(float p_hz) { - range_min = p_hz; } float AudioEffectPhaser::get_range_min_hz() const { - return range_min; } void AudioEffectPhaser::set_range_max_hz(float p_hz) { - range_max = p_hz; } -float AudioEffectPhaser::get_range_max_hz() const { +float AudioEffectPhaser::get_range_max_hz() const { return range_max; } void AudioEffectPhaser::set_rate_hz(float p_hz) { - rate = p_hz; } -float AudioEffectPhaser::get_rate_hz() const { +float AudioEffectPhaser::get_rate_hz() const { return rate; } void AudioEffectPhaser::set_feedback(float p_fbk) { - feedback = p_fbk; } -float AudioEffectPhaser::get_feedback() const { +float AudioEffectPhaser::get_feedback() const { return feedback; } void AudioEffectPhaser::set_depth(float p_depth) { - depth = p_depth; } float AudioEffectPhaser::get_depth() const { - return depth; } void AudioEffectPhaser::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_range_min_hz", "hz"), &AudioEffectPhaser::set_range_min_hz); ClassDB::bind_method(D_METHOD("get_range_min_hz"), &AudioEffectPhaser::get_range_min_hz); diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp index a74ac3c007..fb6b56d984 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.cpp +++ b/servers/audio/effects/audio_effect_pitch_shift.cpp @@ -94,7 +94,9 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff freqPerBin = sampleRate/(double)fftFrameSize; expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize; inFifoLatency = fftFrameSize-stepSize; - if (gRover == 0) gRover = inFifoLatency; + if (gRover == 0) { gRover = inFifoLatency; + +} /* initialize our static arrays */ @@ -142,8 +144,10 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff /* map delta phase into +/- Pi interval */ qpd = tmp/Math_PI; - if (qpd >= 0) qpd += qpd&1; - else qpd -= qpd&1; + if (qpd >= 0) { qpd += qpd&1; + } else { qpd -= qpd&1; + +} tmp -= Math_PI*(double)qpd; /* get deviation from bin frequency from the +/- Pi interval */ @@ -200,7 +204,9 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff } /* zero negative frequencies */ - for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) gFFTworksp[k] = 0.; + for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) { gFFTworksp[k] = 0.; + +} /* do inverse transform */ smbFft(gFFTworksp, fftFrameSize, 1); @@ -210,13 +216,17 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5; gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp); } - for (k = 0; k < stepSize; k++) gOutFIFO[k] = gOutputAccum[k]; + for (k = 0; k < stepSize; k++) { gOutFIFO[k] = gOutputAccum[k]; + +} /* shift accumulator */ memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float)); /* move input FIFO */ - for (k = 0; k < inFifoLatency; k++) gInFIFO[k] = gInFIFO[k+stepSize]; + for (k = 0; k < inFifoLatency; k++) { gInFIFO[k] = gInFIFO[k+stepSize]; + +} } } @@ -225,6 +235,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff } + void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign) /* FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse) @@ -244,7 +255,9 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign) for (i = 2; i < 2*fftFrameSize-2; i += 2) { for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) { - if (i & bitm) j++; + if (i & bitm) { j++; + +} j <<= 1; } if (i < j) { @@ -280,11 +293,11 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign) } } + /* Godot code again */ /* clang-format on */ void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float sample_rate = AudioServer::get_singleton()->get_mix_rate(); float *in_l = (float *)p_src_frames; @@ -313,7 +326,6 @@ void AudioEffectPitchShift::set_pitch_scale(float p_pitch_scale) { } float AudioEffectPitchShift::get_pitch_scale() const { - return pitch_scale; } @@ -323,7 +335,6 @@ void AudioEffectPitchShift::set_oversampling(int p_oversampling) { } int AudioEffectPitchShift::get_oversampling() const { - return oversampling; } @@ -337,7 +348,6 @@ AudioEffectPitchShift::FFT_Size AudioEffectPitchShift::get_fft_size() const { } void AudioEffectPitchShift::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_pitch_scale", "rate"), &AudioEffectPitchShift::set_pitch_scale); ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioEffectPitchShift::get_pitch_scale); diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h index c6528bafa9..48f8e5dc39 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.h +++ b/servers/audio/effects/audio_effect_pitch_shift.h @@ -34,7 +34,6 @@ #include "servers/audio/audio_effect.h" class SMBPitchShift { - enum { MAX_FRAME_LENGTH = 8192 }; diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp index f2784679b5..79388b2dc7 100644 --- a/servers/audio/effects/audio_effect_record.cpp +++ b/servers/audio/effects/audio_effect_record.cpp @@ -101,7 +101,6 @@ void AudioEffectRecordInstance::_io_store_buffer() { } void AudioEffectRecordInstance::_thread_callback(void *_instance) { - AudioEffectRecordInstance *aeri = reinterpret_cast<AudioEffectRecordInstance *>(_instance); aeri->_io_thread_process(); @@ -124,7 +123,6 @@ void AudioEffectRecordInstance::init() { } void AudioEffectRecordInstance::finish() { - #ifdef NO_THREADS AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this); #else @@ -135,7 +133,6 @@ void AudioEffectRecordInstance::finish() { } AudioEffectRecordInstance::~AudioEffectRecordInstance() { - finish(); } diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h index 09101033be..68d968c04b 100644 --- a/servers/audio/effects/audio_effect_record.h +++ b/servers/audio/effects/audio_effect_record.h @@ -49,7 +49,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance { bool is_recording; Thread *io_thread; - bool thread_active; + bool thread_active = false; Vector<AudioFrame> ring_buffer; Vector<float> recording_data; @@ -71,8 +71,7 @@ public: virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count); virtual bool process_silence() const; - AudioEffectRecordInstance() : - thread_active(false) {} + AudioEffectRecordInstance() {} ~AudioEffectRecordInstance(); }; diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp index 6dccb2945b..f6465abfaf 100644 --- a/servers/audio/effects/audio_effect_reverb.cpp +++ b/servers/audio/effects/audio_effect_reverb.cpp @@ -31,7 +31,6 @@ #include "audio_effect_reverb.h" #include "servers/audio_server.h" void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - for (int i = 0; i < 2; i++) { Reverb &r = reverb[i]; @@ -49,7 +48,6 @@ void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFra int offset = 0; while (todo) { - int to_mix = MIN(todo, Reverb::INPUT_BUFFER_MAX_SIZE); for (int j = 0; j < to_mix; j++) { @@ -75,7 +73,6 @@ void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFra } AudioEffectReverbInstance::AudioEffectReverbInstance() { - reverb[0].set_mix_rate(AudioServer::get_singleton()->get_mix_rate()); reverb[0].set_extra_spread_base(0); reverb[1].set_mix_rate(AudioServer::get_singleton()->get_mix_rate()); @@ -90,75 +87,70 @@ Ref<AudioEffectInstance> AudioEffectReverb::instance() { } void AudioEffectReverb::set_predelay_msec(float p_msec) { - predelay = p_msec; } void AudioEffectReverb::set_predelay_feedback(float p_feedback) { - predelay_fb = CLAMP(p_feedback, 0, 0.98); } -void AudioEffectReverb::set_room_size(float p_size) { +void AudioEffectReverb::set_room_size(float p_size) { room_size = p_size; } -void AudioEffectReverb::set_damping(float p_damping) { +void AudioEffectReverb::set_damping(float p_damping) { damping = p_damping; } -void AudioEffectReverb::set_spread(float p_spread) { +void AudioEffectReverb::set_spread(float p_spread) { spread = p_spread; } void AudioEffectReverb::set_dry(float p_dry) { - dry = p_dry; } -void AudioEffectReverb::set_wet(float p_wet) { +void AudioEffectReverb::set_wet(float p_wet) { wet = p_wet; } -void AudioEffectReverb::set_hpf(float p_hpf) { +void AudioEffectReverb::set_hpf(float p_hpf) { hpf = p_hpf; } float AudioEffectReverb::get_predelay_msec() const { - return predelay; } -float AudioEffectReverb::get_predelay_feedback() const { +float AudioEffectReverb::get_predelay_feedback() const { return predelay_fb; } -float AudioEffectReverb::get_room_size() const { +float AudioEffectReverb::get_room_size() const { return room_size; } -float AudioEffectReverb::get_damping() const { +float AudioEffectReverb::get_damping() const { return damping; } -float AudioEffectReverb::get_spread() const { +float AudioEffectReverb::get_spread() const { return spread; } -float AudioEffectReverb::get_dry() const { +float AudioEffectReverb::get_dry() const { return dry; } -float AudioEffectReverb::get_wet() const { +float AudioEffectReverb::get_wet() const { return wet; } -float AudioEffectReverb::get_hpf() const { +float AudioEffectReverb::get_hpf() const { return hpf; } void AudioEffectReverb::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_predelay_msec", "msec"), &AudioEffectReverb::set_predelay_msec); ClassDB::bind_method(D_METHOD("get_predelay_msec"), &AudioEffectReverb::get_predelay_msec); diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp index 47aee02de2..e744dbf9b0 100644 --- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp +++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -50,7 +50,9 @@ static void smbFft(float *fftBuffer, long fftFrameSize, long sign) for (i = 2; i < 2 * fftFrameSize - 2; i += 2) { for (bitm = 2, j = 0; bitm < 2 * fftFrameSize; bitm <<= 1) { - if (i & bitm) j++; + if (i & bitm) { + j++; + } j <<= 1; } if (i < j) { @@ -95,8 +97,8 @@ static void smbFft(float *fftBuffer, long fftFrameSize, long sign) } } } -void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { +void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { uint64_t time = OS::get_singleton()->get_ticks_usec(); //copy everything over first, since this only really does capture @@ -148,14 +150,12 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames } void AudioEffectSpectrumAnalyzerInstance::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_magnitude_for_frequency_range", "from_hz", "to_hz", "mode"), &AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range, DEFVAL(MAGNITUDE_MAX)); BIND_ENUM_CONSTANT(MAGNITUDE_AVERAGE); BIND_ENUM_CONSTANT(MAGNITUDE_MAX); } Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(float p_begin, float p_end, MagnitudeMode p_mode) const { - if (last_fft_time == 0) { return Vector2(); } @@ -196,7 +196,6 @@ Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(f return avg; } else { - Vector2 max; for (int i = begin_pos; i <= end_pos; i++) { @@ -209,7 +208,6 @@ Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(f } Ref<AudioEffectInstance> AudioEffectSpectrumAnalyzer::instance() { - Ref<AudioEffectSpectrumAnalyzerInstance> ins; ins.instance(); ins->base = Ref<AudioEffectSpectrumAnalyzer>(this); @@ -236,7 +234,6 @@ void AudioEffectSpectrumAnalyzer::set_buffer_length(float p_seconds) { } float AudioEffectSpectrumAnalyzer::get_buffer_length() const { - return buffer_length; } @@ -258,7 +255,6 @@ AudioEffectSpectrumAnalyzer::FFT_Size AudioEffectSpectrumAnalyzer::get_fft_size( } void AudioEffectSpectrumAnalyzer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_buffer_length", "seconds"), &AudioEffectSpectrumAnalyzer::set_buffer_length); ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectSpectrumAnalyzer::get_buffer_length); diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp index a10aca02b2..4f9bee83e4 100644 --- a/servers/audio/effects/audio_effect_stereo_enhance.cpp +++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp @@ -31,14 +31,12 @@ #include "audio_effect_stereo_enhance.h" #include "servers/audio_server.h" void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float intensity = base->pan_pullout; bool surround_mode = base->surround > 0; float surround_amount = base->surround; unsigned int delay_frames = (base->time_pullout / 1000.0) * AudioServer::get_singleton()->get_mix_rate(); for (int i = 0; i < p_frame_count; i++) { - float l = p_src_frames[i].l; float r = p_src_frames[i].r; @@ -48,7 +46,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A r = (center + (r - center) * intensity); if (surround_mode) { - float val = (l + r) / 2.0; delay_ringbuff[ringbuff_pos & ringbuff_mask] = val; @@ -58,7 +55,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A l += out; r += -out; } else { - float val = r; delay_ringbuff[ringbuff_pos & ringbuff_mask] = val; @@ -75,7 +71,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A } AudioEffectStereoEnhanceInstance::~AudioEffectStereoEnhanceInstance() { - memdelete_arr(delay_ringbuff); } @@ -108,35 +103,30 @@ Ref<AudioEffectInstance> AudioEffectStereoEnhance::instance() { } void AudioEffectStereoEnhance::set_pan_pullout(float p_amount) { - pan_pullout = p_amount; } float AudioEffectStereoEnhance::get_pan_pullout() const { - return pan_pullout; } void AudioEffectStereoEnhance::set_time_pullout(float p_amount) { - time_pullout = p_amount; } -float AudioEffectStereoEnhance::get_time_pullout() const { +float AudioEffectStereoEnhance::get_time_pullout() const { return time_pullout; } void AudioEffectStereoEnhance::set_surround(float p_amount) { - surround = p_amount; } -float AudioEffectStereoEnhance::get_surround() const { +float AudioEffectStereoEnhance::get_surround() const { return surround; } void AudioEffectStereoEnhance::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_pan_pullout", "amount"), &AudioEffectStereoEnhance::set_pan_pullout); ClassDB::bind_method(D_METHOD("get_pan_pullout"), &AudioEffectStereoEnhance::get_pan_pullout); diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index d272a2cdf7..aba04550db 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -35,21 +35,18 @@ void AudioStreamGenerator::set_mix_rate(float p_mix_rate) { } float AudioStreamGenerator::get_mix_rate() const { - return mix_rate; } void AudioStreamGenerator::set_buffer_length(float p_seconds) { - buffer_len = p_seconds; } -float AudioStreamGenerator::get_buffer_length() const { +float AudioStreamGenerator::get_buffer_length() const { return buffer_len; } Ref<AudioStreamPlayback> AudioStreamGenerator::instance_playback() { - Ref<AudioStreamGeneratorPlayback> playback; playback.instance(); playback->generator = this; @@ -58,8 +55,8 @@ Ref<AudioStreamPlayback> AudioStreamGenerator::instance_playback() { playback->buffer.clear(); return playback; } -String AudioStreamGenerator::get_stream_name() const { +String AudioStreamGenerator::get_stream_name() const { return "UserFeed"; } @@ -99,8 +96,8 @@ bool AudioStreamGeneratorPlayback::push_frame(const Vector2 &p_frame) { bool AudioStreamGeneratorPlayback::can_push_buffer(int p_frames) const { return buffer.space_left() >= p_frames; } -bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frames) { +bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frames) { int to_write = p_frames.size(); if (buffer.space_left() < to_write) { return false; @@ -115,7 +112,6 @@ bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frame AudioFrame buf[2048]; int ofs = 0; while (to_write) { - int w = MIN(to_write, 2048); for (int i = 0; i < w; i++) { buf[i] = r[i + ofs]; @@ -143,7 +139,6 @@ void AudioStreamGeneratorPlayback::clear_buffer() { } void AudioStreamGeneratorPlayback::_mix_internal(AudioFrame *p_buffer, int p_frames) { - int read_amount = buffer.data_left(); if (p_frames < read_amount) { read_amount = p_frames; @@ -162,12 +157,12 @@ void AudioStreamGeneratorPlayback::_mix_internal(AudioFrame *p_buffer, int p_fra mixed += p_frames / generator->get_mix_rate(); } + float AudioStreamGeneratorPlayback::get_stream_sampling_rate() { return generator->get_mix_rate(); } void AudioStreamGeneratorPlayback::start(float p_from_pos) { - if (mixed == 0.0) { _begin_resample(); } @@ -179,8 +174,8 @@ void AudioStreamGeneratorPlayback::start(float p_from_pos) { void AudioStreamGeneratorPlayback::stop() { active = false; } -bool AudioStreamGeneratorPlayback::is_playing() const { +bool AudioStreamGeneratorPlayback::is_playing() const { return active; //always playing, can't be stopped } @@ -191,6 +186,7 @@ int AudioStreamGeneratorPlayback::get_loop_count() const { float AudioStreamGeneratorPlayback::get_playback_position() const { return mixed; } + void AudioStreamGeneratorPlayback::seek(float p_time) { //no seek possible } diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h index aee3459e17..763d913684 100644 --- a/servers/audio/effects/audio_stream_generator.h +++ b/servers/audio/effects/audio_stream_generator.h @@ -58,7 +58,6 @@ public: }; class AudioStreamGeneratorPlayback : public AudioStreamPlaybackResampled { - GDCLASS(AudioStreamGeneratorPlayback, AudioStreamPlaybackResampled); friend class AudioStreamGenerator; RingBuffer<AudioFrame> buffer; diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp index 426f178dcb..08a6cf55fa 100644 --- a/servers/audio/effects/eq.cpp +++ b/servers/audio/effects/eq.cpp @@ -42,48 +42,45 @@ static int solve_quadratic(double a, double b, double c, double *r1, double *r2) //solves quadractic and returns number of roots double base = 2 * a; - if (base == 0.0f) + if (base == 0.0f) { return 0; + } double squared = b * b - 4 * a * c; - if (squared < 0.0) + if (squared < 0.0) { return 0; + } squared = sqrt(squared); *r1 = (-b + squared) / base; *r2 = (-b - squared) / base; - if (*r1 == *r2) + if (*r1 == *r2) { return 1; - else + } else { return 2; + } } EQ::BandProcess::BandProcess() { - c1 = c2 = c3 = history.a1 = history.a2 = history.a3 = 0; history.b1 = history.b2 = history.b3 = 0; } void EQ::recalculate_band_coefficients() { - #define BAND_LOG(m_f) (log((m_f)) / log(2.)) for (int i = 0; i < band.size(); i++) { - double octave_size; double frq = band[i].freq; if (i == 0) { - octave_size = BAND_LOG(band[1].freq) - BAND_LOG(frq); } else if (i == (band.size() - 1)) { - octave_size = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq); } else { - double next = BAND_LOG(band[i + 1].freq) - BAND_LOG(frq); double prev = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq); octave_size = (next + prev) / 2.0; @@ -118,27 +115,24 @@ void EQ::recalculate_band_coefficients() { } void EQ::set_preset_band_mode(Preset p_preset) { - band.clear(); #define PUSH_BANDS(m_bands) \ for (int i = 0; i < m_bands; i++) { \ Band b; \ b.freq = bands[i]; \ + b.c1 = b.c2 = b.c3 = 0; \ band.push_back(b); \ } switch (p_preset) { - case PRESET_6_BANDS: { - static const double bands[] = { 32, 100, 320, 1e3, 3200, 10e3 }; PUSH_BANDS(6); } break; case PRESET_8_BANDS: { - static const double bands[] = { 32, 72, 192, 512, 1200, 3000, 7500, 16e3 }; PUSH_BANDS(8); @@ -152,14 +146,12 @@ void EQ::set_preset_band_mode(Preset p_preset) { } break; case PRESET_21_BANDS: { - static const double bands[] = { 22, 32, 44, 63, 90, 125, 175, 250, 350, 500, 700, 1e3, 1400, 2e3, 2800, 4e3, 5600, 8e3, 11e3, 16e3, 22e3 }; PUSH_BANDS(21); } break; case PRESET_31_BANDS: { - static const double bands[] = { 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1e3, 1250, 1600, 2e3, 2500, 3150, 4e3, 5e3, 6300, 8e3, 10e3, 12500, 16e3, 20e3 }; PUSH_BANDS(31); } break; @@ -169,19 +161,17 @@ void EQ::set_preset_band_mode(Preset p_preset) { } int EQ::get_band_count() const { - return band.size(); } -float EQ::get_band_frequency(int p_band) { +float EQ::get_band_frequency(int p_band) { ERR_FAIL_INDEX_V(p_band, band.size(), 0); return band[p_band].freq; } -void EQ::set_bands(const Vector<float> &p_bands) { +void EQ::set_bands(const Vector<float> &p_bands) { band.resize(p_bands.size()); for (int i = 0; i < p_bands.size(); i++) { - band.write[i].freq = p_bands[i]; } @@ -189,13 +179,11 @@ void EQ::set_bands(const Vector<float> &p_bands) { } void EQ::set_mix_rate(float p_mix_rate) { - mix_rate = p_mix_rate; recalculate_band_coefficients(); } EQ::BandProcess EQ::get_band_processor(int p_band) const { - EQ::BandProcess band_proc; ERR_FAIL_INDEX_V(p_band, band.size(), band_proc); diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h index 6c002effbf..391a7aa24b 100644 --- a/servers/audio/effects/eq.h +++ b/servers/audio/effects/eq.h @@ -52,7 +52,6 @@ public: }; class BandProcess { - friend class EQ; float c1, c2, c3; struct History { @@ -69,7 +68,6 @@ public: private: struct Band { - float freq; float c1, c2, c3; }; @@ -96,7 +94,6 @@ public: /* Inline Function */ inline void EQ::BandProcess::process_one(float &p_data) { - history.a1 = p_data; history.b1 = c1 * (history.a1 - history.a3) + c3 * history.b2 - c2 * history.b3; diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp index ea2174f1d4..7c35d88ced 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb.cpp @@ -31,7 +31,9 @@ // Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006 #include "reverb.h" + #include "core/math/math_funcs.h" + #include <math.h> const float Reverb::comb_tunings[MAX_COMBS] = { @@ -55,24 +57,27 @@ const float Reverb::allpass_tunings[MAX_ALLPASS] = { }; void Reverb::process(float *p_src, float *p_dst, int p_frames) { - - if (p_frames > INPUT_BUFFER_MAX_SIZE) + if (p_frames > INPUT_BUFFER_MAX_SIZE) { p_frames = INPUT_BUFFER_MAX_SIZE; + } int predelay_frames = lrint((params.predelay / 1000.0) * params.mix_rate); - if (predelay_frames < 10) + if (predelay_frames < 10) { predelay_frames = 10; - if (predelay_frames >= echo_buffer_size) + } + if (predelay_frames >= echo_buffer_size) { predelay_frames = echo_buffer_size - 1; + } for (int i = 0; i < p_frames; i++) { - - if (echo_buffer_pos >= echo_buffer_size) + if (echo_buffer_pos >= echo_buffer_size) { echo_buffer_pos = 0; + } int read_pos = echo_buffer_pos - predelay_frames; - while (read_pos < 0) + while (read_pos < 0) { read_pos += echo_buffer_size; + } float in = undenormalise(echo_buffer[read_pos] * params.predelay_fb + p_src[i]); @@ -92,7 +97,6 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { float hp_b1 = hpaux; for (int i = 0; i < p_frames; i++) { - float in = input_buffer[i]; input_buffer[i] = in * hp_a1 + hpf_h1 * hp_a2 + hpf_h2 * hp_b1; hpf_h2 = input_buffer[i]; @@ -101,14 +105,13 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { } for (int i = 0; i < MAX_COMBS; i++) { - Comb &c = comb[i]; int size_limit = c.size - lrintf((float)c.extra_spread_frames * (1.0 - params.extra_spread)); for (int j = 0; j < p_frames; j++) { - - if (c.pos >= size_limit) //reset this now just in case + if (c.pos >= size_limit) { //reset this now just in case c.pos = 0; + } float out = undenormalise(c.buffer[c.pos] * c.feedback); out = out * (1.0 - c.damp) + c.damp_h * c.damp; //lowpass @@ -155,14 +158,13 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { */ for (int i = 0; i < MAX_ALLPASS; i++) { - AllPass &a = allpass[i]; int size_limit = a.size - lrintf((float)a.extra_spread_frames * (1.0 - params.extra_spread)); for (int j = 0; j < p_frames; j++) { - - if (a.pos >= size_limit) + if (a.pos >= size_limit) { a.pos = 0; + } float aux = a.buffer[a.pos]; a.buffer[a.pos] = undenormalise(allpass_feedback * aux + p_dst[j]); @@ -174,108 +176,102 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) { static const float wet_scale = 0.6; for (int i = 0; i < p_frames; i++) { - p_dst[i] = p_dst[i] * params.wet * wet_scale + p_src[i] * params.dry; } } void Reverb::set_room_size(float p_size) { - params.room_size = p_size; update_parameters(); } -void Reverb::set_damp(float p_damp) { +void Reverb::set_damp(float p_damp) { params.damp = p_damp; update_parameters(); } -void Reverb::set_wet(float p_wet) { +void Reverb::set_wet(float p_wet) { params.wet = p_wet; } void Reverb::set_dry(float p_dry) { - params.dry = p_dry; } void Reverb::set_predelay(float p_predelay) { - params.predelay = p_predelay; } -void Reverb::set_predelay_feedback(float p_predelay_fb) { +void Reverb::set_predelay_feedback(float p_predelay_fb) { params.predelay_fb = p_predelay_fb; } void Reverb::set_highpass(float p_frq) { - - if (p_frq > 1) + if (p_frq > 1) { p_frq = 1; - if (p_frq < 0) + } + if (p_frq < 0) { p_frq = 0; + } params.hpf = p_frq; } void Reverb::set_extra_spread(float p_spread) { - params.extra_spread = p_spread; } void Reverb::set_mix_rate(float p_mix_rate) { - params.mix_rate = p_mix_rate; configure_buffers(); } void Reverb::set_extra_spread_base(float p_sec) { - params.extra_spread_base = p_sec; configure_buffers(); } void Reverb::configure_buffers() { - clear_buffers(); //clear if necessary for (int i = 0; i < MAX_COMBS; i++) { - Comb &c = comb[i]; c.extra_spread_frames = lrint(params.extra_spread_base * params.mix_rate); int len = lrint(comb_tunings[i] * params.mix_rate) + c.extra_spread_frames; - if (len < 5) + if (len < 5) { len = 5; //may this happen? + } c.buffer = memnew_arr(float, len); c.pos = 0; - for (int j = 0; j < len; j++) + for (int j = 0; j < len; j++) { c.buffer[j] = 0; + } c.size = len; } for (int i = 0; i < MAX_ALLPASS; i++) { - AllPass &a = allpass[i]; a.extra_spread_frames = lrint(params.extra_spread_base * params.mix_rate); int len = lrint(allpass_tunings[i] * params.mix_rate) + a.extra_spread_frames; - if (len < 5) + if (len < 5) { len = 5; //may this happen? + } a.buffer = memnew_arr(float, len); a.pos = 0; - for (int j = 0; j < len; j++) + for (int j = 0; j < len; j++) { a.buffer[j] = 0; + } a.size = len; } echo_buffer_size = (int)(((float)MAX_ECHO_MS / 1000.0) * params.mix_rate + 1.0); echo_buffer = memnew_arr(float, echo_buffer_size); for (int i = 0; i < echo_buffer_size; i++) { - echo_buffer[i] = 0; } @@ -283,19 +279,18 @@ void Reverb::configure_buffers() { } void Reverb::update_parameters() { - //more freeverb derived constants static const float room_scale = 0.28f; static const float room_offset = 0.7f; for (int i = 0; i < MAX_COMBS; i++) { - Comb &c = comb[i]; c.feedback = room_offset + params.room_size * room_scale; - if (c.feedback < room_offset) + if (c.feedback < room_offset) { c.feedback = room_offset; - else if (c.feedback > (room_offset + room_scale)) + } else if (c.feedback > (room_offset + room_scale)) { c.feedback = (room_offset + room_scale); + } float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough) auxdmp *= auxdmp; @@ -305,29 +300,28 @@ void Reverb::update_parameters() { } void Reverb::clear_buffers() { - - if (echo_buffer) + if (echo_buffer) { memdelete_arr(echo_buffer); + } for (int i = 0; i < MAX_COMBS; i++) { - - if (comb[i].buffer) + if (comb[i].buffer) { memdelete_arr(comb[i].buffer); + } comb[i].buffer = nullptr; } for (int i = 0; i < MAX_ALLPASS; i++) { - - if (allpass[i].buffer) + if (allpass[i].buffer) { memdelete_arr(allpass[i].buffer); + } allpass[i].buffer = nullptr; } } Reverb::Reverb() { - params.room_size = 0.8; params.damp = 0.5; params.dry = 1.0; @@ -338,18 +332,14 @@ Reverb::Reverb() { params.predelay = 150; params.predelay_fb = 0.4; params.hpf = 0; - hpf_h1 = 0; - hpf_h2 = 0; input_buffer = memnew_arr(float, INPUT_BUFFER_MAX_SIZE); - echo_buffer = nullptr; configure_buffers(); update_parameters(); } Reverb::~Reverb() { - memdelete_arr(input_buffer); clear_buffers(); } diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h index 92e4aed435..614de0c534 100644 --- a/servers/audio/effects/reverb.h +++ b/servers/audio/effects/reverb.h @@ -57,48 +57,35 @@ private: static const float allpass_tunings[MAX_ALLPASS]; struct Comb { - - int size; - float *buffer; - float feedback; - float damp; //lowpass - float damp_h; //history - int pos; - int extra_spread_frames; - - Comb() { - size = 0; - buffer = 0; - feedback = 0; - damp_h = 0; - pos = 0; - } + int size = 0; + float *buffer = nullptr; + float feedback = 0; + float damp = 0; //lowpass + float damp_h = 0; //history + int pos = 0; + int extra_spread_frames = 0; + + Comb() {} }; struct AllPass { - - int size; - float *buffer; - int pos; - int extra_spread_frames; - AllPass() { - size = 0; - buffer = 0; - pos = 0; - } + int size = 0; + float *buffer = nullptr; + int pos = 0; + int extra_spread_frames = 0; + AllPass() {} }; Comb comb[MAX_COMBS]; AllPass allpass[MAX_ALLPASS]; float *input_buffer; - float *echo_buffer; + float *echo_buffer = nullptr; int echo_buffer_size; int echo_buffer_pos; - float hpf_h1, hpf_h2; + float hpf_h1, hpf_h2 = 0; struct Parameters { - float room_size; float damp; float wet; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 90033d4a87..09d2914e05 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -47,45 +47,41 @@ AudioDriver *AudioDriver::singleton = nullptr; AudioDriver *AudioDriver::get_singleton() { - return singleton; } void AudioDriver::set_singleton() { - singleton = this; } void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time) { - - if (p_update_mix_time) + if (p_update_mix_time) { update_mix_time(p_frames); + } - if (AudioServer::get_singleton()) + if (AudioServer::get_singleton()) { AudioServer::get_singleton()->_driver_process(p_frames, p_buffer); + } } void AudioDriver::update_mix_time(int p_frames) { - _last_mix_frames = p_frames; - if (OS::get_singleton()) + if (OS::get_singleton()) { _last_mix_time = OS::get_singleton()->get_ticks_usec(); + } } double AudioDriver::get_time_since_last_mix() const { - return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; } double AudioDriver::get_time_to_next_mix() const { - double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; double mix_buffer = _last_mix_frames / (double)get_mix_rate(); return mix_buffer - 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; @@ -93,7 +89,6 @@ void AudioDriver::input_buffer_init(int driver_buffer_frames) { } void AudioDriver::input_buffer_write(int32_t sample) { - if ((int)input_position < input_buffer.size()) { input_buffer.write[input_position++] = sample; if ((int)input_position >= input_buffer.size()) { @@ -109,9 +104,12 @@ void AudioDriver::input_buffer_write(int32_t sample) { AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_channels) const { switch (p_channels) { - case 4: return SPEAKER_SURROUND_31; - case 6: return SPEAKER_SURROUND_51; - case 8: return SPEAKER_SURROUND_71; + case 4: + return SPEAKER_SURROUND_31; + case 6: + return SPEAKER_SURROUND_51; + case 8: + return SPEAKER_SURROUND_71; } // Default to STEREO @@ -120,10 +118,14 @@ AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_c int AudioDriver::get_total_channels_by_speaker_mode(AudioDriver::SpeakerMode p_mode) const { switch (p_mode) { - case SPEAKER_MODE_STEREO: return 2; - case SPEAKER_SURROUND_31: return 4; - case SPEAKER_SURROUND_51: return 6; - case SPEAKER_SURROUND_71: return 8; + case SPEAKER_MODE_STEREO: + return 2; + case SPEAKER_SURROUND_31: + return 4; + case SPEAKER_SURROUND_51: + return 6; + case SPEAKER_SURROUND_71: + return 8; } ERR_FAIL_V(2); @@ -150,7 +152,6 @@ Array AudioDriver::capture_get_device_list() { } AudioDriver::AudioDriver() { - _last_mix_time = 0; _last_mix_frames = 0; input_position = 0; @@ -168,7 +169,6 @@ AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = { int AudioDriverManager::driver_count = 1; void AudioDriverManager::add_driver(AudioDriver *p_driver) { - ERR_FAIL_COND(driver_count >= MAX_DRIVERS); drivers[driver_count - 1] = p_driver; @@ -177,12 +177,14 @@ void AudioDriverManager::add_driver(AudioDriver *p_driver) { } int AudioDriverManager::get_driver_count() { - return driver_count; } void AudioDriverManager::initialize(int p_driver) { GLOBAL_DEF_RST("audio/enable_audio_input", false); + GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); + GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY); + int failed_driver = -1; // Check if there is a selected driver @@ -214,7 +216,6 @@ void AudioDriverManager::initialize(int p_driver) { } AudioDriver *AudioDriverManager::get_driver(int p_driver) { - ERR_FAIL_INDEX_V(p_driver, driver_count, nullptr); return drivers[p_driver]; } @@ -225,7 +226,6 @@ AudioDriver *AudioDriverManager::get_driver(int p_driver) { ////////////////////////////////////////////// void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { - int todo = p_frames; #ifdef DEBUG_ENABLED @@ -239,7 +239,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { } while (todo) { - if (to_mix == 0) { _mix_step(); } @@ -254,13 +253,10 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { //master master, send to output int cs = master->channels.size(); for (int k = 0; k < cs; k++) { - if (master->channels[k].active) { - const AudioFrame *buf = master->channels[k].buffer.ptr(); for (int j = 0; j < to_copy; j++) { - float l = CLAMP(buf[from + j].l, -1.0, 1.0); int32_t vl = l * ((1 << 20) - 1); int32_t vl2 = (vl < 0 ? -1 : 1) * (ABS(vl) << 11); @@ -274,7 +270,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { } else { for (int j = 0; j < to_copy; j++) { - p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 0] = 0; p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 1] = 0; } @@ -291,14 +286,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { } void AudioServer::_mix_step() { - bool solo_mode = false; for (int i = 0; i < buses.size(); i++) { Bus *bus = buses[i]; bus->index_cache = i; //might be moved around by editor, so.. for (int k = 0; k < bus->channels.size(); k++) { - bus->channels.write[k].used = false; } @@ -307,7 +300,6 @@ void AudioServer::_mix_step() { solo_mode = true; bus->soloed = true; do { - if (bus != buses[0]) { //everything has a send save for master bus if (!bus_map.has(bus->send)) { @@ -333,7 +325,6 @@ void AudioServer::_mix_step() { //make callbacks for mixing the audio for (Set<CallbackItem>::Element *E = callbacks.front(); E; E = E->next()) { - E->get().callback(E->get().userdata); } @@ -342,13 +333,11 @@ void AudioServer::_mix_step() { Bus *bus = buses[i]; for (int k = 0; k < bus->channels.size(); k++) { - if (bus->channels[k].active && !bus->channels[k].used) { //buffer was not used, but it's still active, so it must be cleaned AudioFrame *buf = bus->channels.write[k].buffer.ptrw(); for (uint32_t j = 0; j < buffer_size; j++) { - buf[j] = AudioFrame(0, 0); } } @@ -357,26 +346,26 @@ void AudioServer::_mix_step() { //process effects if (!bus->bypass) { for (int j = 0; j < bus->effects.size(); j++) { - - if (!bus->effects[j].enabled) + if (!bus->effects[j].enabled) { continue; + } #ifdef DEBUG_ENABLED uint64_t ticks = OS::get_singleton()->get_ticks_usec(); #endif for (int k = 0; k < bus->channels.size(); k++) { - - if (!(bus->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) + if (!(bus->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) { continue; + } bus->channels.write[k].effect_instances.write[j]->process(bus->channels[k].buffer.ptr(), temp_buffer.write[k].ptrw(), buffer_size); } //swap buffers, so internal buffer always has the right data for (int k = 0; k < bus->channels.size(); k++) { - - if (!(buses[i]->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) + if (!(buses[i]->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) { continue; + } SWAP(bus->channels.write[k].buffer, temp_buffer.write[k]); } @@ -403,9 +392,9 @@ void AudioServer::_mix_step() { } for (int k = 0; k < bus->channels.size(); k++) { - - if (!bus->channels[k].active) + if (!bus->channels[k].active) { continue; + } AudioFrame *buf = bus->channels.write[k].buffer.ptrw(); @@ -425,7 +414,6 @@ void AudioServer::_mix_step() { //apply volume and compute peak for (uint32_t j = 0; j < buffer_size; j++) { - buf[j] *= volume; float l = ABS(buf[j].l); @@ -467,15 +455,16 @@ void AudioServer::_mix_step() { } bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const { - if (p_bus < 0 || p_bus >= buses.size()) + if (p_bus < 0 || p_bus >= buses.size()) { return false; - if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size()) + } + 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(), nullptr); ERR_FAIL_INDEX_V(p_buffer, buses[p_bus]->channels.size(), nullptr); @@ -494,12 +483,10 @@ AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) } int AudioServer::thread_get_mix_buffer_size() const { - return buffer_size; } int AudioServer::thread_find_bus_index(const StringName &p_name) { - if (bus_map.has(p_name)) { return bus_map[p_name]->index_cache; } else { @@ -508,7 +495,6 @@ int AudioServer::thread_find_bus_index(const StringName &p_name) { } void AudioServer::set_bus_count(int p_count) { - ERR_FAIL_COND(p_count < 1); ERR_FAIL_INDEX(p_count, 256); @@ -527,14 +513,11 @@ void AudioServer::set_bus_count(int p_count) { buses.resize(p_count); for (int i = cb; i < buses.size(); i++) { - String attempt = "New Bus"; int attempts = 1; while (true) { - bool name_free = true; for (int j = 0; j < i; j++) { - if (buses[j]->name == attempt) { name_free = false; break; @@ -572,7 +555,6 @@ void AudioServer::set_bus_count(int p_count) { } void AudioServer::remove_bus(int p_index) { - ERR_FAIL_INDEX(p_index, buses.size()); ERR_FAIL_COND(p_index == 0); @@ -588,25 +570,23 @@ void AudioServer::remove_bus(int p_index) { } void AudioServer::add_bus(int p_at_pos) { - MARK_EDITED if (p_at_pos >= buses.size()) { p_at_pos = -1; } else if (p_at_pos == 0) { - if (buses.size() > 1) + if (buses.size() > 1) { p_at_pos = 1; - else + } else { p_at_pos = -1; + } } String attempt = "New Bus"; int attempts = 1; while (true) { - bool name_free = true; for (int j = 0; j < buses.size(); j++) { - if (buses[j]->name == attempt) { name_free = false; break; @@ -634,23 +614,24 @@ void AudioServer::add_bus(int p_at_pos) { bus_map[attempt] = bus; - if (p_at_pos == -1) + if (p_at_pos == -1) { buses.push_back(bus); - else + } else { buses.insert(p_at_pos, bus); + } emit_signal("bus_layout_changed"); } void AudioServer::move_bus(int p_bus, int p_to_pos) { - ERR_FAIL_COND(p_bus < 1 || p_bus >= buses.size()); ERR_FAIL_COND(p_to_pos != -1 && (p_to_pos < 1 || p_to_pos > buses.size())); MARK_EDITED - if (p_bus == p_to_pos) + if (p_bus == p_to_pos) { return; + } Bus *bus = buses[p_bus]; buses.remove(p_bus); @@ -667,15 +648,14 @@ void AudioServer::move_bus(int p_bus, int p_to_pos) { } int AudioServer::get_bus_count() const { - return buses.size(); } void AudioServer::set_bus_name(int p_bus, const String &p_name) { - ERR_FAIL_INDEX(p_bus, buses.size()); - if (p_bus == 0 && p_name != "Master") + if (p_bus == 0 && p_name != "Master") { return; //bus 0 is always master + } MARK_EDITED @@ -690,10 +670,8 @@ void AudioServer::set_bus_name(int p_bus, const String &p_name) { int attempts = 1; while (true) { - bool name_free = true; for (int i = 0; i < buses.size(); i++) { - if (buses[i]->name == attempt) { name_free = false; break; @@ -714,8 +692,8 @@ void AudioServer::set_bus_name(int p_bus, const String &p_name) { emit_signal("bus_layout_changed"); } -String AudioServer::get_bus_name(int p_bus) const { +String AudioServer::get_bus_name(int p_bus) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), String()); return buses[p_bus]->name; } @@ -730,27 +708,24 @@ int AudioServer::get_bus_index(const StringName &p_bus_name) const { } void AudioServer::set_bus_volume_db(int p_bus, float p_volume_db) { - ERR_FAIL_INDEX(p_bus, buses.size()); MARK_EDITED buses[p_bus]->volume_db = p_volume_db; } -float AudioServer::get_bus_volume_db(int p_bus) const { +float AudioServer::get_bus_volume_db(int p_bus) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), 0); 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()); MARK_EDITED @@ -759,13 +734,11 @@ void AudioServer::set_bus_send(int p_bus, const StringName &p_send) { } StringName AudioServer::get_bus_send(int p_bus) const { - ERR_FAIL_INDEX_V(p_bus, buses.size(), StringName()); return buses[p_bus]->send; } void AudioServer::set_bus_solo(int p_bus, bool p_enable) { - ERR_FAIL_INDEX(p_bus, buses.size()); MARK_EDITED @@ -774,44 +747,40 @@ void AudioServer::set_bus_solo(int p_bus, bool p_enable) { } bool AudioServer::is_bus_solo(int p_bus) const { - ERR_FAIL_INDEX_V(p_bus, buses.size(), false); return buses[p_bus]->solo; } void AudioServer::set_bus_mute(int p_bus, bool p_enable) { - ERR_FAIL_INDEX(p_bus, buses.size()); MARK_EDITED buses[p_bus]->mute = p_enable; } -bool AudioServer::is_bus_mute(int p_bus) const { +bool AudioServer::is_bus_mute(int p_bus) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), false); return buses[p_bus]->mute; } void AudioServer::set_bus_bypass_effects(int p_bus, bool p_enable) { - ERR_FAIL_INDEX(p_bus, buses.size()); MARK_EDITED buses[p_bus]->bypass = p_enable; } -bool AudioServer::is_bus_bypassing_effects(int p_bus) const { +bool AudioServer::is_bus_bypassing_effects(int p_bus) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), false); return buses[p_bus]->bypass; } void AudioServer::_update_bus_effects(int p_bus) { - for (int i = 0; i < buses[p_bus]->channels.size(); i++) { buses.write[p_bus]->channels.write[i].effect_instances.resize(buses[p_bus]->effects.size()); for (int j = 0; j < buses[p_bus]->effects.size(); j++) { @@ -825,7 +794,6 @@ void AudioServer::_update_bus_effects(int p_bus) { } void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, int p_at_pos) { - ERR_FAIL_COND(p_effect.is_null()); ERR_FAIL_INDEX(p_bus, buses.size()); @@ -853,7 +821,6 @@ void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, in } void AudioServer::remove_bus_effect(int p_bus, int p_effect) { - ERR_FAIL_INDEX(p_bus, buses.size()); MARK_EDITED @@ -867,14 +834,12 @@ void AudioServer::remove_bus_effect(int p_bus, int p_effect) { } int AudioServer::get_bus_effect_count(int p_bus) { - ERR_FAIL_INDEX_V(p_bus, buses.size(), 0); return buses[p_bus]->effects.size(); } Ref<AudioEffectInstance> AudioServer::get_bus_effect_instance(int p_bus, int p_effect, int p_channel) { - ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffectInstance>()); ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), Ref<AudioEffectInstance>()); ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), Ref<AudioEffectInstance>()); @@ -883,7 +848,6 @@ Ref<AudioEffectInstance> AudioServer::get_bus_effect_instance(int p_bus, int p_e } Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus, int p_effect) { - ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffect>()); ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), Ref<AudioEffect>()); @@ -891,7 +855,6 @@ Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus, int p_effect) { } void AudioServer::swap_bus_effects(int p_bus, int p_effect, int p_by_effect) { - ERR_FAIL_INDEX(p_bus, buses.size()); ERR_FAIL_INDEX(p_effect, buses[p_bus]->effects.size()); ERR_FAIL_INDEX(p_by_effect, buses[p_bus]->effects.size()); @@ -905,7 +868,6 @@ void AudioServer::swap_bus_effects(int p_bus, int p_effect, int p_by_effect) { } void AudioServer::set_bus_effect_enabled(int p_bus, int p_effect, bool p_enabled) { - ERR_FAIL_INDEX(p_bus, buses.size()); ERR_FAIL_INDEX(p_effect, buses[p_bus]->effects.size()); @@ -913,22 +875,21 @@ void AudioServer::set_bus_effect_enabled(int p_bus, int p_effect, bool p_enabled buses.write[p_bus]->effects.write[p_effect].enabled = p_enabled; } -bool AudioServer::is_bus_effect_enabled(int p_bus, int p_effect) const { +bool AudioServer::is_bus_effect_enabled(int p_bus, int p_effect) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), false); ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), false); return buses[p_bus]->effects[p_effect].enabled; } float AudioServer::get_bus_peak_volume_left_db(int p_bus, int p_channel) const { - ERR_FAIL_INDEX_V(p_bus, buses.size(), 0); ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), 0); return buses[p_bus]->channels[p_channel].peak_volume.l; } -float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const { +float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const { ERR_FAIL_INDEX_V(p_bus, buses.size(), 0); ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), 0); @@ -936,7 +897,6 @@ float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const } bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const { - ERR_FAIL_INDEX_V(p_bus, buses.size(), false); ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), false); @@ -944,11 +904,10 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const { } void AudioServer::set_global_rate_scale(float p_scale) { - global_rate_scale = p_scale; } -float AudioServer::get_global_rate_scale() const { +float AudioServer::get_global_rate_scale() const { return global_rate_scale; } @@ -969,7 +928,6 @@ void AudioServer::init_channels_and_buffers() { } 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::FLOAT, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); @@ -981,8 +939,9 @@ void AudioServer::init() { set_bus_count(1); set_bus_name(0, "Master"); - if (AudioDriver::get_singleton()) + if (AudioDriver::get_singleton()) { AudioDriver::get_singleton()->start(); + } #ifdef TOOLS_ENABLED set_edited(false); //avoid editors from thinking this was edited @@ -994,35 +953,39 @@ void AudioServer::init() { void AudioServer::update() { #ifdef DEBUG_ENABLED if (EngineDebugger::is_profiling("servers")) { - // Driver time includes server time + effects times // Server time includes effects times uint64_t driver_time = AudioDriver::get_singleton()->get_profiling_time(); uint64_t server_time = prof_time; // Subtract the server time from the driver time - if (driver_time > server_time) + if (driver_time > server_time) { driver_time -= server_time; + } Array values; for (int i = buses.size() - 1; i >= 0; i--) { Bus *bus = buses[i]; - if (bus->bypass) + if (bus->bypass) { continue; + } for (int j = 0; j < bus->effects.size(); j++) { - if (!bus->effects[j].enabled) + if (!bus->effects[j].enabled) { continue; + } values.push_back(String(bus->name) + bus->effects[j].effect->get_name()); values.push_back(USEC_TO_SEC(bus->effects[j].prof_time)); // Subtract the effect time from the driver and server times - if (driver_time > bus->effects[j].prof_time) + if (driver_time > bus->effects[j].prof_time) { driver_time -= bus->effects[j].prof_time; - if (server_time > bus->effects[j].prof_time) + } + if (server_time > bus->effects[j].prof_time) { server_time -= bus->effects[j].prof_time; + } } } @@ -1038,12 +1001,14 @@ void AudioServer::update() { // Reset profiling times for (int i = buses.size() - 1; i >= 0; i--) { Bus *bus = buses[i]; - if (bus->bypass) + if (bus->bypass) { continue; + } for (int j = 0; j < bus->effects.size(); j++) { - if (!bus->effects[j].enabled) + if (!bus->effects[j].enabled) { continue; + } bus->effects.write[j].prof_time = 0; } @@ -1054,13 +1019,11 @@ void AudioServer::update() { #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() { - String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); if (ResourceLoader::exists(layout_path)) { @@ -1072,7 +1035,6 @@ void AudioServer::load_default_bus_layout() { } void AudioServer::finish() { - for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) { AudioDriverManager::get_driver(i)->finish(); } @@ -1087,45 +1049,38 @@ void AudioServer::finish() { /* MISC config */ void AudioServer::lock() { - AudioDriver::get_singleton()->lock(); } -void AudioServer::unlock() { +void AudioServer::unlock() { AudioDriver::get_singleton()->unlock(); } AudioServer::SpeakerMode AudioServer::get_speaker_mode() const { - return (AudioServer::SpeakerMode)AudioDriver::get_singleton()->get_speaker_mode(); } -float AudioServer::get_mix_rate() const { +float AudioServer::get_mix_rate() const { return AudioDriver::get_singleton()->get_mix_rate(); } float AudioServer::read_output_peak_db() const { - return 0; } AudioServer *AudioServer::get_singleton() { - return singleton; } double AudioServer::get_output_latency() const { - return AudioDriver::get_singleton()->get_latency(); } double AudioServer::get_time_to_next_mix() const { - return AudioDriver::get_singleton()->get_time_to_next_mix(); } double AudioServer::get_time_since_last_mix() const { - return AudioDriver::get_singleton()->get_time_since_last_mix(); } @@ -1141,7 +1096,6 @@ void AudioServer::add_callback(AudioCallback p_callback, void *p_userdata) { } void AudioServer::remove_callback(AudioCallback p_callback, void *p_userdata) { - lock(); CallbackItem ci; ci.callback = p_callback; @@ -1160,7 +1114,6 @@ void AudioServer::add_update_callback(AudioCallback p_callback, void *p_userdata } void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userdata) { - lock(); CallbackItem ci; ci.callback = p_callback; @@ -1170,7 +1123,6 @@ void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userd } 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); lock(); @@ -1194,11 +1146,9 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) { bus->volume_db = p_bus_layout->buses[i].volume_db; for (int j = 0; j < p_bus_layout->buses[i].effects.size(); j++) { - Ref<AudioEffect> fx = p_bus_layout->buses[i].effects[j].effect; if (fx.is_valid()) { - Bus::Effect bfx; bfx.effect = fx; bfx.enabled = p_bus_layout->buses[i].effects[j].enabled; @@ -1222,14 +1172,12 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) { } Ref<AudioBusLayout> AudioServer::generate_bus_layout() const { - Ref<AudioBusLayout> state; state.instance(); state->buses.resize(buses.size()); for (int i = 0; i < buses.size(); i++) { - state->buses.write[i].name = buses[i]->name; state->buses.write[i].send = buses[i]->send; state->buses.write[i].mute = buses[i]->mute; @@ -1248,37 +1196,30 @@ Ref<AudioBusLayout> AudioServer::generate_bus_layout() const { } Array AudioServer::get_device_list() { - return AudioDriver::get_singleton()->get_device_list(); } String AudioServer::get_device() { - return AudioDriver::get_singleton()->get_device(); } void AudioServer::set_device(String device) { - AudioDriver::get_singleton()->set_device(device); } Array AudioServer::capture_get_device_list() { - return AudioDriver::get_singleton()->capture_get_device_list(); } String AudioServer::capture_get_device() { - return AudioDriver::get_singleton()->capture_get_device(); } void AudioServer::capture_set_device(const String &p_name) { - AudioDriver::get_singleton()->capture_set_device(p_name); } void AudioServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count); ClassDB::bind_method(D_METHOD("get_bus_count"), &AudioServer::get_bus_count); @@ -1357,7 +1298,6 @@ void AudioServer::_bind_methods() { } AudioServer::AudioServer() { - singleton = this; mix_frames = 0; channel_count = 0; @@ -1371,14 +1311,12 @@ AudioServer::AudioServer() { } AudioServer::~AudioServer() { - singleton = nullptr; } ///////////////////////////////// bool AudioBusLayout::_set(const StringName &p_name, const Variant &p_value) { - String s = p_name; if (s.begins_with("bus/")) { int index = s.get_slice("/", 1).to_int(); @@ -1431,13 +1369,12 @@ bool AudioBusLayout::_set(const StringName &p_name, const Variant &p_value) { } bool AudioBusLayout::_get(const StringName &p_name, Variant &r_ret) const { - String s = p_name; if (s.begins_with("bus/")) { - int index = s.get_slice("/", 1).to_int(); - if (index < 0 || index >= buses.size()) + if (index < 0 || index >= buses.size()) { return false; + } const Bus &bus = buses[index]; @@ -1482,8 +1419,8 @@ bool AudioBusLayout::_get(const StringName &p_name, Variant &r_ret) const { return false; } -void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const { +void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const { for (int i = 0; i < buses.size(); i++) { p_list->push_back(PropertyInfo(Variant::STRING, "bus/" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::BOOL, "bus/" + itos(i) + "/solo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); @@ -1500,7 +1437,6 @@ void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const { } AudioBusLayout::AudioBusLayout() { - buses.resize(1); buses.write[0].name = "Master"; } diff --git a/servers/audio_server.h b/servers/audio_server.h index a1a3dde719..80e244aacd 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -42,7 +42,6 @@ class AudioStream; class AudioStreamSample; class AudioDriver { - static AudioDriver *singleton; uint64_t _last_mix_time; uint64_t _last_mix_frames; @@ -81,9 +80,6 @@ public: SPEAKER_SURROUND_71, }; - static const int DEFAULT_MIX_RATE = 44100; - static const int DEFAULT_OUTPUT_LATENCY = 15; - static AudioDriver *get_singleton(); void set_singleton(); @@ -125,12 +121,14 @@ public: }; class AudioDriverManager { - enum { MAX_DRIVERS = 10 }; + static const int DEFAULT_MIX_RATE = 44100; + static const int DEFAULT_OUTPUT_LATENCY = 15; + static AudioDriver *drivers[MAX_DRIVERS]; static int driver_count; @@ -146,7 +144,6 @@ public: class AudioBusLayout; class AudioServer : public Object { - GDCLASS(AudioServer, Object); public: @@ -184,7 +181,6 @@ private: float global_rate_scale; struct Bus { - StringName name; bool solo; bool mute; @@ -237,7 +233,6 @@ private: void _mix_step(); struct CallbackItem { - AudioCallback callback; void *userdata; @@ -258,10 +253,14 @@ protected: public: _FORCE_INLINE_ int get_channel_count() const { switch (get_speaker_mode()) { - case SPEAKER_MODE_STEREO: return 1; - case SPEAKER_SURROUND_31: return 2; - case SPEAKER_SURROUND_51: return 3; - case SPEAKER_SURROUND_71: return 4; + case SPEAKER_MODE_STEREO: + return 1; + case SPEAKER_SURROUND_31: + return 2; + case SPEAKER_SURROUND_51: + return 3; + case SPEAKER_SURROUND_71: + return 4; } ERR_FAIL_V(1); } @@ -366,13 +365,11 @@ public: VARIANT_ENUM_CAST(AudioServer::SpeakerMode) class AudioBusLayout : public Resource { - GDCLASS(AudioBusLayout, Resource); friend class AudioServer; struct Bus { - StringName name; bool solo; bool mute; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index da1a68a179..0ea11a2670 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -30,7 +30,7 @@ #include "display_server.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "scene/resources/texture.h" DisplayServer *DisplayServer::singleton = nullptr; @@ -127,6 +127,7 @@ void DisplayServer::global_menu_clear(const String &p_menu_root) { void DisplayServer::mouse_set_mode(MouseMode p_mode) { WARN_PRINT("Mouse is not supported by this display server."); } + DisplayServer::MouseMode DisplayServer::mouse_get_mode() const { return MOUSE_MODE_VISIBLE; } @@ -134,12 +135,15 @@ DisplayServer::MouseMode DisplayServer::mouse_get_mode() const { void DisplayServer::mouse_warp_to_position(const Point2i &p_to) { WARN_PRINT("Mouse warping is not supported by this display server."); } + Point2i DisplayServer::mouse_get_absolute_position() const { ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server."); } + Point2i DisplayServer::mouse_get_position() const { ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server."); } + int DisplayServer::mouse_get_button_state() const { ERR_FAIL_V_MSG(0, "Mouse is not supported by this display server."); } @@ -147,6 +151,7 @@ int DisplayServer::mouse_get_button_state() const { void DisplayServer::clipboard_set(const String &p_text) { WARN_PRINT("Clipboard is not supported by this display server."); } + String DisplayServer::clipboard_get() const { ERR_FAIL_V_MSG(String(), "Clipboard is not supported by this display server."); } @@ -154,6 +159,7 @@ String DisplayServer::clipboard_get() const { void DisplayServer::screen_set_orientation(ScreenOrientation p_orientation, int p_screen) { WARN_PRINT("Orientation not supported by this display server."); } + DisplayServer::ScreenOrientation DisplayServer::screen_get_orientation(int p_screen) const { return SCREEN_LANDSCAPE; } @@ -164,12 +170,13 @@ float DisplayServer::screen_get_scale(int p_screen) const { bool DisplayServer::screen_is_touchscreen(int p_screen) const { //return false; - return InputFilter::get_singleton() && InputFilter::get_singleton()->is_emulating_touch_from_mouse(); + return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse(); } void DisplayServer::screen_set_keep_on(bool p_enable) { WARN_PRINT("Keeping screen on not supported by this display server."); } + bool DisplayServer::screen_is_kept_on() const { return false; } @@ -177,6 +184,7 @@ bool DisplayServer::screen_is_kept_on() const { DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &) { ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server."); } + void DisplayServer::delete_sub_window(WindowID p_id) { ERR_FAIL_MSG("Sub-windows not supported by this display server."); } @@ -184,6 +192,7 @@ void DisplayServer::delete_sub_window(WindowID p_id) { void DisplayServer::window_set_ime_active(const bool p_active, WindowID p_window) { WARN_PRINT("IME not supported by this display server."); } + void DisplayServer::window_set_ime_position(const Point2i &p_pos, WindowID p_window) { WARN_PRINT("IME not supported by this display server."); } @@ -191,6 +200,7 @@ void DisplayServer::window_set_ime_position(const Point2i &p_pos, WindowID p_win Point2i DisplayServer::ime_get_selection() const { ERR_FAIL_V_MSG(Point2i(), "IME or NOTIFICATION_WM_IME_UPDATE not supported by this display server."); } + String DisplayServer::ime_get_text() const { ERR_FAIL_V_MSG(String(), "IME or NOTIFICATION_WM_IME_UPDATEnot supported by this display server."); } @@ -198,13 +208,15 @@ String DisplayServer::ime_get_text() const { void DisplayServer::console_set_visible(bool p_enabled) { WARN_PRINT("Console window not supported by this display server."); } + bool DisplayServer::is_console_visible() const { return false; } -void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_legth) { +void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) { WARN_PRINT("Virtual keyboard not supported by this display server."); } + void DisplayServer::virtual_keyboard_hide() { WARN_PRINT("Virtual keyboard not supported by this display server."); } @@ -217,9 +229,11 @@ int DisplayServer::virtual_keyboard_get_height() const { void DisplayServer::cursor_set_shape(CursorShape p_shape) { WARN_PRINT("Cursor shape not supported by this display server."); } + DisplayServer::CursorShape DisplayServer::cursor_get_shape() const { return CURSOR_ARROW; } + void DisplayServer::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { WARN_PRINT("Custom cursor shape not supported by this display server."); } @@ -235,15 +249,19 @@ void DisplayServer::enable_for_stealing_focus(OS::ProcessID pid) { Error DisplayServer::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track, int p_screen) { ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Native video not supported by this display server."); } + bool DisplayServer::native_video_is_playing() const { return false; } + void DisplayServer::native_video_pause() { WARN_PRINT("Native video not supported by this display server."); } + void DisplayServer::native_video_unpause() { WARN_PRINT("Native video not supported by this display server."); } + void DisplayServer::native_video_stop() { WARN_PRINT("Native video not supported by this display server."); } @@ -252,13 +270,29 @@ Error DisplayServer::dialog_show(String p_title, String p_description, Vector<St WARN_PRINT("Native dialogs not supported by this display server."); return OK; } + Error DisplayServer::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) { WARN_PRINT("Native dialogs not supported by this display server."); return OK; } -DisplayServer::LatinKeyboardVariant DisplayServer::get_latin_keyboard_variant() const { - return LATIN_KEYBOARD_QWERTY; +int DisplayServer::keyboard_get_layout_count() const { + return 0; +} + +int DisplayServer::keyboard_get_current_layout() const { + return -1; +} + +void DisplayServer::keyboard_set_current_layout(int p_index) { +} + +String DisplayServer::keyboard_get_layout_language(int p_index) const { + return ""; +} + +String DisplayServer::keyboard_get_layout_name(int p_index) const { + return "Not supported"; } void DisplayServer::force_process_and_drop_events() { @@ -267,9 +301,11 @@ void DisplayServer::force_process_and_drop_events() { void DisplayServer::release_rendering_thread() { WARN_PRINT("Rendering thread not supported by this display server."); } + void DisplayServer::make_rendering_thread() { WARN_PRINT("Rendering thread not supported by this display server."); } + void DisplayServer::swap_buffers() { WARN_PRINT("Swap buffers not supported by this display server."); } @@ -277,6 +313,7 @@ void DisplayServer::swap_buffers() { void DisplayServer::set_native_icon(const String &p_filename) { WARN_PRINT("Native icon not supported by this display server."); } + void DisplayServer::set_icon(const Ref<Image> &p_icon) { WARN_PRINT("Icon not supported by this display server."); } @@ -284,6 +321,7 @@ void DisplayServer::set_icon(const Ref<Image> &p_icon) { void DisplayServer::_set_use_vsync(bool p_enable) { WARN_PRINT("VSync not supported by this display server."); } + void DisplayServer::vsync_set_enabled(bool p_enable) { vsync_enabled = p_enable; if (switch_vsync_function) { //if a function was set, use function @@ -292,6 +330,7 @@ void DisplayServer::vsync_set_enabled(bool p_enable) { _set_use_vsync(p_enable); } } + bool DisplayServer::vsync_is_enabled() const { return vsync_enabled; } @@ -299,6 +338,7 @@ bool DisplayServer::vsync_is_enabled() const { void DisplayServer::vsync_set_use_via_compositor(bool p_enable) { WARN_PRINT("VSync via compositor not supported by this display server."); } + bool DisplayServer::vsync_is_using_via_compositor() const { return false; } @@ -307,7 +347,6 @@ void DisplayServer::set_context(Context p_context) { } void DisplayServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature); ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name); @@ -415,7 +454,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("console_set_visible", "console_visible"), &DisplayServer::console_set_visible); ClassDB::bind_method(D_METHOD("is_console_visible"), &DisplayServer::is_console_visible); - ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide); ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height); @@ -437,7 +476,11 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("dialog_show", "title", "description", "buttons", "callback"), &DisplayServer::dialog_show); ClassDB::bind_method(D_METHOD("dialog_input_text", "title", "description", "existing_text", "callback"), &DisplayServer::dialog_input_text); - ClassDB::bind_method(D_METHOD("get_latin_keyboard_variant"), &DisplayServer::get_latin_keyboard_variant); + ClassDB::bind_method(D_METHOD("keyboard_get_layout_count"), &DisplayServer::keyboard_get_layout_count); + ClassDB::bind_method(D_METHOD("keyboard_get_current_layout"), &DisplayServer::keyboard_get_current_layout); + ClassDB::bind_method(D_METHOD("keyboard_set_current_layout", "index"), &DisplayServer::keyboard_set_current_layout); + ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &DisplayServer::keyboard_get_layout_language); + ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &DisplayServer::keyboard_get_layout_name); ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events); ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events); @@ -519,14 +562,6 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_FLAG_NO_FOCUS); BIND_ENUM_CONSTANT(WINDOW_FLAG_MAX); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_QWERTY); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_QWERTZ); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_AZERTY); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_QZERTY); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_DVORAK); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_NEO); - BIND_ENUM_CONSTANT(LATIN_KEYBOARD_COLEMAK); - BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER); BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_EXIT); BIND_ENUM_CONSTANT(WINDOW_EVENT_FOCUS_IN); @@ -563,31 +598,34 @@ DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driv return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error); } -void DisplayServer::_input_set_mouse_mode(InputFilter::MouseMode p_mode) { +void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) { singleton->mouse_set_mode(MouseMode(p_mode)); } -InputFilter::MouseMode DisplayServer::_input_get_mouse_mode() { - return InputFilter::MouseMode(singleton->mouse_get_mode()); + +Input::MouseMode DisplayServer::_input_get_mouse_mode() { + return Input::MouseMode(singleton->mouse_get_mode()); } void DisplayServer::_input_warp(const Vector2 &p_to_pos) { singleton->mouse_warp_to_position(p_to_pos); } -InputFilter::CursorShape DisplayServer::_input_get_current_cursor_shape() { - return (InputFilter::CursorShape)singleton->cursor_get_shape(); +Input::CursorShape DisplayServer::_input_get_current_cursor_shape() { + return (Input::CursorShape)singleton->cursor_get_shape(); } -void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, InputFilter::CursorShape p_shape, const Vector2 &p_hostspot) { + +void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) { singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot); } DisplayServer::DisplayServer() { singleton = this; - InputFilter::set_mouse_mode_func = _input_set_mouse_mode; - InputFilter::get_mouse_mode_func = _input_get_mouse_mode; - InputFilter::warp_mouse_func = _input_warp; - InputFilter::get_current_cursor_shape_func = _input_get_current_cursor_shape; - InputFilter::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func; + Input::set_mouse_mode_func = _input_set_mouse_mode; + Input::get_mouse_mode_func = _input_get_mouse_mode; + Input::warp_mouse_func = _input_warp; + Input::get_current_cursor_shape_func = _input_get_current_cursor_shape; + Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func; } + DisplayServer::~DisplayServer() { } diff --git a/servers/display_server.h b/servers/display_server.h index 93db7ef844..166274f8ed 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -32,7 +32,7 @@ #define DISPLAY_SERVER_H #include "core/callable.h" -#include "core/input/input_filter.h" +#include "core/input/input.h" #include "core/os/os.h" #include "core/resource.h" @@ -61,11 +61,11 @@ public: typedef Vector<String> (*GetRenderingDriversFunction)(); private: - static void _input_set_mouse_mode(InputFilter::MouseMode p_mode); - static InputFilter::MouseMode _input_get_mouse_mode(); + static void _input_set_mouse_mode(Input::MouseMode p_mode); + static Input::MouseMode _input_get_mouse_mode(); static void _input_warp(const Vector2 &p_to_pos); - static InputFilter::CursorShape _input_get_current_cursor_shape(); - static void _input_set_custom_mouse_cursor_func(const RES &, InputFilter::CursorShape, const Vector2 &p_hostspot); + static Input::CursorShape _input_get_current_cursor_shape(); + static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot); protected: static void _bind_methods(); @@ -280,7 +280,7 @@ public: virtual void console_set_visible(bool p_enabled); virtual bool is_console_visible() const; - virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_legth = -1); + virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1); virtual void virtual_keyboard_hide(); // returns height of the currently shown virtual keyboard (0 if keyboard is hidden) @@ -324,17 +324,11 @@ public: virtual Error dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback); virtual Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback); - enum LatinKeyboardVariant { - LATIN_KEYBOARD_QWERTY, - LATIN_KEYBOARD_QWERTZ, - LATIN_KEYBOARD_AZERTY, - LATIN_KEYBOARD_QZERTY, - LATIN_KEYBOARD_DVORAK, - LATIN_KEYBOARD_NEO, - LATIN_KEYBOARD_COLEMAK, - }; - - virtual LatinKeyboardVariant get_latin_keyboard_variant() const; + virtual int keyboard_get_layout_count() const; + virtual int keyboard_get_current_layout() const; + virtual void keyboard_set_current_layout(int p_index); + virtual String keyboard_get_layout_language(int p_index) const; + virtual String keyboard_get_layout_name(int p_index) const; virtual void process_events() = 0; @@ -384,6 +378,5 @@ VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation) VARIANT_ENUM_CAST(DisplayServer::WindowMode) VARIANT_ENUM_CAST(DisplayServer::WindowFlags) VARIANT_ENUM_CAST(DisplayServer::CursorShape) -VARIANT_ENUM_CAST(DisplayServer::LatinKeyboardVariant) #endif // DISPLAY_SERVER_H diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 17f2232c72..b20f6865cd 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -83,21 +83,27 @@ NavigationServer2D *NavigationServer2D::singleton = nullptr; static RID rid_to_rid(const RID d) { return d; } + static bool bool_to_bool(const bool d) { return d; } + static int int_to_int(const int d) { return d; } + static real_t real_to_real(const real_t d) { return d; } + static Vector3 v2_to_v3(const Vector2 d) { return Vector3(d.x, 0.0, d.y); } + static Vector2 v3_to_v2(const Vector3 &d) { return Vector2(d.x, d.z); } + static Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) { Vector<Vector2> nd; nd.resize(d.size()); @@ -106,21 +112,26 @@ static Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) { } return nd; } + static Transform trf2_to_trf3(const Transform2D &d) { Vector3 o(v2_to_v3(d.get_origin())); Basis b; b.rotate(Vector3(0, 1, 0), d.get_rotation()); return Transform(b, o); } + static Object *obj_to_obj(Object *d) { return d; } + static StringName sn_to_sn(StringName &d) { return d; } + static Variant var_to_var(Variant &d) { return d; } + static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) { if (d.is_valid()) { return d->get_mesh(); diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 67a4d0e413..8f9b5df589 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -37,7 +37,6 @@ NavigationServer3D *NavigationServer3D::singleton = nullptr; void NavigationServer3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer3D::map_create); ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer3D::map_set_active); ClassDB::bind_method(D_METHOD("map_is_active", "nap"), &NavigationServer3D::map_is_active); diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 85ec2aae47..acbbb7e1e8 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -38,6 +38,7 @@ Area2DSW::BodyKey::BodyKey(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_a body_shape = p_body_shape; area_shape = p_area_shape; } + Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); @@ -46,27 +47,28 @@ Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_a } void Area2DSW::_shapes_changed() { - - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area2DSW::set_transform(const Transform2D &p_transform) { - - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } _set_transform(p_transform); _set_inv_transform(p_transform.affine_inverse()); } void Area2DSW::set_space(Space2DSW *p_space) { - if (get_space()) { - if (monitor_query_list.in_list()) + if (monitor_query_list.in_list()) { get_space()->area_remove_from_monitor_query_list(&monitor_query_list); - if (moved_list.in_list()) + } + if (moved_list.in_list()) { get_space()->area_remove_from_moved_list(&moved_list); + } } monitored_bodies.clear(); @@ -76,7 +78,6 @@ void Area2DSW::set_space(Space2DSW *p_space) { } void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == monitor_callback_id) { monitor_callback_method = p_method; return; @@ -92,12 +93,12 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { _shape_changed(); - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == area_monitor_callback_id) { area_monitor_callback_method = p_method; return; @@ -113,74 +114,97 @@ void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth _shape_changed(); - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area2DSW::set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode p_mode) { bool do_override = p_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED; - if (do_override == (space_override_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)) + if (do_override == (space_override_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)) { return; + } _unregister_shapes(); space_override_mode = p_mode; _shape_changed(); } void Area2DSW::set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value) { - switch (p_param) { - case PhysicsServer2D::AREA_PARAM_GRAVITY: gravity = p_value; break; - case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: gravity_vector = p_value; break; - case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point = p_value; break; - case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale = p_value; break; - case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation = p_value; break; - case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: linear_damp = p_value; break; - case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: angular_damp = p_value; break; - case PhysicsServer2D::AREA_PARAM_PRIORITY: priority = p_value; break; + case PhysicsServer2D::AREA_PARAM_GRAVITY: + gravity = p_value; + break; + case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: + gravity_vector = p_value; + break; + case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: + gravity_is_point = p_value; + break; + case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: + gravity_distance_scale = p_value; + break; + case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: + point_attenuation = p_value; + break; + case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: + linear_damp = p_value; + break; + case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: + angular_damp = p_value; + break; + case PhysicsServer2D::AREA_PARAM_PRIORITY: + priority = p_value; + break; } } Variant Area2DSW::get_param(PhysicsServer2D::AreaParameter p_param) const { - switch (p_param) { - case PhysicsServer2D::AREA_PARAM_GRAVITY: return gravity; - case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector; - case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point; - case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale; - case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation; - case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: return linear_damp; - case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: return angular_damp; - case PhysicsServer2D::AREA_PARAM_PRIORITY: return priority; + case PhysicsServer2D::AREA_PARAM_GRAVITY: + return gravity; + case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: + return gravity_vector; + case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: + return gravity_is_point; + case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: + return gravity_distance_scale; + case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: + return point_attenuation; + case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: + return linear_damp; + case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: + return angular_damp; + case PhysicsServer2D::AREA_PARAM_PRIORITY: + return priority; } return Variant(); } void Area2DSW::_queue_monitor_update() { - ERR_FAIL_COND(!get_space()); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { get_space()->area_add_to_monitor_query_list(&monitor_query_list); + } } void Area2DSW::set_monitorable(bool p_monitorable) { - - if (monitorable == p_monitorable) + if (monitorable == p_monitorable) { return; + } monitorable = p_monitorable; _set_static(!monitorable); } void Area2DSW::call_queries() { - if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) { - Variant res[5]; Variant *resptr[5]; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { resptr[i] = &res[i]; + } Object *obj = ObjectDB::get_instance(monitor_callback_id); if (!obj) { @@ -190,9 +214,9 @@ void Area2DSW::call_queries() { } for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) { - - if (E->get().state == 0) + if (E->get().state == 0) { continue; //nothing happened + } res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; res[1] = E->key().rid; @@ -208,11 +232,11 @@ void Area2DSW::call_queries() { monitored_bodies.clear(); if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) { - Variant res[5]; Variant *resptr[5]; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { resptr[i] = &res[i]; + } Object *obj = ObjectDB::get_instance(area_monitor_callback_id); if (!obj) { @@ -222,9 +246,9 @@ void Area2DSW::call_queries() { } for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) { - - if (E->get().state == 0) + if (E->get().state == 0) { continue; //nothing happened + } res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; res[1] = E->key().rid; @@ -246,7 +270,6 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), moved_list(this) { - _set_static(true); //areas are not active by default space_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED; gravity = 9.80665; diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index ae2a8ff995..f14466f582 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -41,7 +41,6 @@ class Body2DSW; class Constraint2DSW; class Area2DSW : public CollisionObject2DSW { - PhysicsServer2D::AreaSpaceOverrideMode space_override_mode; real_t gravity; Vector2 gravity_vector; @@ -63,23 +62,21 @@ class Area2DSW : public CollisionObject2DSW { SelfList<Area2DSW> moved_list; struct BodyKey { - RID rid; ObjectID instance_id; uint32_t body_shape; uint32_t area_shape; _FORCE_INLINE_ bool operator<(const BodyKey &p_key) const { - if (rid == p_key.rid) { - if (body_shape == p_key.body_shape) { - return area_shape < p_key.area_shape; - } else + } else { return body_shape < p_key.body_shape; - } else + } + } else { return rid < p_key.rid; + } } _FORCE_INLINE_ BodyKey() {} @@ -88,7 +85,6 @@ class Area2DSW : public CollisionObject2DSW { }; struct BodyState { - int state; _FORCE_INLINE_ void inc() { state++; } _FORCE_INLINE_ void dec() { state--; } @@ -170,33 +166,35 @@ public: }; void Area2DSW::add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { - BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].inc(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } -void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { - BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].inc(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } -void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } #endif // AREA_2D_SW_H diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 0e70a626c2..d7bceb9f02 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -32,7 +32,6 @@ #include "collision_solver_2d_sw.h" bool AreaPair2DSW::setup(real_t p_step) { - bool result = false; if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) { @@ -42,20 +41,21 @@ bool AreaPair2DSW::setup(real_t p_step) { } if (result != colliding) { - if (result) { - - if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) { body->add_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->add_body_to_query(body, body_shape, area_shape); + } } else { - - if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->remove_body_from_query(body, body_shape, area_shape); + } } colliding = result; @@ -68,7 +68,6 @@ void AreaPair2DSW::solve(real_t p_step) { } AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, int p_area_shape) { - body = p_body; area = p_area; body_shape = p_body_shape; @@ -76,18 +75,19 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, colliding = false; body->add_constraint(this, 0); area->add_constraint(this); - if (p_body->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) //need to be active to process pair + if (p_body->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) { //need to be active to process pair p_body->set_active(true); + } } AreaPair2DSW::~AreaPair2DSW() { - if (colliding) { - - if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->remove_body_from_query(body, body_shape, area_shape); + } } body->remove_constraint(this); area->remove_constraint(this); @@ -96,7 +96,6 @@ AreaPair2DSW::~AreaPair2DSW() { ////////////////////////////////// bool Area2Pair2DSW::setup(real_t p_step) { - bool result = false; if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) { result = false; @@ -105,22 +104,23 @@ bool Area2Pair2DSW::setup(real_t p_step) { } if (result != colliding) { - if (result) { - - if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) { area_b->add_area_to_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_b->is_monitorable()) { area_a->add_area_to_query(area_b, shape_b, shape_a); + } } else { - - if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) { 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_b->is_monitorable()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); + } } colliding = result; @@ -133,7 +133,6 @@ void Area2Pair2DSW::solve(real_t p_step) { } Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area_b, int p_shape_b) { - area_a = p_area_a; area_b = p_area_b; shape_a = p_shape_a; @@ -144,14 +143,14 @@ Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area } Area2Pair2DSW::~Area2Pair2DSW() { - if (colliding) { - - if (area_b->has_area_monitor_callback()) + 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()) + if (area_a->has_area_monitor_callback()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); + } } area_a->remove_constraint(this); diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h index 78173d98b2..5e8670b464 100644 --- a/servers/physics_2d/area_pair_2d_sw.h +++ b/servers/physics_2d/area_pair_2d_sw.h @@ -36,7 +36,6 @@ #include "constraint_2d_sw.h" class AreaPair2DSW : public Constraint2DSW { - Body2DSW *body; Area2DSW *area; int body_shape; @@ -52,7 +51,6 @@ public: }; class Area2Pair2DSW : public Constraint2DSW { - Area2DSW *area_a; Area2DSW *area_b; int shape_a; diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index 39e28fd002..856bba78f7 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -34,19 +34,16 @@ #include "space_2d_sw.h" void Body2DSW::_update_inertia() { - - if (!user_inertia && get_space() && !inertia_update_list.in_list()) + if (!user_inertia && get_space() && !inertia_update_list.in_list()) { get_space()->body_add_to_inertia_update_list(&inertia_update_list); + } } void Body2DSW::update_inertias() { - //update shapes and motions switch (mode) { - case PhysicsServer2D::BODY_MODE_RIGID: { - if (user_inertia) { _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0; break; @@ -55,14 +52,12 @@ void Body2DSW::update_inertias() { real_t total_area = 0; for (int i = 0; i < get_shape_count(); i++) { - total_area += get_shape_aabb(i).get_area(); } inertia = 0; for (int i = 0; i < get_shape_count(); i++) { - if (is_shape_disabled(i)) { continue; } @@ -80,20 +75,19 @@ void Body2DSW::update_inertias() { _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0; - if (mass) + if (mass) { _inv_mass = 1.0 / mass; - else + } else { _inv_mass = 0; + } } break; case PhysicsServer2D::BODY_MODE_KINEMATIC: case PhysicsServer2D::BODY_MODE_STATIC: { - _inv_inertia = 0; _inv_mass = 0; } break; case PhysicsServer2D::BODY_MODE_CHARACTER: { - _inv_inertia = 0; _inv_mass = 1.0 / mass; @@ -105,19 +99,22 @@ void Body2DSW::update_inertias() { } void Body2DSW::set_active(bool p_active) { - - if (active == p_active) + if (active == p_active) { return; + } active = p_active; if (!p_active) { - if (get_space()) + if (get_space()) { get_space()->body_remove_from_active_list(&active_list); + } } else { - if (mode == PhysicsServer2D::BODY_MODE_STATIC) + if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; //static bodies can't become active - if (get_space()) + } + if (get_space()) { get_space()->body_add_to_active_list(&active_list); + } //still_time=0; } @@ -135,14 +132,11 @@ void Body2DSW::set_active(bool p_active) { } void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value) { - switch (p_param) { case PhysicsServer2D::BODY_PARAM_BOUNCE: { - bounce = p_value; } break; case PhysicsServer2D::BODY_PARAM_FRICTION: { - friction = p_value; } break; case PhysicsServer2D::BODY_PARAM_MASS: { @@ -165,11 +159,9 @@ void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value) gravity_scale = p_value; } break; case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: { - linear_damp = p_value; } break; case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP: { - angular_damp = p_value; } break; default: { @@ -178,14 +170,11 @@ void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value) } real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const { - switch (p_param) { case PhysicsServer2D::BODY_PARAM_BOUNCE: { - return bounce; } case PhysicsServer2D::BODY_PARAM_FRICTION: { - return friction; } case PhysicsServer2D::BODY_PARAM_MASS: { @@ -198,11 +187,9 @@ real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const { return gravity_scale; } case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: { - return linear_damp; } case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP: { - return angular_damp; } default: { @@ -213,7 +200,6 @@ real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const { } void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { - PhysicsServer2D::BodyMode prev = mode; mode = p_mode; @@ -221,7 +207,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { //CLEAR UP EVERYTHING IN CASE IT NOT WORKS! case PhysicsServer2D::BODY_MODE_STATIC: case PhysicsServer2D::BODY_MODE_KINEMATIC: { - _set_inv_transform(get_transform().affine_inverse()); _inv_mass = 0; _inv_inertia = 0; @@ -234,7 +219,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { } } break; case PhysicsServer2D::BODY_MODE_RIGID: { - _inv_mass = mass > 0 ? (1.0 / mass) : 0; _inv_inertia = inertia > 0 ? (1.0 / inertia) : 0; _set_static(false); @@ -242,7 +226,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { } break; case PhysicsServer2D::BODY_MODE_CHARACTER: { - _inv_mass = mass > 0 ? (1.0 / mass) : 0; _inv_inertia = 0; _set_static(false); @@ -258,24 +241,20 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) { _update_queries(); */ } -PhysicsServer2D::BodyMode Body2DSW::get_mode() const { +PhysicsServer2D::BodyMode Body2DSW::get_mode() const { return mode; } void Body2DSW::_shapes_changed() { - _update_inertia(); wakeup_neighbours(); } void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_variant) { - switch (p_state) { case PhysicsServer2D::BODY_STATE_TRANSFORM: { - if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { - new_transform = p_variant; //wakeup_neighbours(); set_active(true); @@ -292,8 +271,9 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va Transform2D t = p_variant; t.orthonormalize(); new_transform = get_transform(); //used as old to compute motion - if (t == new_transform) + if (t == new_transform) { break; + } _set_transform(t); _set_inv_transform(get_transform().inverse()); } @@ -301,7 +281,6 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va } break; case PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY: { - /* if (mode==PhysicsServer2D::BODY_MODE_STATIC) break; @@ -321,8 +300,9 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va } break; case PhysicsServer2D::BODY_STATE_SLEEPING: { //? - if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) + if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { break; + } bool do_sleep = p_variant; if (do_sleep) { linear_velocity = Vector2(); @@ -331,20 +311,22 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va //biased_angular_velocity=Vector3(); set_active(false); } else { - if (mode != PhysicsServer2D::BODY_MODE_STATIC) + if (mode != PhysicsServer2D::BODY_MODE_STATIC) { set_active(true); + } } } break; case PhysicsServer2D::BODY_STATE_CAN_SLEEP: { can_sleep = p_variant; - if (mode == PhysicsServer2D::BODY_MODE_RIGID && !active && !can_sleep) + if (mode == PhysicsServer2D::BODY_MODE_RIGID && !active && !can_sleep) { set_active(true); + } } break; } } -Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const { +Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const { switch (p_state) { case PhysicsServer2D::BODY_STATE_TRANSFORM: { return get_transform(); @@ -367,26 +349,27 @@ Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const { } void Body2DSW::set_space(Space2DSW *p_space) { - if (get_space()) { - wakeup_neighbours(); - if (inertia_update_list.in_list()) + if (inertia_update_list.in_list()) { get_space()->body_remove_from_inertia_update_list(&inertia_update_list); - if (active_list.in_list()) + } + if (active_list.in_list()) { get_space()->body_remove_from_active_list(&active_list); - if (direct_state_query_list.in_list()) + } + if (direct_state_query_list.in_list()) { get_space()->body_remove_from_state_query_list(&direct_state_query_list); + } } _set_space(p_space); if (get_space()) { - _update_inertia(); - if (active) + if (active) { get_space()->body_add_to_active_list(&active_list); + } /* _update_queries(); if (is_active()) { @@ -400,7 +383,6 @@ void Body2DSW::set_space(Space2DSW *p_space) { } void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) { - if (p_area->is_gravity_point()) { if (p_area->get_gravity_distance_scale() > 0) { Vector2 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin(); @@ -417,9 +399,9 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) { } void Body2DSW::integrate_forces(real_t p_step) { - - if (mode == PhysicsServer2D::BODY_MODE_STATIC) + if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; + } Area2DSW *def_area = get_space()->get_default_area(); // Area2DSW *damp_area = def_area; @@ -461,15 +443,17 @@ void Body2DSW::integrate_forces(real_t p_step) { gravity *= gravity_scale; // If less than 0, override dampenings with that of the Body2D - if (angular_damp >= 0) + if (angular_damp >= 0) { area_angular_damp = angular_damp; + } /* else area_angular_damp=damp_area->get_angular_damp(); */ - if (linear_damp >= 0) + if (linear_damp >= 0) { area_linear_damp = linear_damp; + } /* else area_linear_damp=damp_area->get_linear_damp(); @@ -479,7 +463,6 @@ void Body2DSW::integrate_forces(real_t p_step) { bool do_motion = false; if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { - //compute motion, angular and etc. velocities from prev transform motion = new_transform.get_origin() - get_transform().get_origin(); linear_velocity = motion / p_step; @@ -506,13 +489,15 @@ void Body2DSW::integrate_forces(real_t p_step) { real_t damp = 1.0 - p_step * area_linear_damp; - if (damp < 0) // reached zero in the given time + if (damp < 0) { // reached zero in the given time damp = 0; + } real_t angular_damp = 1.0 - p_step * area_angular_damp; - if (angular_damp < 0) // reached zero in the given time + if (angular_damp < 0) { // reached zero in the given time angular_damp = 0; + } linear_velocity *= damp; angular_velocity *= angular_damp; @@ -522,7 +507,6 @@ void Body2DSW::integrate_forces(real_t p_step) { } if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) { - motion = linear_velocity * p_step; do_motion = true; } @@ -544,19 +528,20 @@ void Body2DSW::integrate_forces(real_t p_step) { } void Body2DSW::integrate_velocities(real_t p_step) { - - if (mode == PhysicsServer2D::BODY_MODE_STATIC) + if (mode == PhysicsServer2D::BODY_MODE_STATIC) { return; + } - if (fi_callback) + if (fi_callback) { get_space()->body_add_to_state_query_list(&direct_state_query_list); + } if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { - _set_transform(new_transform, false); _set_inv_transform(new_transform.affine_inverse()); - if (contacts.size() == 0 && linear_velocity == Vector2() && angular_velocity == 0) + if (contacts.size() == 0 && linear_velocity == Vector2() && angular_velocity == 0) { set_active(false); //stopped moving, deactivate + } return; } @@ -569,38 +554,37 @@ void Body2DSW::integrate_velocities(real_t p_step) { _set_transform(Transform2D(angle, pos), continuous_cd_mode == PhysicsServer2D::CCD_MODE_DISABLED); _set_inv_transform(get_transform().inverse()); - if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) + if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) { new_transform = get_transform(); + } //_update_inertia_tensor(); } void Body2DSW::wakeup_neighbours() { - for (Map<Constraint2DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) { - const Constraint2DSW *c = E->key(); Body2DSW **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { - - if (i == E->get()) + if (i == E->get()) { continue; + } Body2DSW *b = n[i]; - if (b->mode != PhysicsServer2D::BODY_MODE_RIGID) + if (b->mode != PhysicsServer2D::BODY_MODE_RIGID) { continue; + } - if (!b->is_active()) + if (!b->is_active()) { b->set_active(true); + } } } } void Body2DSW::call_queries() { - if (fi_callback) { - PhysicsDirectBodyState2DSW *dbs = PhysicsDirectBodyState2DSW::singleton; dbs->body = this; @@ -609,12 +593,10 @@ void Body2DSW::call_queries() { Object *obj = ObjectDB::get_instance(fi_callback->id); if (!obj) { - set_force_integration_callback(ObjectID(), StringName()); } else { Callable::CallError ce; if (fi_callback->callback_udata.get_type() != Variant::NIL) { - obj->call(fi_callback->method, vp, 2, ce); } else { @@ -625,36 +607,31 @@ void Body2DSW::call_queries() { } bool Body2DSW::sleep_test(real_t p_step) { - - if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) + if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { return true; // - else if (mode == PhysicsServer2D::BODY_MODE_CHARACTER) + } else if (mode == PhysicsServer2D::BODY_MODE_CHARACTER) { return !active; // characters and kinematic bodies don't sleep unless asked to sleep - else if (!can_sleep) + } else if (!can_sleep) { return false; + } if (Math::abs(angular_velocity) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) { - still_time += p_step; return still_time > get_space()->get_body_time_to_sleep(); } else { - still_time = 0; //maybe this should be set to 0 on set_active? return false; } } void Body2DSW::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) { - if (fi_callback) { - memdelete(fi_callback); fi_callback = nullptr; } if (p_id.is_valid()) { - fi_callback = memnew(ForceIntegrationCallback); fi_callback->id = p_id; fi_callback->method = p_method; @@ -667,7 +644,6 @@ Body2DSW::Body2DSW() : active_list(this), inertia_update_list(this), direct_state_query_list(this) { - mode = PhysicsServer2D::BODY_MODE_RIGID; active = true; angular_velocity = 0; @@ -701,31 +677,27 @@ Body2DSW::Body2DSW() : } Body2DSW::~Body2DSW() { - - if (fi_callback) + if (fi_callback) { memdelete(fi_callback); + } } PhysicsDirectBodyState2DSW *PhysicsDirectBodyState2DSW::singleton = nullptr; PhysicsDirectSpaceState2D *PhysicsDirectBodyState2DSW::get_space_state() { - return body->get_space()->get_direct_state(); } Variant PhysicsDirectBodyState2DSW::get_contact_collider_shape_metadata(int p_contact_idx) const { - ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Variant()); if (!PhysicsServer2DSW::singletonsw->body_owner.owns(body->contacts[p_contact_idx].collider)) { - return Variant(); } Body2DSW *other = PhysicsServer2DSW::singletonsw->body_owner.getornull(body->contacts[p_contact_idx].collider); int sidx = body->contacts[p_contact_idx].collider_shape; if (sidx < 0 || sidx >= other->get_shape_count()) { - return Variant(); } diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index 0514b263b4..2300c9cdee 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -38,7 +38,6 @@ class Constraint2DSW; class Body2DSW : public CollisionObject2DSW { - PhysicsServer2D::BodyMode mode; Vector2 biased_linear_velocity; @@ -87,7 +86,6 @@ class Body2DSW : public CollisionObject2DSW { Map<Constraint2DSW *, int> constraint_map; struct AreaCMP { - Area2DSW *area; int refCount; _FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); } @@ -102,7 +100,6 @@ class Body2DSW : public CollisionObject2DSW { Vector<AreaCMP> areas; struct Contact { - Vector2 local_pos; Vector2 local_normal; real_t depth; @@ -118,7 +115,6 @@ class Body2DSW : public CollisionObject2DSW { int contact_count; struct ForceIntegrationCallback { - ObjectID id; StringName method; Variant callback_udata; @@ -150,15 +146,18 @@ public: int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount -= 1; - if (areas[index].refCount < 1) + if (areas[index].refCount < 1) { areas.remove(index); + } } } _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count = 0; - if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC && p_size) set_active(true); + if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC && p_size) { + set_active(true); + } } _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); } @@ -205,7 +204,6 @@ public: } _FORCE_INLINE_ void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) { - linear_velocity += p_impulse * _inv_mass; angular_velocity += _inv_inertia * p_offset.cross(p_impulse); } @@ -215,7 +213,6 @@ public: } _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_pos, const Vector2 &p_j) { - biased_linear_velocity += p_j * _inv_mass; biased_angular_velocity += _inv_inertia * p_pos.cross(p_j); } @@ -224,8 +221,9 @@ public: _FORCE_INLINE_ bool is_active() const { return active; } _FORCE_INLINE_ void wakeup() { - if ((!get_space()) || mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) + if ((!get_space()) || mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { return; + } set_active(true); } @@ -249,7 +247,6 @@ public: } _FORCE_INLINE_ void add_force(const Vector2 &p_offset, const Vector2 &p_force) { - applied_force += p_force; applied_torque += p_offset.cross(p_force); } @@ -277,7 +274,6 @@ public: void integrate_velocities(real_t p_step); _FORCE_INLINE_ Vector2 get_motion() const { - if (mode > PhysicsServer2D::BODY_MODE_KINEMATIC) { return new_transform.get_origin() - get_transform().get_origin(); } else if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) { @@ -298,11 +294,11 @@ public: //add contact inline void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_normal, real_t p_depth, int p_local_shape, const Vector2 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector2 &p_collider_velocity_at_pos) { - int c_max = contacts.size(); - if (c_max == 0) + if (c_max == 0) { return; + } Contact *c = contacts.ptrw(); @@ -311,11 +307,9 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no if (contact_count < c_max) { idx = contact_count++; } else { - real_t least_depth = 1e20; int least_deep = -1; for (int i = 0; i < c_max; i++) { - if (i == 0 || c[i].depth < least_depth) { least_deep = i; least_depth = c[i].depth; @@ -323,11 +317,11 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no } if (least_deep >= 0 && least_depth < p_depth) { - idx = least_deep; } - if (idx == -1) + if (idx == -1) { return; //none least deepe than this + } } c[idx].local_pos = p_local_pos; @@ -342,7 +336,6 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no } class PhysicsDirectBodyState2DSW : public PhysicsDirectBodyState2D { - GDCLASS(PhysicsDirectBodyState2DSW, PhysicsDirectBodyState2D); public: diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index f38a76cff6..e483ddf1cc 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -36,14 +36,12 @@ #define ACCUMULATE_IMPULSES void BodyPair2DSW::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) { - BodyPair2DSW *self = (BodyPair2DSW *)p_self; self->_contact_added_callback(p_point_A, p_point_B); } void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) { - // check if we already have the contact Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A); @@ -69,12 +67,10 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto real_t recycle_radius_2 = space->get_contact_recycle_radius() * space->get_contact_recycle_radius(); for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; if ( c.local_A.distance_squared_to(local_A) < (recycle_radius_2) && c.local_B.distance_squared_to(local_B) < (recycle_radius_2)) { - contact.acc_normal_impulse = c.acc_normal_impulse; contact.acc_tangent_impulse = c.acc_tangent_impulse; contact.acc_bias_impulse = c.acc_bias_impulse; @@ -86,14 +82,12 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto // figure out if the contact amount must be reduced to fit the new contact if (new_index == MAX_CONTACTS) { - // remove the contact with the minimum depth int least_deep = -1; real_t min_depth = 1e10; for (int i = 0; i <= contact_count; i++) { - Contact &c = (i == contact_count) ? contact : contacts[i]; Vector2 global_A = A->get_transform().basis_xform(c.local_A); Vector2 global_B = B->get_transform().basis_xform(c.local_B) + offset_B; @@ -102,7 +96,6 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto real_t depth = axis.dot(c.normal); if (depth < min_depth) { - min_depth = depth; least_deep = i; } @@ -121,20 +114,17 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto contacts[new_index] = contact; if (new_index == contact_count) { - contact_count++; } } void BodyPair2DSW::_validate_contacts() { - //make sure to erase contacts that are no longer valid real_t max_separation = space->get_contact_max_separation(); real_t max_separation2 = max_separation * max_separation; for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; bool erase = false; @@ -169,11 +159,11 @@ void BodyPair2DSW::_validate_contacts() { } bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Transform2D &p_xform_A, Body2DSW *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) { - Vector2 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); - if (mlen < CMP_EPSILON) + if (mlen < CMP_EPSILON) { return false; + } Vector2 mnormal = motion / mlen; @@ -199,8 +189,9 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Vector2 local_to = from_inv.xform(to); Vector2 rpos, rnorm; - if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm)) + if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm)) { return false; + } //ray hit something @@ -211,10 +202,11 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const //create a contact - if (p_swap_result) + if (p_swap_result) { _contact_added_callback(contact_B, contact_A); - else + } else { _contact_added_callback(contact_A, contact_B); + } return true; } @@ -228,7 +220,6 @@ real_t combine_friction(Body2DSW *A, Body2DSW *B) { } bool BodyPair2DSW::setup(real_t p_step) { - //cannot collide if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode() <= PhysicsServer2D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer2D::BODY_MODE_KINEMATIC && A->get_max_contacts_reported() == 0 && B->get_max_contacts_reported() == 0)) { collided = false; @@ -270,17 +261,18 @@ bool BodyPair2DSW::setup(real_t p_step) { collided = CollisionSolver2DSW::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis); if (!collided) { - //test ccd (currently just a raycast) if (A->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && A->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC) { - if (_test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B)) + if (_test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B)) { collided = true; + } } if (B->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && B->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC) { - if (_test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A, true)) + if (_test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A, true)) { collided = true; + } } if (!collided) { @@ -289,22 +281,24 @@ bool BodyPair2DSW::setup(real_t p_step) { } } - if (oneway_disabled) + if (oneway_disabled) { return false; + } //if (!prev_collided) { { - if (A->is_shape_set_as_one_way_collision(shape_A)) { Vector2 direction = xform_A.get_axis(1).normalized(); bool valid = false; if (B->get_linear_velocity().dot(direction) >= 0) { for (int i = 0; i < contact_count; i++) { Contact &c = contacts[i]; - if (!c.reused) + if (!c.reused) { continue; - if (c.normal.dot(direction) > 0) //greater (normal inverted) + } + if (c.normal.dot(direction) > 0) { //greater (normal inverted) continue; + } valid = true; break; @@ -324,10 +318,12 @@ bool BodyPair2DSW::setup(real_t p_step) { if (A->get_linear_velocity().dot(direction) >= 0) { for (int i = 0; i < contact_count; i++) { Contact &c = contacts[i]; - if (!c.reused) + if (!c.reused) { continue; - if (c.normal.dot(direction) < 0) //less (normal ok) + } + if (c.normal.dot(direction) < 0) { //less (normal ok) continue; + } valid = true; break; @@ -345,13 +341,13 @@ bool BodyPair2DSW::setup(real_t p_step) { real_t bias = 0.3; if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) { - - if (shape_A_ptr->get_custom_bias() == 0) + if (shape_A_ptr->get_custom_bias() == 0) { bias = shape_B_ptr->get_custom_bias(); - else if (shape_B_ptr->get_custom_bias() == 0) + } else if (shape_B_ptr->get_custom_bias() == 0) { bias = shape_A_ptr->get_custom_bias(); - else + } else { bias = (shape_B_ptr->get_custom_bias() + shape_A_ptr->get_custom_bias()) * 0.5; + } } cc = 0; @@ -361,7 +357,6 @@ bool BodyPair2DSW::setup(real_t p_step) { bool do_process = false; for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; Vector2 global_A = xform_Au.xform(c.local_A); @@ -388,7 +383,6 @@ bool BodyPair2DSW::setup(real_t p_step) { c.rB = global_B - offset_B; if (gather_A | gather_B) { - //Vector2 crB( -B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x ); global_A += offset_A; @@ -399,7 +393,6 @@ bool BodyPair2DSW::setup(real_t p_step) { A->add_contact(global_A, -c.normal, depth, shape_A, global_B, shape_B, B->get_instance_id(), B->get_self(), crB + B->get_linear_velocity()); } if (gather_B) { - Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x); B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crA + A->get_linear_velocity()); } @@ -442,7 +435,6 @@ bool BodyPair2DSW::setup(real_t p_step) { c.bounce = combine_bounce(A, B); if (c.bounce) { - Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x); Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x); Vector2 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA; @@ -456,17 +448,17 @@ bool BodyPair2DSW::setup(real_t p_step) { } void BodyPair2DSW::solve(real_t p_step) { - - if (!collided) + if (!collided) { return; + } for (int i = 0; i < contact_count; ++i) { - Contact &c = contacts[i]; cc++; - if (!c.active) + if (!c.active) { continue; + } // Relative velocity at contact @@ -512,7 +504,6 @@ void BodyPair2DSW::solve(real_t p_step) { BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_shape_B) : Constraint2DSW(_arr, 2) { - A = p_A; B = p_B; shape_A = p_shape_A; @@ -526,7 +517,6 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_sh } BodyPair2DSW::~BodyPair2DSW() { - A->remove_constraint(this); B->remove_constraint(this); } diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h index e46ecbc8eb..ea4d55841a 100644 --- a/servers/physics_2d/body_pair_2d_sw.h +++ b/servers/physics_2d/body_pair_2d_sw.h @@ -35,7 +35,6 @@ #include "constraint_2d_sw.h" class BodyPair2DSW : public Constraint2DSW { - enum { MAX_CONTACTS = 2 }; @@ -54,7 +53,6 @@ class BodyPair2DSW : public Constraint2DSW { Space2DSW *space; struct Contact { - Vector2 position; Vector2 normal; Vector2 local_A, local_B; diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp index 5e3a13f4dd..3bdfc1a973 100644 --- a/servers/physics_2d/broad_phase_2d_basic.cpp +++ b/servers/physics_2d/broad_phase_2d_basic.cpp @@ -31,7 +31,6 @@ #include "broad_phase_2d_basic.h" BroadPhase2DBasic::ID BroadPhase2DBasic::create(CollisionObject2DSW *p_object_, int p_subindex) { - current++; Element e; @@ -44,76 +43,71 @@ BroadPhase2DBasic::ID BroadPhase2DBasic::create(CollisionObject2DSW *p_object_, } void BroadPhase2DBasic::move(ID p_id, const Rect2 &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); E->get().aabb = p_aabb; } -void BroadPhase2DBasic::set_static(ID p_id, bool p_static) { +void BroadPhase2DBasic::set_static(ID p_id, bool p_static) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); E->get()._static = p_static; } -void BroadPhase2DBasic::remove(ID p_id) { +void BroadPhase2DBasic::remove(ID p_id) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); element_map.erase(E); } CollisionObject2DSW *BroadPhase2DBasic::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } -bool BroadPhase2DBasic::is_static(ID p_id) const { +bool BroadPhase2DBasic::is_static(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, false); return E->get()._static; } -int BroadPhase2DBasic::get_subindex(ID p_id) const { +int BroadPhase2DBasic::get_subindex(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, -1); return E->get().subindex; } int BroadPhase2DBasic::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect2 aabb = E->get().aabb; if (aabb.intersects_segment(p_from, p_to)) { - p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; - if (rc >= p_max_results) + if (rc >= p_max_results) { break; + } } } return rc; } -int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect2 aabb = E->get().aabb; if (aabb.intersects(p_aabb)) { - p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; - if (rc >= p_max_results) + if (rc >= p_max_results) { break; + } } } @@ -121,28 +115,25 @@ int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_re } void BroadPhase2DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_userdata = p_userdata; pair_callback = p_pair_callback; } -void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_userdata = p_userdata; unpair_callback = p_unpair_callback; } void BroadPhase2DBasic::update() { - // recompute pairs for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) { - for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) { - Element *elem_A = &I->get(); Element *elem_B = &J->get(); - if (elem_A->owner == elem_B->owner) + if (elem_A->owner == elem_B->owner) { continue; + } bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static); @@ -151,29 +142,30 @@ void BroadPhase2DBasic::update() { Map<PairKey, void *>::Element *E = pair_map.find(key); if (!pair_ok && E) { - if (unpair_callback) + if (unpair_callback) { unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata); + } pair_map.erase(key); } if (pair_ok && !E) { - void *data = nullptr; - if (pair_callback) + if (pair_callback) { data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); - pair_map.insert(key, data); + if (data) { + pair_map.insert(key, data); + } + } } } } } BroadPhase2DSW *BroadPhase2DBasic::_create() { - return memnew(BroadPhase2DBasic); } BroadPhase2DBasic::BroadPhase2DBasic() { - current = 1; unpair_callback = nullptr; unpair_userdata = nullptr; diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h index 7d02590af9..ec5cfdbf1d 100644 --- a/servers/physics_2d/broad_phase_2d_basic.h +++ b/servers/physics_2d/broad_phase_2d_basic.h @@ -34,9 +34,7 @@ #include "core/map.h" #include "space_2d_sw.h" class BroadPhase2DBasic : public BroadPhase2DSW { - struct Element { - CollisionObject2DSW *owner; bool _static; Rect2 aabb; @@ -48,7 +46,6 @@ class BroadPhase2DBasic : public BroadPhase2DSW { ID current; struct PairKey { - union { struct { ID a; diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp index 2cb021258a..ae549ed2e4 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp +++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp @@ -34,13 +34,11 @@ #define LARGE_ELEMENT_FI 1.01239812 void BroadPhase2DHashGrid::_pair_attempt(Element *p_elem, Element *p_with) { - Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with); ERR_FAIL_COND(p_elem->_static && p_with->_static); if (!E) { - PairData *pd = memnew(PairData); p_elem->paired[p_with] = pd; p_with->paired[p_elem] = pd; @@ -50,7 +48,6 @@ void BroadPhase2DHashGrid::_pair_attempt(Element *p_elem, Element *p_with) { } void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) { - Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with); ERR_FAIL_COND(!E); //this should really be paired.. @@ -58,7 +55,6 @@ void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) { E->get()->rc--; if (E->get()->rc == 0) { - if (E->get()->colliding) { //uncollide if (unpair_callback) { @@ -73,20 +69,15 @@ void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) { } void BroadPhase2DHashGrid::_check_motion(Element *p_elem) { - for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) { - bool pairing = p_elem->aabb.intersects(E->key()->aabb); if (pairing != E->get()->colliding) { - if (pairing) { - if (pair_callback) { E->get()->ud = pair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, pair_userdata); } } else { - if (unpair_callback) { unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata); } @@ -98,17 +89,19 @@ void BroadPhase2DHashGrid::_check_motion(Element *p_elem) { } void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, bool p_static) { - Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI); //use magic number to avoid floating point issues if (sz.width * sz.height > large_object_min_surface) { //large object, do not use grid, must check against all elements for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - if (E->key() == p_elem->self) + if (E->key() == p_elem->self) { continue; // do not pair against itself - if (E->get().owner == p_elem->owner) + } + if (E->get().owner == p_elem->owner) { continue; - if (E->get()._static && p_static) + } + if (E->get()._static && p_static) { continue; + } _pair_attempt(p_elem, &E->get()); } @@ -121,9 +114,7 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor(); for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - PosKey pk; pk.x = i; pk.y = j; @@ -132,7 +123,6 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo PosBin *pb = hash_table[idx]; while (pb) { - if (pb->key == pk) { break; } @@ -156,26 +146,23 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo } } else { if (pb->object_set[p_elem].inc() == 1) { - entered = true; } } if (entered) { - for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - - if (E->key()->owner == p_elem->owner) + if (E->key()->owner == p_elem->owner) { continue; + } _pair_attempt(p_elem, E->key()); } if (!p_static) { - for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - - if (E->key()->owner == p_elem->owner) + if (E->key()->owner == p_elem->owner) { continue; + } _pair_attempt(p_elem, E->key()); } } @@ -186,23 +173,23 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo //pair separatedly with large elements for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - - if (E->key() == p_elem) + if (E->key() == p_elem) { continue; // do not pair against itself - if (E->key()->owner == p_elem->owner) + } + if (E->key()->owner == p_elem->owner) { continue; - if (E->key()->_static && p_static) + } + if (E->key()->_static && p_static) { continue; + } _pair_attempt(E->key(), p_elem); } } void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool p_static) { - Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI); if (sz.width * sz.height > large_object_min_surface) { - //unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static Map<Element *, PairData *>::Element *E = p_elem->paired.front(); while (E) { @@ -221,9 +208,7 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor(); for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - PosKey pk; pk.x = i; pk.y = j; @@ -232,7 +217,6 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool PosBin *pb = hash_table[idx]; while (pb) { - if (pb->key == pk) { break; } @@ -246,48 +230,41 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool if (p_static) { if (pb->static_object_set[p_elem].dec() == 0) { - pb->static_object_set.erase(p_elem); exited = true; } } else { if (pb->object_set[p_elem].dec() == 0) { - pb->object_set.erase(p_elem); exited = true; } } if (exited) { - for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - - if (E->key()->owner == p_elem->owner) + if (E->key()->owner == p_elem->owner) { continue; + } _unpair_attempt(p_elem, E->key()); } if (!p_static) { - for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - - if (E->key()->owner == p_elem->owner) + if (E->key()->owner == p_elem->owner) { continue; + } _unpair_attempt(p_elem, E->key()); } } } if (pb->object_set.empty() && pb->static_object_set.empty()) { - if (hash_table[idx] == pb) { hash_table[idx] = pb->next; } else { - PosBin *px = hash_table[idx]; while (px) { - if (px->next == pb) { px->next = pb->next; break; @@ -305,12 +282,15 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool } for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - if (E->key() == p_elem) + if (E->key() == p_elem) { continue; // do not pair against itself - if (E->key()->owner == p_elem->owner) + } + if (E->key()->owner == p_elem->owner) { continue; - if (E->key()->_static && p_static) + } + if (E->key()->_static && p_static) { continue; + } //unpair from large elements _unpair_attempt(p_elem, E->key()); @@ -318,7 +298,6 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool } BroadPhase2DHashGrid::ID BroadPhase2DHashGrid::create(CollisionObject2DSW *p_object, int p_subindex) { - current++; Element e; @@ -333,22 +312,20 @@ BroadPhase2DHashGrid::ID BroadPhase2DHashGrid::create(CollisionObject2DSW *p_obj } void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); Element &e = E->get(); - if (p_aabb == e.aabb) + if (p_aabb == e.aabb) { return; + } if (p_aabb != Rect2()) { - _enter_grid(&e, p_aabb, e._static); } if (e.aabb != Rect2()) { - _exit_grid(&e, e.aabb, e._static); } @@ -358,18 +335,20 @@ void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) { e.aabb = p_aabb; } -void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) { +void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); Element &e = E->get(); - if (e._static == p_static) + if (e._static == p_static) { return; + } - if (e.aabb != Rect2()) + if (e.aabb != Rect2()) { _exit_grid(&e, e.aabb, e._static); + } e._static = p_static; @@ -378,33 +357,33 @@ void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) { _check_motion(&e); } } -void BroadPhase2DHashGrid::remove(ID p_id) { +void BroadPhase2DHashGrid::remove(ID p_id) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); Element &e = E->get(); - if (e.aabb != Rect2()) + if (e.aabb != Rect2()) { _exit_grid(&e, e.aabb, e._static); + } element_map.erase(p_id); } CollisionObject2DSW *BroadPhase2DHashGrid::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } -bool BroadPhase2DHashGrid::is_static(ID p_id) const { +bool BroadPhase2DHashGrid::is_static(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, false); return E->get()._static; } -int BroadPhase2DHashGrid::get_subindex(ID p_id) const { +int BroadPhase2DHashGrid::get_subindex(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, -1); return E->get().subindex; @@ -412,7 +391,6 @@ int BroadPhase2DHashGrid::get_subindex(ID p_id) const { template <bool use_aabb, bool use_segment> void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index) { - PosKey pk; pk.x = p_cell.x; pk.y = p_cell.y; @@ -421,7 +399,6 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons PosBin *pb = hash_table[idx]; while (pb) { - if (pb->key == pk) { break; } @@ -429,23 +406,27 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons pb = pb->next; } - if (!pb) + if (!pb) { return; + } for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) { - - if (index >= p_max_results) + if (index >= p_max_results) { break; - if (E->key()->pass == pass) + } + if (E->key()->pass == pass) { continue; + } E->key()->pass = pass; - if (use_aabb && !p_aabb.intersects(E->key()->aabb)) + if (use_aabb && !p_aabb.intersects(E->key()->aabb)) { continue; + } - if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) + if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) { continue; + } p_results[index] = E->key()->owner; p_result_indices[index] = E->key()->subindex; @@ -453,18 +434,20 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons } for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) { - - if (index >= p_max_results) + if (index >= p_max_results) { break; - if (E->key()->pass == pass) + } + if (E->key()->pass == pass) { continue; + } if (use_aabb && !p_aabb.intersects(E->key()->aabb)) { continue; } - if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) + if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) { continue; + } E->key()->pass = pass; p_results[index] = E->key()->owner; @@ -474,18 +457,20 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons } int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - pass++; Vector2 dir = (p_to - p_from); - if (dir == Vector2()) + if (dir == Vector2()) { return 0; + } //avoid divisions by zero dir.normalize(); - if (dir.x == 0.0) + if (dir.x == 0.0) { dir.x = 0.000001; - if (dir.y == 0.0) + } + if (dir.y == 0.0) { dir.y = 0.000001; + } Vector2 delta = dir.abs(); delta.x = cell_size / delta.x; @@ -498,15 +483,17 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t Vector2 max; - if (dir.x < 0) + if (dir.x < 0) { max.x = (Math::floor((double)pos.x) * cell_size - p_from.x) / dir.x; - else + } else { max.x = (Math::floor((double)pos.x + 1) * cell_size - p_from.x) / dir.x; + } - if (dir.y < 0) + if (dir.y < 0) { max.y = (Math::floor((double)pos.y) * cell_size - p_from.y) / dir.y; - else + } else { max.y = (Math::floor((double)pos.y + 1) * cell_size - p_from.y) / dir.y; + } int cullcount = 0; _cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount); @@ -515,45 +502,44 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t bool reached_y = false; while (true) { - if (max.x < max.y) { - max.x += delta.x; pos.x += step.x; } else { - max.y += delta.y; pos.y += step.y; } if (step.x > 0) { - if (pos.x >= end.x) + if (pos.x >= end.x) { reached_x = true; + } } else if (pos.x <= end.x) { - reached_x = true; } if (step.y > 0) { - if (pos.y >= end.y) + if (pos.y >= end.y) { reached_y = true; + } } else if (pos.y <= end.y) { - reached_y = true; } _cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount); - if (reached_x && reached_y) + if (reached_x && reached_y) { break; + } } for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - - if (cullcount >= p_max_results) + if (cullcount >= p_max_results) { break; - if (E->key()->pass == pass) + } + if (E->key()->pass == pass) { continue; + } E->key()->pass = pass; @@ -562,8 +548,9 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t continue; */ - if (!E->key()->aabb.intersects_segment(p_from, p_to)) + if (!E->key()->aabb.intersects_segment(p_from, p_to)) { continue; + } p_results[cullcount] = E->key()->owner; p_result_indices[cullcount] = E->key()->subindex; @@ -574,7 +561,6 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t } int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) { - pass++; Point2i from = (p_aabb.position / cell_size).floor(); @@ -582,24 +568,24 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p int cullcount = 0; for (int i = from.x; i <= to.x; i++) { - for (int j = from.y; j <= to.y; j++) { - _cull<true, false>(Point2i(i, j), p_aabb, Point2(), Point2(), p_results, p_max_results, p_result_indices, cullcount); } } for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) { - - if (cullcount >= p_max_results) + if (cullcount >= p_max_results) { break; - if (E->key()->pass == pass) + } + if (E->key()->pass == pass) { continue; + } E->key()->pass = pass; - if (!p_aabb.intersects(E->key()->aabb)) + if (!p_aabb.intersects(E->key()->aabb)) { continue; + } /* if (!E->key()->aabb.intersects_segment(p_from,p_to)) @@ -614,12 +600,11 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p } void BroadPhase2DHashGrid::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_callback = p_pair_callback; pair_userdata = p_userdata; } -void BroadPhase2DHashGrid::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void BroadPhase2DHashGrid::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_callback = p_unpair_callback; unpair_userdata = p_userdata; } @@ -628,12 +613,10 @@ void BroadPhase2DHashGrid::update() { } BroadPhase2DSW *BroadPhase2DHashGrid::_create() { - return memnew(BroadPhase2DHashGrid); } 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); @@ -645,15 +628,15 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() { 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++) + for (uint32_t i = 0; i < hash_table_size; i++) { hash_table[i] = nullptr; + } pass = 1; current = 0; } BroadPhase2DHashGrid::~BroadPhase2DHashGrid() { - for (uint32_t i = 0; i < hash_table_size; i++) { while (hash_table[i]) { PosBin *pb = hash_table[i]; diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h index dc29d0c619..de1ada0932 100644 --- a/servers/physics_2d/broad_phase_2d_hash_grid.h +++ b/servers/physics_2d/broad_phase_2d_hash_grid.h @@ -35,9 +35,7 @@ #include "core/map.h" class BroadPhase2DHashGrid : public BroadPhase2DSW { - struct PairData { - bool colliding; int rc; void *ud; @@ -49,7 +47,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { }; struct Element { - ID self; CollisionObject2DSW *owner; bool _static; @@ -60,7 +57,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { }; struct RC { - int ref; _FORCE_INLINE_ int inc() { @@ -85,7 +81,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { uint64_t pass; struct PairKey { - union { struct { ID a; @@ -126,7 +121,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { _FORCE_INLINE_ void _cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index); struct PosKey { - union { struct { int32_t x; @@ -153,7 +147,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW { }; struct PosBin { - PosKey key; Map<Element *, RC> object_set; Map<Element *, RC> static_object_set; diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h index 5e42c72d83..e4444cd180 100644 --- a/servers/physics_2d/broad_phase_2d_sw.h +++ b/servers/physics_2d/broad_phase_2d_sw.h @@ -37,7 +37,6 @@ class CollisionObject2DSW; class BroadPhase2DSW { - public: typedef BroadPhase2DSW *(*CreateFunction)(); diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 0ec293c042..6931d96fe4 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -33,7 +33,6 @@ #include "space_2d_sw.h" void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform, bool p_disabled) { - Shape s; s.shape = p_shape; s.xform = p_transform; @@ -53,7 +52,6 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra } void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { - ERR_FAIL_INDEX(p_index, shapes.size()); shapes[p_index].shape->remove_owner(this); shapes.write[p_index].shape = p_shape; @@ -68,13 +66,11 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { } void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) { - ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].metadata = p_metadata; } void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) { - ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].xform = p_transform; @@ -91,13 +87,15 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) { ERR_FAIL_INDEX(p_idx, shapes.size()); CollisionObject2DSW::Shape &shape = shapes.write[p_idx]; - if (shape.disabled == p_disabled) + if (shape.disabled == p_disabled) { return; + } shape.disabled = p_disabled; - if (!space) + if (!space) { return; + } if (p_disabled && shape.bpid != 0) { space->get_broadphase()->remove(shape.bpid); @@ -115,10 +113,8 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) { } void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) { - //remove a shape, all the times it appears for (int i = 0; i < shapes.size(); i++) { - if (shapes[i].shape == p_shape) { remove_shape(i); i--; @@ -127,13 +123,12 @@ void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) { } void CollisionObject2DSW::remove_shape(int p_index) { - //remove anything from shape to be erased to end, so subindices don't change ERR_FAIL_INDEX(p_index, shapes.size()); for (int i = p_index; i < shapes.size(); i++) { - - if (shapes[i].bpid == 0) + if (shapes[i].bpid == 0) { continue; + } //should never get here with a null owner space->get_broadphase()->remove(shapes[i].bpid); shapes.write[i].bpid = 0; @@ -149,12 +144,14 @@ void CollisionObject2DSW::remove_shape(int p_index) { } void CollisionObject2DSW::_set_static(bool p_static) { - if (_static == p_static) + if (_static == p_static) { return; + } _static = p_static; - if (!space) + if (!space) { return; + } for (int i = 0; i < get_shape_count(); i++) { const Shape &s = shapes[i]; if (s.bpid > 0) { @@ -164,9 +161,7 @@ void CollisionObject2DSW::_set_static(bool p_static) { } void CollisionObject2DSW::_unregister_shapes() { - for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid > 0) { space->get_broadphase()->remove(s.bpid); @@ -176,16 +171,16 @@ void CollisionObject2DSW::_unregister_shapes() { } void CollisionObject2DSW::_update_shapes() { - - if (!space) + if (!space) { return; + } for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; - if (s.disabled) + if (s.disabled) { continue; + } if (s.bpid == 0) { s.bpid = space->get_broadphase()->create(this, i); @@ -204,15 +199,15 @@ void CollisionObject2DSW::_update_shapes() { } void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { - - if (!space) + if (!space) { return; + } for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; - if (s.disabled) + if (s.disabled) { continue; + } if (s.bpid == 0) { s.bpid = space->get_broadphase()->create(this, i); @@ -231,13 +226,10 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { } void CollisionObject2DSW::_set_space(Space2DSW *p_space) { - if (space) { - space->remove_object(this); for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid) { space->get_broadphase()->remove(s.bpid); @@ -249,21 +241,18 @@ void CollisionObject2DSW::_set_space(Space2DSW *p_space) { space = p_space; if (space) { - space->add_object(this); _update_shapes(); } } void CollisionObject2DSW::_shape_changed() { - _update_shapes(); _shapes_changed(); } CollisionObject2DSW::CollisionObject2DSW(Type p_type) : pending_shape_update_list(this) { - _static = true; type = p_type; space = nullptr; diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 98105a7c0e..84a2baaa74 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -53,7 +53,6 @@ private: bool pickable; struct Shape { - Transform2D xform; Transform2D xform_inv; BroadPhase2DSW::ID bpid; @@ -186,7 +185,6 @@ public: _FORCE_INLINE_ bool is_pickable() const { return pickable; } _FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW *p_other) const { - return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp index a954cb3de3..d993754fee 100644 --- a/servers/physics_2d/collision_solver_2d_sat.cpp +++ b/servers/physics_2d/collision_solver_2d_sat.cpp @@ -30,10 +30,9 @@ #include "collision_solver_2d_sat.h" -#include "core/math/geometry.h" +#include "core/math/geometry_2d.h" struct _CollectorCallback2D { - CollisionSolver2DSW::CallbackResult callback; void *userdata; bool swap; @@ -42,22 +41,21 @@ struct _CollectorCallback2D { Vector2 *sep_axis; _FORCE_INLINE_ void call(const Vector2 &p_point_A, const Vector2 &p_point_B) { - /* if (normal.dot(p_point_A) >= normal.dot(p_point_B)) return; */ - if (swap) + if (swap) { callback(p_point_B, p_point_A, userdata); - else + } else { callback(p_point_A, p_point_B, userdata); + } } }; typedef void (*GenerateContactsFunc)(const Vector2 *, int, const Vector2 *, int, _CollectorCallback2D *); _FORCE_INLINE_ static void _generate_contacts_point_point(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 1); ERR_FAIL_COND(p_point_count_B != 1); @@ -67,13 +65,12 @@ _FORCE_INLINE_ static void _generate_contacts_point_point(const Vector2 *p_point } _FORCE_INLINE_ static void _generate_contacts_point_edge(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 1); ERR_FAIL_COND(p_point_count_B != 2); #endif - Vector2 closest_B = Geometry::get_closest_point_to_segment_uncapped_2d(*p_points_A, p_points_B); + Vector2 closest_B = Geometry2D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B); p_collector->call(*p_points_A, closest_B); } @@ -85,7 +82,6 @@ struct _generate_contacts_Pair { }; _FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 2); ERR_FAIL_COND(p_point_count_B != 2); // circle is actually a 4x3 matrix @@ -115,25 +111,25 @@ _FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 *p_points_ sa.sort(dvec, 4); for (int i = 1; i <= 2; i++) { - if (dvec[i].a) { Vector2 a = p_points_A[dvec[i].idx]; Vector2 b = n.plane_project(dB, a); - if (n.dot(a) > n.dot(b) - CMP_EPSILON) + if (n.dot(a) > n.dot(b) - CMP_EPSILON) { continue; + } p_collector->call(a, b); } else { Vector2 b = p_points_B[dvec[i].idx]; Vector2 a = n.plane_project(dA, b); - if (n.dot(a) > n.dot(b) - CMP_EPSILON) + if (n.dot(a) > n.dot(b) - CMP_EPSILON) { continue; + } p_collector->call(a, b); } } } static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 1); ERR_FAIL_COND(p_point_count_B < 1); @@ -165,7 +161,6 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po points_A = p_points_B; points_B = p_points_A; } else { - pointcount_B = p_point_count_B; pointcount_A = p_point_count_A; points_A = p_points_A; @@ -182,7 +177,6 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po template <class ShapeA, class ShapeB, bool castA = false, bool castB = false, bool withMargin = false> class SeparatorAxisTest2D { - const ShapeA *shape_A; const ShapeB *shape_B; const Transform2D *transform_A; @@ -199,7 +193,6 @@ class SeparatorAxisTest2D { public: _FORCE_INLINE_ bool test_previous_axis() { - if (callback && callback->sep_axis && *callback->sep_axis != Vector2()) { return test_axis(*callback->sep_axis); } else { @@ -211,30 +204,30 @@ public: } _FORCE_INLINE_ bool test_cast() { - if (castA) { - Vector2 na = motion_A.normalized(); - if (!test_axis(na)) + if (!test_axis(na)) { return false; - if (!test_axis(na.tangent())) + } + if (!test_axis(na.tangent())) { return false; + } } if (castB) { - Vector2 nb = motion_B.normalized(); - if (!test_axis(nb)) + if (!test_axis(nb)) { return false; - if (!test_axis(nb.tangent())) + } + if (!test_axis(nb.tangent())) { return false; + } } return true; } _FORCE_INLINE_ bool test_axis(const Vector2 &p_axis) { - Vector2 axis = p_axis; if (Math::is_zero_approx(axis.x) && @@ -245,15 +238,17 @@ public: real_t min_A, max_A, min_B, max_B; - if (castA) + if (castA) { shape_A->project_range_cast(motion_A, axis, *transform_A, min_A, max_A); - else + } else { shape_A->project_range(axis, *transform_A, min_A, max_A); + } - if (castB) + if (castB) { shape_B->project_range_cast(motion_B, axis, *transform_B, min_B, max_B); - else + } else { shape_B->project_range(axis, *transform_B, min_B, max_B); + } if (withMargin) { min_A -= margin_A; @@ -269,8 +264,9 @@ public: real_t dmax = max_B - (min_A + max_A) * 0.5; if (dmin > 0.0 || dmax < 0.0) { - if (callback && callback->sep_axis) + if (callback && callback->sep_axis) { *callback->sep_axis = axis; + } #ifdef DEBUG_ENABLED best_axis_count++; #endif @@ -308,16 +304,17 @@ public: } _FORCE_INLINE_ void generate_contacts() { - // nothing to do, don't generate - if (best_axis == Vector2(0.0, 0.0)) + if (best_axis == Vector2(0.0, 0.0)) { return; + } if (callback) { callback->collided = true; - if (!callback->callback) + if (!callback->callback) { return; //only collide, no callback + } } static const int max_supports = 2; @@ -333,7 +330,6 @@ public: } if (withMargin) { - for (int i = 0; i < support_count_A; i++) { supports_A[i] += -best_axis * margin_A; } @@ -351,7 +347,6 @@ public: } if (withMargin) { - for (int i = 0; i < support_count_B; i++) { supports_B[i] += best_axis * margin_B; } @@ -360,13 +355,13 @@ public: callback->normal = best_axis; _generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback); - if (callback->sep_axis && *callback->sep_axis != Vector2()) + if (callback->sep_axis && *callback->sep_axis != Vector2()) { *callback->sep_axis = Vector2(); //invalidate previous axis (no test) + } } } _FORCE_INLINE_ SeparatorAxisTest2D(const ShapeA *p_shape_A, const Transform2D &p_transform_a, const ShapeB *p_shape_B, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_A = Vector2(), const Vector2 &p_motion_B = Vector2(), real_t p_margin_A = 0, real_t p_margin_B = 0) { - margin_A = p_margin_A; margin_B = p_margin_B; best_depth = 1e15; @@ -397,35 +392,42 @@ typedef void (*CollisionFunc)(const Shape2DSW *, const Transform2D &, const Shap template <bool castA, bool castB, bool withMargin> static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); const SegmentShape2DSW *segment_B = static_cast<const SegmentShape2DSW *>(p_b); SeparatorAxisTest2D<SegmentShape2DSW, SegmentShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, segment_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } //this collision is kind of pointless - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } - if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) + if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) { return; - if (!separator.test_axis(segment_B->get_xformed_normal(p_transform_b))) + } + if (!separator.test_axis(segment_B->get_xformed_normal(p_transform_b))) { return; + } if (withMargin) { //points grow to circles - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_a()))) + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_a()))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_b()))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_b()))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_a()))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_a()))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_b()))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_b()))) { return; + } } separator.generate_contacts(); @@ -433,90 +435,102 @@ static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D & template <bool castA, bool castB, bool withMargin> static void _collision_segment_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b); SeparatorAxisTest2D<SegmentShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //segment normal if (!separator.test_axis( - (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().tangent())) + (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().tangent())) { return; + } //endpoint a vs circle - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.get_origin())) + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.get_origin())) { return; + } //endpoint b vs circle - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.get_origin())) + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.get_origin())) { return; + } separator.generate_contacts(); } template <bool castA, bool castB, bool withMargin> static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); SeparatorAxisTest2D<SegmentShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } - if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) + if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) { return; + } - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_b.elements[1].normalized())) + if (!separator.test_axis(p_transform_b.elements[1].normalized())) { return; + } if (withMargin) { - Transform2D inv = p_transform_b.affine_inverse(); Vector2 a = p_transform_a.xform(segment_A->get_a()); Vector2 b = p_transform_a.xform(segment_A->get_b()); - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a))) { return; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b))) + } + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b))) { return; + } if (castA) { - - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a + p_motion_a))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a + p_motion_a))) { return; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b + p_motion_a))) + } + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b + p_motion_a))) { return; + } } if (castB) { - - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b))) { return; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b))) + } + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b))) { return; + } } if (castA && castB) { - - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b + p_motion_a))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b + p_motion_a))) { return; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b + p_motion_a))) + } + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b + p_motion_a))) { return; + } } } @@ -525,64 +539,74 @@ static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D template <bool castA, bool castB, bool withMargin> static void _collision_segment_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); SeparatorAxisTest2D<SegmentShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } - if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) + if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) { return; + } - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) { return; + } separator.generate_contacts(); } template <bool castA, bool castB, bool withMargin> static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a); const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); SeparatorAxisTest2D<SegmentShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } - if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) + if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) { return; + } for (int i = 0; i < convex_B->get_point_count(); i++) { - - if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) + if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) { return; + } if (withMargin) { - - if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(convex_B->get_point(i)))) + if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(convex_B->get_point(i)))) { return; - if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(convex_B->get_point(i)))) + } + if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(convex_B->get_point(i)))) { return; + } } } @@ -593,74 +617,79 @@ static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transf template <bool castA, bool castB, bool withMargin> static void _collision_circle_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b); SeparatorAxisTest2D<CircleShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } - if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.get_origin())) + if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.get_origin())) { return; + } separator.generate_contacts(); } template <bool castA, bool castB, bool withMargin> static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); SeparatorAxisTest2D<CircleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } const Vector2 &sphere = p_transform_a.elements[2]; const Vector2 *axis = &p_transform_b.elements[0]; //const Vector2& half_extents = rectangle_B->get_half_extents(); - if (!separator.test_axis(axis[0].normalized())) + if (!separator.test_axis(axis[0].normalized())) { return; + } - if (!separator.test_axis(axis[1].normalized())) + if (!separator.test_axis(axis[1].normalized())) { return; + } Transform2D binv = p_transform_b.affine_inverse(); { - - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphere))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphere))) { return; + } } if (castA) { - Vector2 sphereofs = sphere + p_motion_a; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) { return; + } } if (castB) { - Vector2 sphereofs = sphere - p_motion_b; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) { return; + } } if (castA && castB) { - Vector2 sphereofs = sphere - p_motion_b + p_motion_a; - if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) + if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) { return; + } } separator.generate_contacts(); @@ -668,53 +697,59 @@ static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D template <bool castA, bool castB, bool withMargin> static void _collision_circle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); SeparatorAxisTest2D<CircleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //capsule axis - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } //capsule endpoints - if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) + if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) { return; - if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) + } + if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) { return; + } separator.generate_contacts(); } template <bool castA, bool castB, bool withMargin> static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a); const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); SeparatorAxisTest2D<CircleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //poly faces and poly points vs circle for (int i = 0; i < convex_B->get_point_count(); i++) { - - if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.xform(convex_B->get_point(i)))) + if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.xform(convex_B->get_point(i)))) { return; + } - if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) + if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) { return; + } } separator.generate_contacts(); @@ -724,42 +759,46 @@ static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transfo template <bool castA, bool castB, bool withMargin> static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b); SeparatorAxisTest2D<RectangleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //box faces A - if (!separator.test_axis(p_transform_a.elements[0].normalized())) + if (!separator.test_axis(p_transform_a.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_a.elements[1].normalized())) + if (!separator.test_axis(p_transform_a.elements[1].normalized())) { return; + } //box faces B - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_b.elements[1].normalized())) + if (!separator.test_axis(p_transform_b.elements[1].normalized())) { return; + } if (withMargin) { - Transform2D invA = p_transform_a.affine_inverse(); Transform2D invB = p_transform_b.affine_inverse(); - if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, p_transform_b, invB))) + if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, p_transform_b, invB))) { return; + } if (castA || castB) { - Transform2D aofs = p_transform_a; aofs.elements[2] += p_motion_a; @@ -770,21 +809,21 @@ static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform Transform2D bofsinv = bofs.affine_inverse(); if (castA) { - - if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, p_transform_b, invB))) + if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, p_transform_b, invB))) { return; + } } if (castB) { - - if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, bofs, bofsinv))) + if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, bofs, bofsinv))) { return; + } } if (castA && castB) { - - if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, bofs, bofsinv))) + if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, bofs, bofsinv))) { return; + } } } } @@ -794,56 +833,62 @@ static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform template <bool castA, bool castB, bool withMargin> static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); SeparatorAxisTest2D<RectangleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //box faces - if (!separator.test_axis(p_transform_a.elements[0].normalized())) + if (!separator.test_axis(p_transform_a.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_a.elements[1].normalized())) + if (!separator.test_axis(p_transform_a.elements[1].normalized())) { return; + } //capsule axis - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } //box endpoints to capsule circles Transform2D boxinv = p_transform_a.affine_inverse(); for (int i = 0; i < 2; i++) { - { Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5); - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) { return; + } } if (castA) { Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5); capsule_endpoint -= p_motion_a; - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) { return; + } } if (castB) { Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5); capsule_endpoint += p_motion_b; - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) { return; + } } if (castA && castB) { @@ -851,8 +896,9 @@ static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D capsule_endpoint -= p_motion_a; capsule_endpoint += p_motion_b; - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) { return; + } } } @@ -861,24 +907,27 @@ static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D template <bool castA, bool castB, bool withMargin> static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a); const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); SeparatorAxisTest2D<RectangleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //box faces - if (!separator.test_axis(p_transform_a.elements[0].normalized())) + if (!separator.test_axis(p_transform_a.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_a.elements[1].normalized())) + if (!separator.test_axis(p_transform_a.elements[1].normalized())) { return; + } //convex faces Transform2D boxinv; @@ -886,28 +935,29 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Tran boxinv = p_transform_a.affine_inverse(); } for (int i = 0; i < convex_B->get_point_count(); i++) { - - if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) + if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) { return; + } if (withMargin) { //all points vs all points need to be tested if margin exist - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i))))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i))))) { return; + } if (castA) { - - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) - p_motion_a))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) - p_motion_a))) { return; + } } if (castB) { - - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b))) { return; + } } if (castA && castB) { - - if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b - p_motion_a))) + if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b - p_motion_a))) { return; + } } } } @@ -919,38 +969,40 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Tran template <bool castA, bool castB, bool withMargin> static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a); const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b); SeparatorAxisTest2D<CapsuleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //capsule axis - if (!separator.test_axis(p_transform_b.elements[0].normalized())) + if (!separator.test_axis(p_transform_b.elements[0].normalized())) { return; + } - if (!separator.test_axis(p_transform_a.elements[0].normalized())) + if (!separator.test_axis(p_transform_a.elements[0].normalized())) { return; + } //capsule endpoints for (int i = 0; i < 2; i++) { - Vector2 capsule_endpoint_A = p_transform_a.get_origin() + p_transform_a.elements[1] * capsule_A->get_height() * (i == 0 ? 0.5 : -0.5); for (int j = 0; j < 2; j++) { - Vector2 capsule_endpoint_B = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (j == 0 ? 0.5 : -0.5); - if (TEST_POINT(capsule_endpoint_A, capsule_endpoint_B)) + if (TEST_POINT(capsule_endpoint_A, capsule_endpoint_B)) { return; + } } } @@ -959,38 +1011,40 @@ static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D & template <bool castA, bool castB, bool withMargin> static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a); const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); SeparatorAxisTest2D<CapsuleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } //capsule axis - if (!separator.test_axis(p_transform_a.elements[0].normalized())) + if (!separator.test_axis(p_transform_a.elements[0].normalized())) { return; + } //poly vs capsule for (int i = 0; i < convex_B->get_point_count(); i++) { - Vector2 cpoint = p_transform_b.xform(convex_B->get_point(i)); for (int j = 0; j < 2; j++) { - Vector2 capsule_endpoint_A = p_transform_a.get_origin() + p_transform_a.elements[1] * capsule_A->get_height() * (j == 0 ? 0.5 : -0.5); - if (TEST_POINT(capsule_endpoint_A, cpoint)) + if (TEST_POINT(capsule_endpoint_A, cpoint)) { return; + } } - if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) + if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) { return; + } } separator.generate_contacts(); @@ -1000,37 +1054,37 @@ static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transf template <bool castA, bool castB, bool withMargin> static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) { - const ConvexPolygonShape2DSW *convex_A = static_cast<const ConvexPolygonShape2DSW *>(p_a); const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b); SeparatorAxisTest2D<ConvexPolygonShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(convex_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_cast()) + if (!separator.test_cast()) { return; + } for (int i = 0; i < convex_A->get_point_count(); i++) { - - if (!separator.test_axis(convex_A->get_xformed_segment_normal(p_transform_a, i))) + if (!separator.test_axis(convex_A->get_xformed_segment_normal(p_transform_a, i))) { return; + } } for (int i = 0; i < convex_B->get_point_count(); i++) { - - if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) + if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) { return; + } } if (withMargin) { - for (int i = 0; i < convex_A->get_point_count(); i++) { for (int j = 0; j < convex_B->get_point_count(); j++) { - - if (TEST_POINT(p_transform_a.xform(convex_A->get_point(i)), p_transform_b.xform(convex_B->get_point(j)))) + if (TEST_POINT(p_transform_a.xform(convex_A->get_point(i)), p_transform_b.xform(convex_B->get_point(j)))) { return; + } } } } @@ -1041,7 +1095,6 @@ static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const //////// bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { - PhysicsServer2D::ShapeType type_A = p_shape_A->get_type(); ERR_FAIL_COND_V(type_A == PhysicsServer2D::SHAPE_LINE, false); @@ -1323,7 +1376,6 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D collision_func = collision_table_castA_castB_margin[type_A - 2][type_B - 2]; } } else { - if (*motion_A == Vector2() && *motion_B == Vector2()) { collision_func = collision_table[type_A - 2][type_B - 2]; } else if (*motion_A != Vector2() && *motion_B == Vector2()) { diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp index f117dcbfe5..beba709807 100644 --- a/servers/physics_2d/collision_solver_2d_sw.cpp +++ b/servers/physics_2d/collision_solver_2d_sw.cpp @@ -35,10 +35,10 @@ //#define collision_solver gjk_epa_calculate_penetration bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const LineShape2DSW *line = static_cast<const LineShape2DSW *>(p_shape_A); - if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_LINE) + if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_LINE) { return false; + } Vector2 n = p_transform_A.basis_xform(line->get_normal()).normalized(); Vector2 p = p_transform_A.xform(line->get_normal() * line->get_d()); @@ -52,20 +52,21 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr bool found = false; for (int i = 0; i < support_count; i++) { - supports[i] = p_transform_B.xform(supports[i]); real_t pd = n.dot(supports[i]); - if (pd >= d) + if (pd >= d) { continue; + } found = true; Vector2 support_A = supports[i] - n * (pd - d); if (p_result_callback) { - if (p_swap_result) + if (p_swap_result) { p_result_callback(supports[i], support_A, p_userdata); - else + } else { p_result_callback(support_A, supports[i], p_userdata); + } } } @@ -73,10 +74,10 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr } bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) { - const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A); - if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_RAY) + if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_RAY) { return false; + } Vector2 from = p_transform_A.get_origin(); Vector2 to = from + p_transform_A[1] * ray->get_length(); @@ -93,9 +94,9 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector Vector2 p, n; if (!p_shape_B->intersect_segment(from, to, p, n)) { - - if (sep_axis) + if (sep_axis) { *sep_axis = p_transform_A[1].normalized(); + } return false; } @@ -106,16 +107,16 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector } if (p_result_callback) { - if (p_swap_result) + if (p_swap_result) { p_result_callback(support_B, support_A, p_userdata); - else + } else { p_result_callback(support_A, support_B, p_userdata); + } } return true; } struct _ConcaveCollisionInfo2D { - const Transform2D *transform_A; const Shape2DSW *shape_A; const Transform2D *transform_B; @@ -133,22 +134,22 @@ struct _ConcaveCollisionInfo2D { }; void CollisionSolver2DSW::concave_callback(void *p_userdata, Shape2DSW *p_convex) { - _ConcaveCollisionInfo2D &cinfo = *(_ConcaveCollisionInfo2D *)(p_userdata); cinfo.aabb_tests++; - if (!cinfo.result_callback && cinfo.collided) + if (!cinfo.result_callback && cinfo.collided) { return; //already collided and no contacts requested, don't test anymore + } bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, cinfo.motion_A, p_convex, *cinfo.transform_B, cinfo.motion_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, cinfo.sep_axis, cinfo.margin_A, cinfo.margin_B); - if (!collided) + if (!collided) { return; + } cinfo.collided = true; cinfo.collisions++; } bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { - const ConcaveShape2DSW *concave_B = static_cast<const ConcaveShape2DSW *>(p_shape_B); _ConcaveCollisionInfo2D cinfo; @@ -174,7 +175,6 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf Rect2 local_aabb; for (int i = 0; i < 2; i++) { - Vector2 axis(p_transform_B.elements[i]); real_t axis_scale = 1.0 / axis.length(); axis *= axis_scale; @@ -194,7 +194,6 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf } bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { - PhysicsServer2D::ShapeType type_A = p_shape_A->get_type(); PhysicsServer2D::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); @@ -211,7 +210,6 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p } if (type_A == PhysicsServer2D::SHAPE_LINE) { - if (type_B == PhysicsServer2D::SHAPE_LINE || type_B == PhysicsServer2D::SHAPE_RAY) { return false; } @@ -223,9 +221,7 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p } } else if (type_A == PhysicsServer2D::SHAPE_RAY) { - if (type_B == PhysicsServer2D::SHAPE_RAY) { - return false; //no ray-ray } @@ -236,17 +232,17 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p } } else if (concave_B) { - - if (concave_A) + if (concave_A) { return false; + } - if (!swap) + if (!swap) { return solve_concave(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B); - else + } else { return solve_concave(p_shape_B, p_transform_B, p_motion_B, p_shape_A, p_transform_A, p_motion_A, p_result_callback, p_userdata, true, sep_axis, margin_A, margin_B); + } } else { - return collision_solver(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B); } } diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/constraint_2d_sw.h index f8eb16214f..d8751f588e 100644 --- a/servers/physics_2d/constraint_2d_sw.h +++ b/servers/physics_2d/constraint_2d_sw.h @@ -34,7 +34,6 @@ #include "body_2d_sw.h" class Constraint2DSW { - Body2DSW **_body_ptr; int _body_count; uint64_t island_step; diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp index 4524629d50..81e961e90d 100644 --- a/servers/physics_2d/joints_2d_sw.cpp +++ b/servers/physics_2d/joints_2d_sw.cpp @@ -56,7 +56,6 @@ */ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) { - real_t value = 0; { @@ -66,7 +65,6 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const } if (b) { - value += b->get_inv_mass(); real_t rcn = rB.cross(n); value += b->get_inv_inertia() * rcn * rcn; @@ -78,10 +76,11 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const static inline Vector2 relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB) { Vector2 sum = a->get_linear_velocity() - rA.tangent() * a->get_angular_velocity(); - if (b) + if (b) { return (b->get_linear_velocity() - rB.tangent() * b->get_angular_velocity()) - sum; - else + } else { return -sum; + } } static inline real_t @@ -90,7 +89,6 @@ normal_relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB, Vecto } bool PinJoint2DSW::setup(real_t p_step) { - Space2DSW *space = A->get_space(); ERR_FAIL_COND_V(!space, false); rA = A->get_transform().basis_xform(anchor_A); @@ -115,7 +113,6 @@ bool PinJoint2DSW::setup(real_t p_step) { K[1] = K1[1] + K2[1]; if (B) { - Transform2D K3; K3[0].x = B->get_inv_inertia() * rB.y * rB.y; K3[1].x = -B->get_inv_inertia() * rB.x * rB.y; @@ -140,53 +137,53 @@ bool PinJoint2DSW::setup(real_t p_step) { // apply accumulated impulse A->apply_impulse(rA, -P); - if (B) + if (B) { B->apply_impulse(rB, P); + } return true; } inline Vector2 custom_cross(const Vector2 &p_vec, real_t p_other) { - return Vector2(p_other * p_vec.y, -p_other * p_vec.x); } void PinJoint2DSW::solve(real_t p_step) { - // compute relative velocity Vector2 vA = A->get_linear_velocity() - custom_cross(rA, A->get_angular_velocity()); Vector2 rel_vel; - if (B) + if (B) { rel_vel = B->get_linear_velocity() - custom_cross(rB, B->get_angular_velocity()) - vA; - else + } else { rel_vel = -vA; + } Vector2 impulse = M.basis_xform(bias - rel_vel - Vector2(softness, softness) * P); A->apply_impulse(rA, -impulse); - if (B) + if (B) { B->apply_impulse(rB, impulse); + } P += impulse; } void PinJoint2DSW::set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value) { - - if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) + if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) { softness = p_value; + } } real_t PinJoint2DSW::get_param(PhysicsServer2D::PinJointParam p_param) const { - - if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) + if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) { return softness; + } ERR_FAIL_V(0); } PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b) : Joint2DSW(_arr, p_body_b ? 2 : 1) { - A = p_body_a; B = p_body_b; anchor_A = p_body_a->get_inv_transform().xform(p_pos); @@ -195,16 +192,18 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p softness = 0; p_body_a->add_constraint(this, 0); - if (p_body_b) + if (p_body_b) { p_body_b->add_constraint(this, 1); + } } PinJoint2DSW::~PinJoint2DSW() { - - if (A) + if (A) { A->remove_constraint(this); - if (B) + } + if (B) { B->remove_constraint(this); + } } ////////////////////////////////////////////// @@ -259,7 +258,6 @@ mult_k(const Vector2 &vr, const Vector2 &k1, const Vector2 &k2) { } bool GrooveJoint2DSW::setup(real_t p_step) { - // calculate endpoints in worldspace Vector2 ta = A->get_transform().xform(A_groove_1); Vector2 tb = A->get_transform().xform(A_groove_2); @@ -311,7 +309,6 @@ bool GrooveJoint2DSW::setup(real_t p_step) { } void GrooveJoint2DSW::solve(real_t p_step) { - // compute impulse Vector2 vr = relative_velocity(A, B, rA, rB); @@ -329,7 +326,6 @@ void GrooveJoint2DSW::solve(real_t p_step) { GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b) : Joint2DSW(_arr, 2) { - A = p_body_a; B = p_body_b; @@ -343,7 +339,6 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_ } GrooveJoint2DSW::~GrooveJoint2DSW() { - A->remove_constraint(this); B->remove_constraint(this); } @@ -353,17 +348,17 @@ GrooveJoint2DSW::~GrooveJoint2DSW() { ////////////////////////////////////////////// bool DampedSpringJoint2DSW::setup(real_t p_step) { - rA = A->get_transform().basis_xform(anchor_A); rB = B->get_transform().basis_xform(anchor_B); Vector2 delta = (B->get_transform().get_origin() + rB) - (A->get_transform().get_origin() + rA); real_t dist = delta.length(); - if (dist) + if (dist) { n = delta / dist; - else + } else { n = Vector2(); + } real_t k = k_scalar(A, B, rA, rB, n); n_mass = 1.0f / k; @@ -382,7 +377,6 @@ bool DampedSpringJoint2DSW::setup(real_t p_step) { } void DampedSpringJoint2DSW::solve(real_t p_step) { - // compute relative velocity real_t vrn = normal_relative_velocity(A, B, rA, rB, n) - target_vrn; @@ -396,39 +390,29 @@ void DampedSpringJoint2DSW::solve(real_t p_step) { B->apply_impulse(rB, j); } -void DampedSpringJoint2DSW::set_param(PhysicsServer2D::DampedStringParam p_param, real_t p_value) { - +void DampedSpringJoint2DSW::set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value) { switch (p_param) { - - case PhysicsServer2D::DAMPED_STRING_REST_LENGTH: { - + case PhysicsServer2D::DAMPED_SPRING_REST_LENGTH: { rest_length = p_value; } break; - case PhysicsServer2D::DAMPED_STRING_DAMPING: { - + case PhysicsServer2D::DAMPED_SPRING_DAMPING: { damping = p_value; } break; - case PhysicsServer2D::DAMPED_STRING_STIFFNESS: { - + case PhysicsServer2D::DAMPED_SPRING_STIFFNESS: { stiffness = p_value; } break; } } -real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedStringParam p_param) const { - +real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedSpringParam p_param) const { switch (p_param) { - - case PhysicsServer2D::DAMPED_STRING_REST_LENGTH: { - + case PhysicsServer2D::DAMPED_SPRING_REST_LENGTH: { return rest_length; } break; - case PhysicsServer2D::DAMPED_STRING_DAMPING: { - + case PhysicsServer2D::DAMPED_SPRING_DAMPING: { return damping; } break; - case PhysicsServer2D::DAMPED_STRING_STIFFNESS: { - + case PhysicsServer2D::DAMPED_SPRING_STIFFNESS: { return stiffness; } break; } @@ -438,7 +422,6 @@ real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedStringParam p_par DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b) : Joint2DSW(_arr, 2) { - A = p_body_a; B = p_body_b; anchor_A = A->get_inv_transform().xform(p_anchor_a); @@ -453,7 +436,6 @@ DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Ve } DampedSpringJoint2DSW::~DampedSpringJoint2DSW() { - A->remove_constraint(this); B->remove_constraint(this); } diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h index a0d25dc70d..3c8aab77c8 100644 --- a/servers/physics_2d/joints_2d_sw.h +++ b/servers/physics_2d/joints_2d_sw.h @@ -35,7 +35,6 @@ #include "constraint_2d_sw.h" class Joint2DSW : public Constraint2DSW { - real_t max_force; real_t bias; real_t max_bias; @@ -59,7 +58,6 @@ public: }; class PinJoint2DSW : public Joint2DSW { - union { struct { Body2DSW *A; @@ -91,7 +89,6 @@ public: }; class GrooveJoint2DSW : public Joint2DSW { - union { struct { Body2DSW *A; @@ -126,7 +123,6 @@ public: }; class DampedSpringJoint2DSW : public Joint2DSW { - union { struct { Body2DSW *A; @@ -155,8 +151,8 @@ public: virtual bool setup(real_t p_step); virtual void solve(real_t p_step); - void set_param(PhysicsServer2D::DampedStringParam p_param, real_t p_value); - real_t get_param(PhysicsServer2D::DampedStringParam p_param) const; + void set_param(PhysicsServer2D::DampedSpringParam p_param, real_t p_value); + real_t get_param(PhysicsServer2D::DampedSpringParam p_param) const; DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b); ~DampedSpringJoint2DSW(); diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp index 871e2aba1d..6983225668 100644 --- a/servers/physics_2d/physics_server_2d_sw.cpp +++ b/servers/physics_2d/physics_server_2d_sw.cpp @@ -41,44 +41,33 @@ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { - Shape2DSW *shape = nullptr; switch (p_shape) { - case SHAPE_LINE: { - shape = memnew(LineShape2DSW); } break; case SHAPE_RAY: { - shape = memnew(RayShape2DSW); } break; case SHAPE_SEGMENT: { - shape = memnew(SegmentShape2DSW); } break; case SHAPE_CIRCLE: { - shape = memnew(CircleShape2DSW); } break; case SHAPE_RECTANGLE: { - shape = memnew(RectangleShape2DSW); } break; case SHAPE_CAPSULE: { - shape = memnew(CapsuleShape2DSW); } break; case SHAPE_CONVEX_POLYGON: { - shape = memnew(ConvexPolygonShape2DSW); } break; case SHAPE_CONCAVE_POLYGON: { - shape = memnew(ConcavePolygonShape2DSW); } break; case SHAPE_CUSTOM: { - ERR_FAIL_V(RID()); } break; @@ -91,63 +80,56 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) { } RID PhysicsServer2DSW::line_shape_create() { - return _shape_create(SHAPE_LINE); } RID PhysicsServer2DSW::ray_shape_create() { - return _shape_create(SHAPE_RAY); } -RID PhysicsServer2DSW::segment_shape_create() { +RID PhysicsServer2DSW::segment_shape_create() { return _shape_create(SHAPE_SEGMENT); } -RID PhysicsServer2DSW::circle_shape_create() { +RID PhysicsServer2DSW::circle_shape_create() { return _shape_create(SHAPE_CIRCLE); } -RID PhysicsServer2DSW::rectangle_shape_create() { +RID PhysicsServer2DSW::rectangle_shape_create() { return _shape_create(SHAPE_RECTANGLE); } -RID PhysicsServer2DSW::capsule_shape_create() { +RID PhysicsServer2DSW::capsule_shape_create() { return _shape_create(SHAPE_CAPSULE); } RID PhysicsServer2DSW::convex_polygon_shape_create() { - return _shape_create(SHAPE_CONVEX_POLYGON); } -RID PhysicsServer2DSW::concave_polygon_shape_create() { +RID PhysicsServer2DSW::concave_polygon_shape_create() { return _shape_create(SHAPE_CONCAVE_POLYGON); } void PhysicsServer2DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape2DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); }; void PhysicsServer2DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape2DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_custom_bias(p_bias); } PhysicsServer2D::ShapeType PhysicsServer2DSW::shape_get_type(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); return shape->get_type(); }; Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, Variant()); ERR_FAIL_COND_V(!shape->is_configured(), Variant()); @@ -155,18 +137,17 @@ Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const { }; real_t PhysicsServer2DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape2DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); return shape->get_custom_bias(); } void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) { - CollCbkData *cbk = (CollCbkData *)p_userdata; - if (cbk->max == 0) + if (cbk->max == 0) { return; + } if (cbk->valid_dir != Vector2()) { if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) { @@ -194,7 +175,6 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & real_t min_depth = 1e20; int min_depth_idx = 0; for (int i = 0; i < cbk->amount; i++) { - real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); if (d < min_depth) { min_depth = d; @@ -203,14 +183,14 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & } real_t d = p_point_A.distance_squared_to(p_point_B); - if (d < min_depth) + if (d < min_depth) { return; + } cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; cbk->passed++; } else { - cbk->ptr[cbk->amount * 2 + 0] = p_point_A; cbk->ptr[cbk->amount * 2 + 1] = p_point_B; cbk->amount++; @@ -219,14 +199,12 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 & } bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { - Shape2DSW *shape_A = shape_owner.getornull(p_shape_A); ERR_FAIL_COND_V(!shape_A, false); Shape2DSW *shape_B = shape_owner.getornull(p_shape_B); ERR_FAIL_COND_V(!shape_B, false); if (p_result_max == 0) { - return CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr); } @@ -242,7 +220,6 @@ bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_ } RID PhysicsServer2DSW::space_create() { - Space2DSW *space = memnew(Space2DSW); RID id = space_owner.make_rid(space); space->set_self(id); @@ -257,17 +234,16 @@ RID PhysicsServer2DSW::space_create() { }; void PhysicsServer2DSW::space_set_active(RID p_space, bool p_active) { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); - if (p_active) + if (p_active) { active_spaces.insert(space); - else + } else { active_spaces.erase(space); + } } bool PhysicsServer2DSW::space_is_active(RID p_space) const { - const Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, false); @@ -275,7 +251,6 @@ bool PhysicsServer2DSW::space_is_active(RID p_space) const { } void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -283,35 +258,30 @@ void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, rea } real_t PhysicsServer2DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } void PhysicsServer2DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector2> PhysicsServer2DSW::space_get_contacts(RID p_space) const { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, Vector<Vector2>()); return space->get_debug_contacts(); } int PhysicsServer2DSW::space_get_contact_count(RID p_space) const { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); } PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space) { - Space2DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, nullptr); ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); @@ -320,7 +290,6 @@ PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space } RID PhysicsServer2DSW::area_create() { - Area2DSW *area = memnew(Area2DSW); RID rid = area_owner.make_rid(area); area->set_self(rid); @@ -328,7 +297,6 @@ RID PhysicsServer2DSW::area_create() { }; void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -338,26 +306,26 @@ void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) { ERR_FAIL_COND(!space); } - if (area->get_space() == space) + if (area->get_space() == space) { return; //pointless + } area->clear_constraints(); area->set_space(space); }; RID PhysicsServer2DSW::area_get_space(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, RID()); Space2DSW *space = area->get_space(); - if (!space) + if (!space) { return RID(); + } return space->get_self(); }; void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -365,7 +333,6 @@ void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverri } PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_override_mode(RID p_area) const { - const Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); @@ -373,7 +340,6 @@ PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_overrid } void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -384,7 +350,6 @@ void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2 } void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -394,8 +359,8 @@ void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) area->set_shape(p_shape_idx, shape); } -void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) { +void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) { Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -403,7 +368,6 @@ void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, co } void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); ERR_FAIL_INDEX(p_shape, area->get_shape_count()); @@ -413,14 +377,13 @@ void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_ } int PhysicsServer2DSW::area_get_shape_count(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, -1); return area->get_shape_count(); } -RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { +RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, RID()); @@ -429,8 +392,8 @@ RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const { return shape->get_self(); } -Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { +Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform2D()); @@ -438,7 +401,6 @@ Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_ } void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -446,16 +408,15 @@ void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) { } void PhysicsServer2DSW::area_clear_shapes(RID p_area) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - while (area->get_shape_count()) + while (area->get_shape_count()) { area->remove_shape(0); + } } void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -464,8 +425,8 @@ void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id ERR_FAIL_COND(!area); area->set_instance_id(p_id); } -ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const { +ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -476,7 +437,6 @@ ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const { } void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -485,8 +445,8 @@ void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id ERR_FAIL_COND(!area); area->set_canvas_instance_id(p_id); } -ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const { +ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -497,7 +457,6 @@ ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const { } void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { - if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -508,14 +467,12 @@ void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const }; void PhysicsServer2DSW::area_set_transform(RID p_area, const Transform2D &p_transform) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); }; Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) const { - if (space_owner.owns(p_area)) { Space2DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -527,7 +484,6 @@ Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) con }; Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform2D()); @@ -535,14 +491,12 @@ Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const { }; void PhysicsServer2DSW::area_set_pickable(RID p_area, bool p_pickable) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_pickable(p_pickable); } void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); FLUSH_QUERY_CHECK(area); @@ -551,7 +505,6 @@ void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) { } void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -559,7 +512,6 @@ void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { } void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -567,7 +519,6 @@ void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { } void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -575,7 +526,6 @@ void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver } void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area2DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -585,7 +535,6 @@ void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec /* BODY API */ RID PhysicsServer2DSW::body_create() { - Body2DSW *body = memnew(Body2DSW); RID rid = body_owner.make_rid(body); body->set_self(rid); @@ -593,7 +542,6 @@ RID PhysicsServer2DSW::body_create() { } void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); Space2DSW *space = nullptr; @@ -602,26 +550,26 @@ void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) { ERR_FAIL_COND(!space); } - if (body->get_space() == space) + if (body->get_space() == space) { return; //pointless + } body->clear_constraint_map(); body->set_space(space); }; RID PhysicsServer2DSW::body_get_space(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); Space2DSW *space = body->get_space(); - if (!space) + if (!space) { return RID(); + } return space->get_self(); }; void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); FLUSH_QUERY_CHECK(body); @@ -630,7 +578,6 @@ void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) { }; PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); @@ -638,7 +585,6 @@ PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const { }; void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -649,7 +595,6 @@ void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2 } void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -659,8 +604,8 @@ void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) body->set_shape(p_shape_idx, shape); } -void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) { +void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -668,28 +613,25 @@ void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, co } void PhysicsServer2DSW::body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_shape_metadata(p_shape_idx, p_metadata); } Variant PhysicsServer2DSW::body_get_shape_metadata(RID p_body, int p_shape_idx) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Variant()); return body->get_shape_metadata(p_shape_idx); } int PhysicsServer2DSW::body_get_shape_count(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_shape_count(); } -RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { +RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); @@ -698,8 +640,8 @@ RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const { return shape->get_self(); } -Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { +Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Transform2D()); @@ -707,7 +649,6 @@ Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_ } void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -715,16 +656,15 @@ void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) { } void PhysicsServer2DSW::body_clear_shapes(RID p_body) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); - while (body->get_shape_count()) + while (body->get_shape_count()) { body->remove_shape(0); + } } void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); @@ -732,8 +672,8 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo body->set_shape_as_disabled(p_shape_idx, p_disabled); } -void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) { +void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) { Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); @@ -743,14 +683,12 @@ void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_sh } void PhysicsServer2DSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_continuous_collision_detection_mode(p_mode); } PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_detection_mode(RID p_body) const { - const Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, CCD_MODE_DISABLED); @@ -758,7 +696,6 @@ PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_dete } void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -766,7 +703,6 @@ void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id }; ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, ObjectID()); @@ -774,7 +710,6 @@ ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const { }; void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -782,7 +717,6 @@ void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id }; ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, ObjectID()); @@ -790,14 +724,12 @@ ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const { }; void PhysicsServer2DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); }; uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -805,14 +737,12 @@ uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const { }; void PhysicsServer2DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); }; uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -820,7 +750,6 @@ uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const { }; void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -828,7 +757,6 @@ void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, real_t }; real_t PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -836,7 +764,6 @@ real_t PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) cons }; void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -844,7 +771,6 @@ void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Vari }; Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Variant()); @@ -852,7 +778,6 @@ Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const { }; void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_force) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -861,14 +786,12 @@ void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_forc }; Vector2 PhysicsServer2DSW::body_get_applied_force(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector2()); return body->get_applied_force(); }; void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -877,7 +800,6 @@ void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) { }; real_t PhysicsServer2DSW::body_get_applied_torque(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -902,7 +824,6 @@ void PhysicsServer2DSW::body_apply_torque_impulse(RID p_body, real_t p_torque) { } void PhysicsServer2DSW::body_apply_impulse(RID p_body, const Vector2 &p_pos, const Vector2 &p_impulse) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -921,7 +842,6 @@ void PhysicsServer2DSW::body_add_central_force(RID p_body, const Vector2 &p_forc }; void PhysicsServer2DSW::body_add_force(RID p_body, const Vector2 &p_offset, const Vector2 &p_force) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -938,7 +858,6 @@ void PhysicsServer2DSW::body_add_torque(RID p_body, real_t p_torque) { }; void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -953,7 +872,6 @@ void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis }; void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -962,7 +880,6 @@ void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) { }; void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -971,7 +888,6 @@ void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b }; void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -981,20 +897,17 @@ void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e }; void PhysicsServer2DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); }; real_t PhysicsServer2DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return 0; }; void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -1002,35 +915,30 @@ void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit) }; bool PhysicsServer2DSW::body_is_omitting_force_integration(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_force_integration(); }; void PhysicsServer2DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_max_contacts_reported(p_contacts); } int PhysicsServer2DSW::body_get_max_contacts_reported(RID p_body) const { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_max_contacts_reported(); } void PhysicsServer2DSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata); } bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false); @@ -1039,14 +947,12 @@ bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_s } void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_pickable(p_pickable); } bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -1058,7 +964,6 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, } int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { - Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -1068,11 +973,11 @@ int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p } PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); - if (!body_owner.owns(p_body)) + if (!body_owner.owns(p_body)) { return nullptr; + } Body2DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, nullptr); @@ -1086,26 +991,36 @@ PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) { /* JOINT API */ void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { - Joint2DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); switch (p_param) { - case JOINT_PARAM_BIAS: joint->set_bias(p_value); break; - case JOINT_PARAM_MAX_BIAS: joint->set_max_bias(p_value); break; - case JOINT_PARAM_MAX_FORCE: joint->set_max_force(p_value); break; + case JOINT_PARAM_BIAS: + joint->set_bias(p_value); + break; + case JOINT_PARAM_MAX_BIAS: + joint->set_max_bias(p_value); + break; + case JOINT_PARAM_MAX_FORCE: + joint->set_max_force(p_value); + break; } } real_t PhysicsServer2DSW::joint_get_param(RID p_joint, JointParam p_param) const { - const Joint2DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, -1); switch (p_param) { - case JOINT_PARAM_BIAS: return joint->get_bias(); break; - case JOINT_PARAM_MAX_BIAS: return joint->get_max_bias(); break; - case JOINT_PARAM_MAX_FORCE: return joint->get_max_force(); break; + case JOINT_PARAM_BIAS: + return joint->get_bias(); + break; + case JOINT_PARAM_MAX_BIAS: + return joint->get_max_bias(); + break; + case JOINT_PARAM_MAX_FORCE: + return joint->get_max_force(); + break; } return 0; @@ -1139,7 +1054,6 @@ bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) } RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); ERR_FAIL_COND_V(!A, RID()); Body2DSW *B = nullptr; @@ -1156,7 +1070,6 @@ RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID } RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); ERR_FAIL_COND_V(!A, RID()); @@ -1170,7 +1083,6 @@ RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vec } RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) { - Body2DSW *A = body_owner.getornull(p_body_a); ERR_FAIL_COND_V(!A, RID()); @@ -1184,7 +1096,6 @@ RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, con } void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); ERR_FAIL_COND(j->get_type() != JOINT_PIN); @@ -1202,8 +1113,7 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param return pin_joint->get_param(p_param); } -void PhysicsServer2DSW::damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) { - +void PhysicsServer2DSW::damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND(!j); ERR_FAIL_COND(j->get_type() != JOINT_DAMPED_SPRING); @@ -1212,8 +1122,7 @@ void PhysicsServer2DSW::damped_string_joint_set_param(RID p_joint, DampedStringP dsj->set_param(p_param, p_value); } -real_t PhysicsServer2DSW::damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const { - +real_t PhysicsServer2DSW::damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const { Joint2DSW *j = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!j, 0); ERR_FAIL_COND_V(j->get_type() != JOINT_DAMPED_SPRING, 0); @@ -1223,7 +1132,6 @@ real_t PhysicsServer2DSW::damped_string_joint_get_param(RID p_joint, DampedStrin } PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const { - Joint2DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, JOINT_PIN); @@ -1231,11 +1139,9 @@ PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const } void PhysicsServer2DSW::free(RID p_rid) { - _update_shapes(); // just in case if (shape_owner.owns(p_rid)) { - Shape2DSW *shape = shape_owner.getornull(p_rid); while (shape->get_owners().size()) { @@ -1246,7 +1152,6 @@ void PhysicsServer2DSW::free(RID p_rid) { shape_owner.free(p_rid); memdelete(shape); } else if (body_owner.owns(p_rid)) { - Body2DSW *body = body_owner.getornull(p_rid); /* @@ -1260,7 +1165,6 @@ void PhysicsServer2DSW::free(RID p_rid) { body_set_space(p_rid, RID()); while (body->get_shape_count()) { - body->remove_shape(0); } @@ -1268,7 +1172,6 @@ void PhysicsServer2DSW::free(RID p_rid) { memdelete(body); } else if (area_owner.owns(p_rid)) { - Area2DSW *area = area_owner.getornull(p_rid); /* @@ -1279,14 +1182,12 @@ void PhysicsServer2DSW::free(RID p_rid) { area->set_space(nullptr); while (area->get_shape_count()) { - area->remove_shape(0); } area_owner.free(p_rid); memdelete(area); } else if (space_owner.owns(p_rid)) { - Space2DSW *space = space_owner.getornull(p_rid); while (space->get_objects().size()) { @@ -1299,25 +1200,21 @@ void PhysicsServer2DSW::free(RID p_rid) { space_owner.free(p_rid); memdelete(space); } else if (joint_owner.owns(p_rid)) { - Joint2DSW *joint = joint_owner.getornull(p_rid); joint_owner.free(p_rid); memdelete(joint); } else { - ERR_FAIL_MSG("Invalid ID."); } }; void PhysicsServer2DSW::set_active(bool p_active) { - active = p_active; }; void PhysicsServer2DSW::init() { - doing_sync = false; last_step = 0.001; iterations = 8; // 8? @@ -1326,9 +1223,9 @@ void PhysicsServer2DSW::init() { }; void PhysicsServer2DSW::step(real_t p_step) { - - if (!active) + if (!active) { return; + } _update_shapes(); @@ -1340,7 +1237,6 @@ void PhysicsServer2DSW::step(real_t p_step) { active_objects = 0; collision_pairs = 0; for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step((Space2DSW *)E->get(), p_step, iterations); island_count += E->get()->get_island_count(); active_objects += E->get()->get_active_objects(); @@ -1349,21 +1245,19 @@ void PhysicsServer2DSW::step(real_t p_step) { }; void PhysicsServer2DSW::sync() { - doing_sync = true; }; void PhysicsServer2DSW::flush_queries() { - - if (!active) + 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()) { - Space2DSW *space = (Space2DSW *)E->get(); space->call_queries(); } @@ -1371,7 +1265,6 @@ void PhysicsServer2DSW::flush_queries() { flushing_queries = false; if (EngineDebugger::is_profiling("servers")) { - uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX]; static const char *time_name[Space2DSW::ELAPSED_TIME_MAX] = { "integrate_forces", @@ -1386,7 +1279,6 @@ void PhysicsServer2DSW::flush_queries() { } for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - for (int i = 0; i < Space2DSW::ELAPSED_TIME_MAX; i++) { total_time[i] += E->get()->get_elapsed_time(Space2DSW::ElapsedTime(i)); } @@ -1411,13 +1303,11 @@ void PhysicsServer2DSW::end_sync() { } void PhysicsServer2DSW::finish() { - memdelete(stepper); memdelete(direct_state); }; void PhysicsServer2DSW::_update_shapes() { - while (pending_shape_update_list.first()) { pending_shape_update_list.first()->self()->_shape_changed(); pending_shape_update_list.remove(pending_shape_update_list.first()); @@ -1425,18 +1315,14 @@ void PhysicsServer2DSW::_update_shapes() { } int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { - switch (p_info) { - case INFO_ACTIVE_OBJECTS: { - return active_objects; } break; case INFO_COLLISION_PAIRS: { return collision_pairs; } break; case INFO_ISLAND_COUNT: { - return island_count; } break; } @@ -1447,7 +1333,6 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) { PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr; PhysicsServer2DSW::PhysicsServer2DSW() { - singletonsw = this; BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create; //BroadPhase2DSW::create_func=BroadPhase2DBasic::_create; @@ -1459,7 +1344,3 @@ PhysicsServer2DSW::PhysicsServer2DSW() { using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2; flushing_queries = false; }; - -PhysicsServer2DSW::~PhysicsServer2DSW(){ - -}; diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h index 918958ffe2..093c775cb5 100644 --- a/servers/physics_2d/physics_server_2d_sw.h +++ b/servers/physics_2d/physics_server_2d_sw.h @@ -39,7 +39,6 @@ #include "step_2d_sw.h" class PhysicsServer2DSW : public PhysicsServer2D { - GDCLASS(PhysicsServer2DSW, PhysicsServer2D); friend class PhysicsDirectSpaceState2DSW; @@ -79,7 +78,6 @@ class PhysicsServer2DSW : public PhysicsServer2D { public: struct CollCbkData { - Vector2 valid_dir; real_t valid_depth; int max; @@ -268,8 +266,8 @@ public: virtual RID damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b = RID()); virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value); virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const; - virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value); - virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const; + virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value); + virtual real_t damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const; virtual JointType joint_get_type(RID p_joint) const; @@ -290,7 +288,7 @@ public: int get_process_info(ProcessInfo p_info); PhysicsServer2DSW(); - ~PhysicsServer2DSW(); + ~PhysicsServer2DSW() {} }; #endif diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp index 0a89a76615..49c38c6ce0 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp +++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp @@ -33,25 +33,21 @@ #include "core/os/os.h" void PhysicsServer2DWrapMT::thread_exit() { - exit = true; } void PhysicsServer2DWrapMT::thread_step(real_t p_delta) { - physics_2d_server->step(p_delta); step_sem.post(); } void PhysicsServer2DWrapMT::_thread_callback(void *_instance) { - PhysicsServer2DWrapMT *vsmt = reinterpret_cast<PhysicsServer2DWrapMT *>(_instance); vsmt->thread_loop(); } void PhysicsServer2DWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); physics_2d_server->init(); @@ -71,57 +67,47 @@ void PhysicsServer2DWrapMT::thread_loop() { /* EVENT QUEUING */ void PhysicsServer2DWrapMT::step(real_t p_step) { - if (create_thread) { - command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step); } else { - command_queue.flush_all(); //flush all pending from other threads physics_2d_server->step(p_step); } } void PhysicsServer2DWrapMT::sync() { - if (thread) { - if (first_frame) + if (first_frame) { first_frame = false; - else + } else { step_sem.wait(); //must not wait if a step was not issued + } } physics_2d_server->sync(); } void PhysicsServer2DWrapMT::flush_queries() { - physics_2d_server->flush_queries(); } void PhysicsServer2DWrapMT::end_sync() { - physics_2d_server->end_sync(); } void PhysicsServer2DWrapMT::init() { - if (create_thread) { - //OS::get_singleton()->release_rendering_thread(); thread = Thread::create(_thread_callback, this); while (!step_thread_up) { OS::get_singleton()->delay_usec(1000); } } else { - physics_2d_server->init(); } } void PhysicsServer2DWrapMT::finish() { - if (thread) { - command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit); Thread::wait_to_finish(thread); memdelete(thread); @@ -147,7 +133,6 @@ void PhysicsServer2DWrapMT::finish() { PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) : command_queue(p_create_thread) { - physics_2d_server = p_contained; create_thread = p_create_thread; thread = nullptr; @@ -167,7 +152,6 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool } PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() { - memdelete(physics_2d_server); //finish(); } diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h index 7e61927378..bc918b20f4 100644 --- a/servers/physics_2d/physics_server_2d_wrap_mt.h +++ b/servers/physics_2d/physics_server_2d_wrap_mt.h @@ -43,7 +43,6 @@ #endif class PhysicsServer2DWrapMT : public PhysicsServer2D { - mutable PhysicsServer2D *physics_2d_server; mutable CommandQueueMT command_queue; @@ -95,7 +94,6 @@ public: //these work well, but should be used from the main thread only bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count); } @@ -111,20 +109,17 @@ public: // this function only works on physics process, errors and returns null otherwise PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->space_get_direct_state(p_space); } FUNC2(space_set_debug_contacts, RID, int); virtual Vector<Vector2> space_get_contacts(RID p_space) const { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>()); return physics_2d_server->space_get_contacts(p_space); } virtual int space_get_contact_count(RID p_space) const { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0); return physics_2d_server->space_get_contact_count(p_space); } @@ -256,20 +251,17 @@ public: FUNC2(body_set_pickable, RID, bool); bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes); } int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false); return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin); } // this function only works on physics process, errors and returns null otherwise PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) { - ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr); return physics_2d_server->body_get_direct_state(p_body); } @@ -295,8 +287,8 @@ public: FUNC3(pin_joint_set_param, RID, PinJointParam, real_t); FUNC2RC(real_t, pin_joint_get_param, RID, PinJointParam); - FUNC3(damped_string_joint_set_param, RID, DampedStringParam, real_t); - FUNC2RC(real_t, damped_string_joint_get_param, RID, DampedStringParam); + FUNC3(damped_spring_joint_set_param, RID, DampedSpringParam, real_t); + FUNC2RC(real_t, damped_spring_joint_get_param, RID, DampedSpringParam); FUNC1RC(JointType, joint_get_type, RID); @@ -325,14 +317,14 @@ public: template <class T> static PhysicsServer2D *init_server() { - int tm = GLOBAL_DEF("physics/2d/thread_model", 1); - if (tm == 0) // single unsafe + if (tm == 0) { // single unsafe return memnew(T); - else if (tm == 1) // single safe + } else if (tm == 1) { // single safe return memnew(PhysicsServer2DWrapMT(memnew(T), false)); - else // multi threaded + } else { // multi threaded return memnew(PhysicsServer2DWrapMT(memnew(T), true)); + } } #undef ServerNameWrapMT diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 06096d674a..87e22ef1c9 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -30,7 +30,7 @@ #include "shape_2d_sw.h" -#include "core/math/geometry.h" +#include "core/math/geometry_2d.h" #include "core/sort_array.h" void Shape2DSW::configure(const Rect2 &p_aabb) { @@ -43,7 +43,6 @@ void Shape2DSW::configure(const Rect2 &p_aabb) { } Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const { - Vector2 res[2]; int amnt; get_supports(p_normal, res, amnt); @@ -51,7 +50,6 @@ Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const { } void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) { - Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner); if (E) { E->get()++; @@ -61,7 +59,6 @@ void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) { } void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) { - Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner); ERR_FAIL_COND(!E); E->get()--; @@ -71,7 +68,6 @@ void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) { } bool Shape2DSW::is_owner(ShapeOwner2DSW *p_owner) const { - return owners.has(p_owner); } @@ -80,13 +76,11 @@ const Map<ShapeOwner2DSW *, int> &Shape2DSW::get_owners() const { } Shape2DSW::Shape2DSW() { - custom_bias = 0; configured = false; } Shape2DSW::~Shape2DSW() { - ERR_FAIL_COND(owners.size()); } @@ -95,23 +89,19 @@ Shape2DSW::~Shape2DSW() { /*********************************************************/ void LineShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - r_amount = 0; } bool LineShape2DSW::contains_point(const Vector2 &p_point) const { - return normal.dot(p_point) < d; } bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - Vector2 segment = p_begin - p_end; real_t den = normal.dot(segment); //printf("den is %i\n",den); if (Math::abs(den) <= CMP_EPSILON) { - return false; } @@ -119,7 +109,6 @@ bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_e //printf("dist is %i\n",dist); if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) { - return false; } @@ -130,12 +119,10 @@ bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_e } real_t LineShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - return 0; } void LineShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY); Array arr = p_data; ERR_FAIL_COND(arr.size() != 2); @@ -145,7 +132,6 @@ void LineShape2DSW::set_data(const Variant &p_data) { } Variant LineShape2DSW::get_data() const { - Array arr; arr.resize(2); arr[0] = normal; @@ -158,32 +144,28 @@ Variant LineShape2DSW::get_data() const { /*********************************************************/ void RayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - r_amount = 1; - if (p_normal.y > 0) + if (p_normal.y > 0) { *r_supports = Vector2(0, length); - else + } else { *r_supports = Vector2(); + } } bool RayShape2DSW::contains_point(const Vector2 &p_point) const { - return false; } bool RayShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - return false; //rays can't be intersected } real_t RayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - return 0; //rays are mass-less } void RayShape2DSW::set_data(const Variant &p_data) { - Dictionary d = p_data; length = d["length"]; slips_on_slope = d["slips_on_slope"]; @@ -191,7 +173,6 @@ void RayShape2DSW::set_data(const Variant &p_data) { } Variant RayShape2DSW::get_data() const { - Dictionary d; d["length"] = length; d["slips_on_slope"] = slips_on_slope; @@ -203,7 +184,6 @@ Variant RayShape2DSW::get_data() const { /*********************************************************/ void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) { r_supports[0] = a; r_supports[1] = b; @@ -212,22 +192,22 @@ void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports } real_t dp = p_normal.dot(b - a); - if (dp > 0) + if (dp > 0) { *r_supports = b; - else + } else { *r_supports = a; + } r_amount = 1; } bool SegmentShape2DSW::contains_point(const Vector2 &p_point) const { - return false; } bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - - if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &r_point)) + if (!Geometry2D::segment_intersects_segment(p_begin, p_end, a, b, &r_point)) { return false; + } if (n.dot(p_begin) > n.dot(a)) { r_normal = n; @@ -239,12 +219,10 @@ bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & } real_t SegmentShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - return p_mass * ((a * p_scale).distance_squared_to(b * p_scale)) / 12; } void SegmentShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::RECT2); Rect2 r = p_data; @@ -255,15 +233,16 @@ void SegmentShape2DSW::set_data(const Variant &p_data) { Rect2 aabb; aabb.position = a; aabb.expand_to(b); - if (aabb.size.x == 0) + if (aabb.size.x == 0) { aabb.size.x = 0.001; - if (aabb.size.y == 0) + } + if (aabb.size.y == 0) { aabb.size.y = 0.001; + } configure(aabb); } Variant SegmentShape2DSW::get_data() const { - Rect2 r; r.position = a; r.size = b; @@ -275,18 +254,15 @@ Variant SegmentShape2DSW::get_data() const { /*********************************************************/ void CircleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - r_amount = 1; *r_supports = p_normal * radius; } bool CircleShape2DSW::contains_point(const Vector2 &p_point) const { - return p_point.length_squared() < radius * radius; } bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - Vector2 line_vec = p_end - p_begin; real_t a, b, c; @@ -297,8 +273,9 @@ bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p real_t sqrtterm = b * b - 4 * a * c; - if (sqrtterm < 0) + if (sqrtterm < 0) { return false; + } sqrtterm = Math::sqrt(sqrtterm); real_t res = (-b - sqrtterm) / (2 * a); @@ -312,21 +289,18 @@ bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p } real_t CircleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - real_t a = radius * p_scale.x; real_t b = radius * p_scale.y; return p_mass * (a * a + b * b) / 4; } void CircleShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(!p_data.is_num()); radius = p_data; configure(Rect2(-radius, -radius, radius * 2, radius * 2)); } Variant CircleShape2DSW::get_data() const { - return radius; } @@ -335,14 +309,13 @@ Variant CircleShape2DSW::get_data() const { /*********************************************************/ void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - for (int i = 0; i < 2; i++) { - Vector2 ag; ag[i] = 1.0; real_t dp = ag.dot(p_normal); - if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) + if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) { continue; + } real_t sgn = dp > 0 ? 1.0 : -1.0; @@ -374,18 +347,15 @@ bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const { } bool RectangleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - return get_aabb().intersects_segment(p_begin, p_end, &r_point, &r_normal); } real_t RectangleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - Vector2 he2 = half_extents * 2 * p_scale; return p_mass * he2.dot(he2) / 12.0; } void RectangleShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::VECTOR2); half_extents = p_data; @@ -393,7 +363,6 @@ void RectangleShape2DSW::set_data(const Variant &p_data) { } Variant RectangleShape2DSW::get_data() const { - return half_extents; } @@ -402,13 +371,11 @@ Variant RectangleShape2DSW::get_data() const { /*********************************************************/ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - Vector2 n = p_normal; real_t d = n.y; if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) { - // make it flat n.y = 0.0; n.normalize(); @@ -421,7 +388,6 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports r_supports[1].y -= height * 0.5; } else { - real_t h = (d > 0) ? height : -height; n *= radius; @@ -432,25 +398,23 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports } bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const { - Vector2 p = p_point; p.y = Math::abs(p.y); p.y -= height * 0.5; - if (p.y < 0) + if (p.y < 0) { p.y = 0; + } return p.length_squared() < radius * radius; } bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - real_t d = 1e10; Vector2 n = (p_end - p_begin).normalized(); bool collided = false; //try spheres for (int i = 0; i < 2; i++) { - Vector2 begin = p_begin; Vector2 end = p_end; real_t ofs = (i == 0) ? -height * 0.5 : height * 0.5; @@ -467,8 +431,9 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & real_t sqrtterm = b * b - 4 * a * c; - if (sqrtterm < 0) + if (sqrtterm < 0) { continue; + } sqrtterm = Math::sqrt(sqrtterm); real_t res = (-b - sqrtterm) / (2 * a); @@ -490,7 +455,6 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & Vector2 rpos, rnorm; if (Rect2(Point2(-radius, -height * 0.5), Size2(radius * 2.0, height)).intersects_segment(p_begin, p_end, &rpos, &rnorm)) { - real_t pd = n.dot(rpos); if (pd < d) { r_point = rpos; @@ -505,13 +469,11 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 & } real_t CapsuleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - Vector2 he2 = Vector2(radius * 2, height + radius * 2) * p_scale; return p_mass * he2.dot(he2) / 12.0; } void CapsuleShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::VECTOR2); if (p_data.get_type() == Variant::ARRAY) { @@ -520,7 +482,6 @@ void CapsuleShape2DSW::set_data(const Variant &p_data) { height = arr[0]; radius = arr[1]; } else { - Point2 p = p_data; radius = p.x; height = p.y; @@ -531,7 +492,6 @@ void CapsuleShape2DSW::set_data(const Variant &p_data) { } Variant CapsuleShape2DSW::get_data() const { - return Point2(height, radius); } @@ -540,12 +500,10 @@ Variant CapsuleShape2DSW::get_data() const { /*********************************************************/ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - int support_idx = -1; real_t d = -1e10; for (int i = 0; i < point_count; i++) { - //test point real_t ld = p_normal.dot(points[i].pos); if (ld > d) { @@ -555,7 +513,6 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su //test segment if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) { - r_amount = 2; r_supports[0] = points[i].pos; r_supports[1] = points[(i + 1) % point_count].pos; @@ -570,30 +527,27 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su } bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const { - bool out = false; bool in = false; for (int i = 0; i < point_count; i++) { - real_t d = points[i].normal.dot(p_point) - points[i].normal.dot(points[i].pos); - if (d > 0) + if (d > 0) { out = true; - else + } else { in = true; + } } return in != out; } bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - Vector2 n = (p_end - p_begin).normalized(); real_t d = 1e10; bool inters = false; for (int i = 0; i < point_count; i++) { - //hmm.. no can do.. /* if (d.dot(points[i].normal)>=0) @@ -602,12 +556,12 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec Vector2 res; - if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) + if (!Geometry2D::segment_intersects_segment(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) { continue; + } real_t nd = n.dot(res); if (nd < d) { - d = nd; r_point = res; r_normal = points[i].normal; @@ -616,9 +570,9 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec } if (inters) { - - if (n.dot(r_normal) > 0) + if (n.dot(r_normal) > 0) { r_normal = -r_normal; + } } //return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal); @@ -626,11 +580,9 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec } real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const { - Rect2 aabb; aabb.position = points[0].pos * p_scale; for (int i = 0; i < point_count; i++) { - aabb.expand_to(points[i].pos * p_scale); } @@ -638,11 +590,11 @@ real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 } void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY); - if (points) + if (points) { memdelete_arr(points); + } points = nullptr; point_count = 0; @@ -658,13 +610,11 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { } for (int i = 0; i < point_count; i++) { - Vector2 p = points[i].pos; Vector2 pn = points[(i + 1) % point_count].pos; points[i].normal = (pn - p).tangent().normalized(); } } else { - Vector<real_t> dvr = p_data; point_count = dvr.size() / 4; ERR_FAIL_COND(point_count == 0); @@ -673,7 +623,6 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { const real_t *r = dvr.ptr(); for (int i = 0; i < point_count; i++) { - int idx = i << 2; points[i].pos.x = r[idx + 0]; points[i].pos.y = r[idx + 1]; @@ -685,14 +634,14 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) { ERR_FAIL_COND(point_count == 0); Rect2 aabb; aabb.position = points[0].pos; - for (int i = 1; i < point_count; i++) + for (int i = 1; i < point_count; i++) { aabb.expand_to(points[i].pos); + } configure(aabb); } Variant ConvexPolygonShape2DSW::get_data() const { - Vector<Vector2> dvr; dvr.resize(point_count); @@ -705,25 +654,22 @@ Variant ConvexPolygonShape2DSW::get_data() const { } ConvexPolygonShape2DSW::ConvexPolygonShape2DSW() { - points = nullptr; point_count = 0; } ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() { - - if (points) + if (points) { memdelete_arr(points); + } } ////////////////////////////////////////////////// void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const { - real_t d = -1e10; int idx = -1; for (int i = 0; i < points.size(); i++) { - real_t ld = p_normal.dot(points[i]); if (ld > d) { d = ld; @@ -737,12 +683,10 @@ void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_s } bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const { - return false; //sorry } bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const { - uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth); enum { @@ -773,34 +717,27 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve stack[0] = 0; while (true) { - uint32_t node = stack[level] & NODE_IDX_MASK; const BVH &bvh = bvhptr[node]; bool done = false; switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = bvh.aabb.intersects_segment(p_begin, p_end); if (!valid) { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; } else { - if (bvh.left < 0) { - const Segment &s = segmentptr[bvh.right]; Vector2 a = pointptr[s.points[0]]; Vector2 b = pointptr[s.points[1]]; Vector2 res; - if (Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &res)) { - + if (Geometry2D::segment_intersects_segment(p_begin, p_end, a, b, &res)) { real_t nd = n.dot(res); if (nd < d) { - d = nd; r_point = res; r_normal = (b - a).tangent().normalized(); @@ -811,54 +748,50 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; } else { - stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node; } } } continue; case VISIT_LEFT_BIT: { - stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; stack[level + 1] = bvh.left | TEST_AABB_BIT; level++; } continue; case VISIT_RIGHT_BIT: { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; stack[level + 1] = bvh.right | TEST_AABB_BIT; level++; } continue; case VISIT_DONE_BIT: { - if (level == 0) { done = true; break; - } else + } else { level--; + } } continue; } - if (done) + if (done) { break; + } } if (inters) { - - if (n.dot(r_normal) > 0) + if (n.dot(r_normal) > 0) { r_normal = -r_normal; + } } return inters; } int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { - if (p_len == 1) { - bvh_depth = MAX(p_depth, bvh_depth); bvh.push_back(*p_bvh); return bvh.size() - 1; @@ -872,12 +805,10 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { } if (global_aabb.size.x > global_aabb.size.y) { - SortArray<BVH, BVH_CompareX> sort; sort.sort(p_bvh, p_len); } else { - SortArray<BVH, BVH_CompareY> sort; sort.sort(p_bvh, p_len); } @@ -898,13 +829,11 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { } void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY); Rect2 aabb; if (p_data.get_type() == Variant::PACKED_VECTOR2_ARRAY) { - Vector<Vector2> p2arr = p_data; int len = p2arr.size(); ERR_FAIL_COND(len % 2); @@ -923,7 +852,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { Map<Point2, int> pointmap; for (int i = 0; i < len; i += 2) { - Point2 p1 = arr[i]; Point2 p2 = arr[i + 1]; int idx_p1, idx_p2; @@ -951,7 +879,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { points.resize(pointmap.size()); aabb.position = pointmap.front()->key(); for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) { - aabb.expand_to(E->key()); points.write[E->get()] = E->key(); } @@ -959,7 +886,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { Vector<BVH> main_vbh; main_vbh.resize(segments.size()); for (int i = 0; i < main_vbh.size(); i++) { - main_vbh.write[i].aabb.position = points[segments[i].points[0]]; main_vbh.write[i].aabb.expand_to(points[segments[i].points[1]]); main_vbh.write[i].left = -1; @@ -974,14 +900,13 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { configure(aabb); } -Variant ConcavePolygonShape2DSW::get_data() const { +Variant ConcavePolygonShape2DSW::get_data() const { Vector<Vector2> rsegments; int len = segments.size(); rsegments.resize(len * 2); Vector2 *w = rsegments.ptrw(); for (int i = 0; i < len; i++) { - w[(i << 1) + 0] = points[segments[i].points[0]]; w[(i << 1) + 1] = points[segments[i].points[1]]; } @@ -990,7 +915,6 @@ Variant ConcavePolygonShape2DSW::get_data() const { } void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callback, void *p_userdata) const { - uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth); enum { @@ -1021,22 +945,17 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac stack[0] = 0; while (true) { - uint32_t node = stack[level] & NODE_IDX_MASK; const BVH &bvh = bvhptr[node]; switch (stack[level] >> VISITED_BIT_SHIFT) { case TEST_AABB_BIT: { - bool valid = p_local_aabb.intersects(bvh.aabb); if (!valid) { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; } else { - if (bvh.left < 0) { - const Segment &s = segmentptr[bvh.right]; Vector2 a = pointptr[s.points[0]]; Vector2 b = pointptr[s.points[1]]; @@ -1047,32 +966,29 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; } else { - stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node; } } } continue; case VISIT_LEFT_BIT: { - stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; stack[level + 1] = bvh.left | TEST_AABB_BIT; level++; } continue; case VISIT_RIGHT_BIT: { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; stack[level + 1] = bvh.right | TEST_AABB_BIT; level++; } continue; case VISIT_DONE_BIT: { - - if (level == 0) + if (level == 0) { return; - else + } else { level--; + } } continue; } diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index ca001e6dd9..eca284f7a4 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -57,7 +57,6 @@ public: }; class Shape2DSW { - RID self; Rect2 aabb; bool configured; @@ -100,13 +99,12 @@ public: const Map<ShapeOwner2DSW *, int> &get_owners() const; _FORCE_INLINE_ void get_supports_transformed_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_xform, Vector2 *r_supports, int &r_amount) const { - get_supports(p_xform.basis_xform_inv(p_normal).normalized(), r_supports, r_amount); - for (int i = 0; i < r_amount; i++) + for (int i = 0; i < r_amount; i++) { r_supports[i] = p_xform.xform(r_supports[i]); + } if (r_amount == 1) { - if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) { //make line because they are parallel r_amount = 2; @@ -117,7 +115,6 @@ public: } } else { - if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) { //optimize line and make it larger because they are parallel if ((r_supports[1] - r_supports[0]).dot(p_cast) > 0) { @@ -145,7 +142,6 @@ public: project_range_cast(p_cast, p_normal, p_transform, r_min, r_max); \ } \ _FORCE_INLINE_ void project_range_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { \ - \ real_t mina, maxa; \ real_t minb, maxb; \ Transform2D ofsb = p_transform; \ @@ -157,7 +153,6 @@ public: } class LineShape2DSW : public Shape2DSW { - Vector2 normal; real_t d; @@ -195,7 +190,6 @@ public: }; class RayShape2DSW : public Shape2DSW { - real_t length; bool slips_on_slope; @@ -220,7 +214,6 @@ public: r_max = p_normal.dot(p_transform.get_origin()); r_min = p_normal.dot(p_transform.xform(Vector2(0, length))); if (r_max < r_min) { - SWAP(r_max, r_min); } } @@ -232,7 +225,6 @@ public: }; class SegmentShape2DSW : public Shape2DSW { - Vector2 a; Vector2 b; Vector2 n; @@ -245,7 +237,6 @@ public: virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_SEGMENT; } _FORCE_INLINE_ Vector2 get_xformed_normal(const Transform2D &p_xform) const { - return (p_xform.xform(b) - p_xform.xform(a)).normalized().tangent(); } virtual void project_rangev(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal, p_transform, r_min, r_max); } @@ -263,7 +254,6 @@ public: r_max = p_normal.dot(p_transform.xform(a)); r_min = p_normal.dot(p_transform.xform(b)); if (r_max < r_min) { - SWAP(r_max, r_min); } } @@ -279,7 +269,6 @@ public: }; class CircleShape2DSW : public Shape2DSW { - real_t radius; public: @@ -313,7 +302,6 @@ public: }; class RectangleShape2DSW : public Shape2DSW { - Vector2 half_extents; public: @@ -336,18 +324,18 @@ public: r_max = -1e20; r_min = 1e20; for (int i = 0; i < 4; i++) { - real_t d = p_normal.dot(p_transform.xform(Vector2(((i & 1) * 2 - 1) * half_extents.x, ((i >> 1) * 2 - 1) * half_extents.y))); - if (d > r_max) + if (d > r_max) { r_max = d; - if (d < r_min) + } + if (d < r_min) { r_min = d; + } } } _FORCE_INLINE_ Vector2 get_circle_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const Vector2 &p_circle) const { - Vector2 local_v = p_xform_inv.xform(p_circle); Vector2 he( @@ -358,7 +346,6 @@ public: } _FORCE_INLINE_ Vector2 get_box_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const RectangleShape2DSW *p_B, const Transform2D &p_B_xform, const Transform2D &p_B_xform_inv) const { - Vector2 a, b; { @@ -387,7 +374,6 @@ public: }; class CapsuleShape2DSW : public Shape2DSW { - real_t radius; real_t height; @@ -419,7 +405,6 @@ public: r_min = p_normal.dot(p_transform.xform(-n)); if (r_max < r_min) { - SWAP(r_max, r_min); } @@ -430,9 +415,7 @@ public: }; class ConvexPolygonShape2DSW : public Shape2DSW { - struct Point { - Vector2 pos; Vector2 normal; //normal to next segment }; @@ -445,7 +428,6 @@ public: _FORCE_INLINE_ const Vector2 &get_point(int p_idx) const { return points[p_idx].pos; } _FORCE_INLINE_ const Vector2 &get_segment_normal(int p_idx) const { return points[p_idx].normal; } _FORCE_INLINE_ Vector2 get_xformed_segment_normal(const Transform2D &p_xform, int p_idx) const { - Vector2 a = points[p_idx].pos; p_idx++; Vector2 b = points[p_idx == point_count ? 0 : p_idx].pos; @@ -465,7 +447,6 @@ public: virtual Variant get_data() const; _FORCE_INLINE_ void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { - if (!points || point_count <= 0) { r_min = r_max = 0; return; @@ -473,12 +454,13 @@ public: r_min = r_max = p_normal.dot(p_transform.xform(points[0].pos)); for (int i = 1; i < point_count; i++) { - real_t d = p_normal.dot(p_transform.xform(points[i].pos)); - if (d > r_max) + if (d > r_max) { r_max = d; - if (d < r_min) + } + if (d < r_min) { r_min = d; + } } } @@ -489,7 +471,6 @@ public: }; class ConcaveShape2DSW : public Shape2DSW { - public: virtual bool is_concave() const { return true; } typedef void (*Callback)(void *p_userdata, Shape2DSW *p_convex); @@ -498,9 +479,7 @@ public: }; class ConcavePolygonShape2DSW : public ConcaveShape2DSW { - struct Segment { - int points[2]; }; @@ -508,7 +487,6 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW { Vector<Point2> points; struct BVH { - Rect2 aabb; int left, right; }; @@ -517,17 +495,13 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW { int bvh_depth; struct BVH_CompareX { - _FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const { - return (a.aabb.position.x + a.aabb.size.x * 0.5) < (b.aabb.position.x + b.aabb.size.x * 0.5); } }; struct BVH_CompareY { - _FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const { - return (a.aabb.position.y + a.aabb.size.y * 0.5) < (b.aabb.position.y + b.aabb.size.y * 0.5); } }; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 7ae2e9769f..966dcbd651 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -35,24 +35,25 @@ #include "core/pair.h" #include "physics_server_2d_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) { - if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; } - if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas) + 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) + if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies) { return false; + } return true; } int PhysicsDirectSpaceState2DSW::_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) + if (p_result_max <= 0) { return 0; + } Rect2 aabb; aabb.position = p_point - Vector2(0.00001, 0.00001); @@ -63,20 +64,23 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S int cc = 0; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; - if (p_pick_point && !col_obj->is_pickable()) + if (p_pick_point && !col_obj->is_pickable()) { continue; + } - if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id) + 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]; @@ -84,15 +88,18 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point); - if (!shape->contains_point(local_point)) + if (!shape->contains_point(local_point)) { continue; + } - if (cc >= p_result_max) + if (cc >= p_result_max) { continue; + } r_results[cc].collider_id = col_obj->get_instance_id(); - if (r_results[cc].collider_id.is_valid()) + if (r_results[cc].collider_id.is_valid()) { r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); + } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx); @@ -104,17 +111,14 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S } int PhysicsDirectSpaceState2DSW::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 PhysicsDirectSpaceState2DSW::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 PhysicsDirectSpaceState2DSW::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); Vector2 begin, end; @@ -134,12 +138,13 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec real_t min_d = 1e10; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; @@ -160,14 +165,12 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec Vector2 shape_point, shape_normal; if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) { - Transform2D xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); shape_point = xform.xform(shape_point); real_t ld = normal.dot(shape_point); if (ld < min_d) { - min_d = ld; res_point = shape_point; res_normal = inv_xform.basis_xform_inv(shape_normal).normalized(); @@ -178,12 +181,14 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec } } - if (!collided) + if (!collided) { return false; + } r_result.collider_id = res_obj->get_instance_id(); - if (r_result.collider_id.is_valid()) + if (r_result.collider_id.is_valid()) { r_result.collider = ObjectDB::get_instance(r_result.collider_id); + } r_result.normal = res_normal; r_result.metadata = res_obj->get_shape_metadata(res_shape); r_result.position = res_point; @@ -194,9 +199,9 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec } int PhysicsDirectSpaceState2DSW::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) + if (p_result_max <= 0) { return 0; + } Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -209,25 +214,29 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans int cc = 0; for (int i = 0; i < amount; i++) { - - if (cc >= p_result_max) + if (cc >= p_result_max) { break; + } - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) + if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) { continue; + } r_results[cc].collider_id = col_obj->get_instance_id(); - if (r_results[cc].collider_id.is_valid()) + if (r_results[cc].collider_id.is_valid()) { r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); + } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx); @@ -239,7 +248,6 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState2DSW::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 = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -253,12 +261,13 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; //ignore excluded + } const CollisionObject2DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; @@ -271,7 +280,6 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor //test initial overlap if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) { - return false; } @@ -288,10 +296,8 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin); if (collided) { - hi = ofs; } else { - low = ofs; } } @@ -309,9 +315,9 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor } bool PhysicsDirectSpaceState2DSW::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; + if (p_result_max <= 0) { + return false; + } Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -335,15 +341,16 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & PhysicsServer2DSW::CollCbkData *cbkptr = &cbk; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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]; int shape_idx = space->intersection_query_subindex_results[i]; - if (p_exclude.has(col_obj->get_self())) + if (p_exclude.has(col_obj->get_self())) { continue; + } cbk.valid_dir = Vector2(); cbk.valid_depth = 0; @@ -359,7 +366,6 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D & } struct _RestCallbackData2D { - const CollisionObject2DSW *object; const CollisionObject2DSW *best_object; int local_shape; @@ -375,24 +381,27 @@ struct _RestCallbackData2D { }; static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) { - _RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata; if (rd->valid_dir != Vector2()) { - if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth) + if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth) { return; - if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25) + } + if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25) { return; + } } Vector2 contact_rel = p_point_B - p_point_A; real_t len = contact_rel.length(); - if (len < rd->min_allowed_depth) + if (len < rd->min_allowed_depth) { return; + } - if (len <= rd->best_len) + if (len <= rd->best_len) { return; + } rd->best_len = len; rd->best_contact = p_point_B; @@ -403,7 +412,6 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, } bool PhysicsDirectSpaceState2DSW::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 = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -420,15 +428,16 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh rcd.min_allowed_depth = space->test_motion_min_contact_depth; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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]; int shape_idx = space->intersection_query_subindex_results[i]; - if (p_exclude.has(col_obj->get_self())) + if (p_exclude.has(col_obj->get_self())) { continue; + } rcd.valid_dir = Vector2(); rcd.valid_depth = 0; @@ -436,12 +445,14 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh 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, nullptr, p_margin); - if (!sc) + if (!sc) { continue; + } } - if (rcd.best_len == 0 || !rcd.best_object) + if (rcd.best_len == 0 || !rcd.best_object) { return false; + } r_info->collider_id = rcd.best_object->get_instance_id(); r_info->shape = rcd.best_shape; @@ -450,7 +461,6 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh r_info->rid = rcd.best_object->get_self(); r_info->metadata = rcd.best_object->get_shape_metadata(rcd.best_shape); if (rcd.best_object->get_type() == CollisionObject2DSW::TYPE_BODY) { - const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object); Vector2 rel_vec = r_info->point - body->get_transform().get_origin(); r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); @@ -463,33 +473,30 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh } PhysicsDirectSpaceState2DSW::PhysicsDirectSpaceState2DSW() { - space = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { - int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); for (int i = 0; i < amount; i++) { - bool keep = true; - if (intersection_query_results[i] == p_body) + if (intersection_query_results[i] == p_body) { keep = false; - else if (intersection_query_results[i]->get_type() == CollisionObject2DSW::TYPE_AREA) + } else if (intersection_query_results[i]->get_type() == CollisionObject2DSW::TYPE_AREA) { keep = false; - else if ((static_cast<Body2DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) + } else if ((static_cast<Body2DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) { keep = false; - else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) + } else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { keep = false; - else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) + } else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) { keep = false; + } if (!keep) { - if (i < amount - 1) { SWAP(intersection_query_results[i], intersection_query_results[amount - 1]); SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]); @@ -504,18 +511,18 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) { } int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin) { - Rect2 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)) + if (p_body->is_shape_set_as_disabled(i)) { continue; + } - if (p_body->get_shape(i)->get_type() != PhysicsServer2D::SHAPE_RAY) + if (p_body->get_shape(i)->get_type() != PhysicsServer2D::SHAPE_RAY) { continue; + } if (!shapes_found) { body_aabb = p_body->get_shape_aabb(i); @@ -554,7 +561,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t CollisionSolver2DSW::CallbackResult cbkres = PhysicsServer2DSW::_shape_col_cbk; do { - Vector2 recover_motion; bool collided = false; @@ -562,18 +568,19 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t int amount = _cull_aabb_for_body(p_body, body_aabb); for (int j = 0; j < p_body->get_shape_count(); j++) { - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Shape2DSW *body_shape = p_body->get_shape(j); - if (body_shape->get_type() != PhysicsServer2D::SHAPE_RAY) + if (body_shape->get_type() != PhysicsServer2D::SHAPE_RAY) { continue; + } Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -631,7 +638,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t } if (ray_index != -1) { - PhysicsServer2D::SeparationResult &result = r_results[ray_index]; for (int k = 0; k < cbk.amount; k++) { @@ -642,7 +648,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t 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(); @@ -688,7 +693,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t } bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes) { - //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -705,12 +709,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co bool shapes_found = false; for (int i = 0; i < p_body->get_shape_count(); i++) { - - if (p_body->is_shape_set_as_disabled(i)) + if (p_body->is_shape_set_as_disabled(i)) { continue; + } - if (p_exclude_raycast_shapes && p_body->get_shape(i)->get_type() == PhysicsServer2D::SHAPE_RAY) + if (p_exclude_raycast_shapes && p_body->get_shape(i)->get_type() == PhysicsServer2D::SHAPE_RAY) { continue; + } if (!shapes_found) { body_aabb = p_body->get_shape_aabb(i); @@ -748,7 +753,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co Vector2 sr[max_results * 2]; do { - PhysicsServer2DSW::CollCbkData cbk; cbk.max = max_results; cbk.amount = 0; @@ -765,8 +769,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co int amount = _cull_aabb_for_body(p_body, body_aabb); for (int j = 0; j < p_body->get_shape_count(); j++) { - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Shape2DSW *body_shape = p_body->get_shape(j); if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) { @@ -775,7 +780,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -789,7 +793,6 @@ 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 = col_obj_shape_xform.get_axis(1).normalized(); float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx); @@ -846,7 +849,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co Vector2 recover_motion; for (int i = 0; i < cbk.amount; i++) { - Vector2 a = sr[i * 2 + 0]; Vector2 b = sr[i * 2 + 1]; recover_motion += (b - a) * 0.4; @@ -879,9 +881,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co int amount = _cull_aabb_for_body(p_body, motion_aabb); for (int body_shape_idx = 0; body_shape_idx < p_body->get_shape_count(); body_shape_idx++) { - - if (p_body->is_shape_set_as_disabled(body_shape_idx)) + if (p_body->is_shape_set_as_disabled(body_shape_idx)) { continue; + } Shape2DSW *body_shape = p_body->get_shape(body_shape_idx); if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) { @@ -896,7 +898,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; int col_shape_idx = intersection_query_subindex_results[i]; Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx); @@ -911,7 +912,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co 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 == col_shape_idx) { excluded = true; break; @@ -919,7 +919,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } if (excluded) { - continue; } @@ -931,7 +930,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co //test initial overlap if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) { - if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { continue; } @@ -953,16 +951,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0); if (collided) { - hi = ofs; } else { - low = ofs; } } if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) { - Vector2 cd[2]; PhysicsServer2DSW::CollCbkData cbk; cbk.max = 1; @@ -987,7 +982,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } if (stuck) { - safe = 0; unsafe = 0; best_shape = body_shape_idx; //sadly it's the best @@ -997,7 +991,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co continue; } if (best_safe < safe) { - safe = best_safe; unsafe = best_unsafe; best_shape = body_shape_idx; @@ -1011,7 +1004,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } { - //it collided, let's get the rest info in unsafe advance Transform2D ugt = body_transform; ugt.elements[2] += p_motion * unsafe; @@ -1027,9 +1019,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); for (int j = from_shape; j < to_shape; j++) { - - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j); Shape2DSW *body_shape = p_body->get_shape(j); @@ -1043,7 +1035,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co int amount = _cull_aabb_for_body(p_body, body_aabb); for (int i = 0; i < amount; i++) { - const CollisionObject2DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -1058,19 +1049,18 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co 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) + if (excluded) { continue; + } 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)) { - rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized(); rcd.valid_depth = 10e20; } else { @@ -1082,13 +1072,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co 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, nullptr, p_margin); - if (!sc) + if (!sc) { continue; + } } } if (rcd.best_len != 0) { - if (r_result) { r_result->collider = rcd.best_object->get_self(); r_result->collider_id = rcd.best_object->get_instance_id(); @@ -1112,7 +1102,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } if (!collided && r_result) { - r_result->motion = p_motion; r_result->remainder = Vector2(); r_result->motion += (body_transform.get_origin() - p_from.get_origin()); @@ -1122,11 +1111,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co } void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self) { + if (!A->test_collision_mask(B)) { + return nullptr; + } CollisionObject2DSW::Type type_A = A->get_type(); CollisionObject2DSW::Type type_B = B->get_type(); if (type_A > type_B) { - SWAP(A, B); SWAP(p_subindex_A, p_subindex_B); SWAP(type_A, type_B); @@ -1136,22 +1127,18 @@ void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, Coll self->collision_pairs++; if (type_A == CollisionObject2DSW::TYPE_AREA) { - Area2DSW *area = static_cast<Area2DSW *>(A); if (type_B == CollisionObject2DSW::TYPE_AREA) { - Area2DSW *area_b = static_cast<Area2DSW *>(B); Area2Pair2DSW *area2_pair = memnew(Area2Pair2DSW(area_b, p_subindex_B, area, p_subindex_A)); return area2_pair; } else { - Body2DSW *body = static_cast<Body2DSW *>(B); AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body, p_subindex_B, area, p_subindex_A)); return area_pair; } } else { - BodyPair2DSW *b = memnew(BodyPair2DSW((Body2DSW *)A, p_subindex_A, (Body2DSW *)B, p_subindex_B)); return b; } @@ -1160,6 +1147,9 @@ void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, Coll } void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_self) { + if (!p_data) { + return; + } Space2DSW *self = (Space2DSW *)p_self; self->collision_pairs--; @@ -1168,94 +1158,79 @@ void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, Col } const SelfList<Body2DSW>::List &Space2DSW::get_active_body_list() const { - return active_list; } -void Space2DSW::body_add_to_active_list(SelfList<Body2DSW> *p_body) { +void Space2DSW::body_add_to_active_list(SelfList<Body2DSW> *p_body) { active_list.add(p_body); } -void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW> *p_body) { +void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW> *p_body) { active_list.remove(p_body); } void Space2DSW::body_add_to_inertia_update_list(SelfList<Body2DSW> *p_body) { - inertia_update_list.add(p_body); } void Space2DSW::body_remove_from_inertia_update_list(SelfList<Body2DSW> *p_body) { - inertia_update_list.remove(p_body); } BroadPhase2DSW *Space2DSW::get_broadphase() { - return broadphase; } void Space2DSW::add_object(CollisionObject2DSW *p_object) { - ERR_FAIL_COND(objects.has(p_object)); objects.insert(p_object); } void Space2DSW::remove_object(CollisionObject2DSW *p_object) { - ERR_FAIL_COND(!objects.has(p_object)); objects.erase(p_object); } const Set<CollisionObject2DSW *> &Space2DSW::get_objects() const { - return objects; } void Space2DSW::body_add_to_state_query_list(SelfList<Body2DSW> *p_body) { - state_query_list.add(p_body); } -void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW> *p_body) { +void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW> *p_body) { state_query_list.remove(p_body); } void Space2DSW::area_add_to_monitor_query_list(SelfList<Area2DSW> *p_area) { - monitor_query_list.add(p_area); } -void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area) { +void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area) { monitor_query_list.remove(p_area); } void Space2DSW::area_add_to_moved_list(SelfList<Area2DSW> *p_area) { - area_moved_list.add(p_area); } void Space2DSW::area_remove_from_moved_list(SelfList<Area2DSW> *p_area) { - area_moved_list.remove(p_area); } const SelfList<Area2DSW>::List &Space2DSW::get_moved_area_list() const { - return area_moved_list; } void Space2DSW::call_queries() { - while (state_query_list.first()) { - Body2DSW *b = state_query_list.first()->self(); state_query_list.remove(state_query_list.first()); b->call_queries(); } while (monitor_query_list.first()) { - Area2DSW *a = monitor_query_list.first()->self(); monitor_query_list.remove(monitor_query_list.first()); a->call_queries(); @@ -1263,7 +1238,6 @@ void Space2DSW::call_queries() { } void Space2DSW::setup() { - contact_debug_count = 0; while (inertia_update_list.first()) { @@ -1273,63 +1247,77 @@ void Space2DSW::setup() { } void Space2DSW::update() { - broadphase->update(); } void Space2DSW::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_value) { - switch (p_param) { - - case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break; - case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break; - case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break; - case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break; - case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break; - case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break; - case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break; - case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: test_motion_min_contact_depth = p_value; break; + case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: + contact_recycle_radius = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: + contact_max_separation = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: + contact_max_allowed_penetration = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: + body_linear_velocity_sleep_threshold = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: + body_angular_velocity_sleep_threshold = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: + body_time_to_sleep = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: + constraint_bias = p_value; + break; + case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: + test_motion_min_contact_depth = p_value; + break; } } real_t Space2DSW::get_param(PhysicsServer2D::SpaceParameter p_param) const { - switch (p_param) { - - case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; - case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation; - case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration; - case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold; - case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold; - case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep; - case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; - case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: return test_motion_min_contact_depth; + case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: + return contact_recycle_radius; + case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: + return contact_max_separation; + case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: + return contact_max_allowed_penetration; + case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: + return body_linear_velocity_sleep_threshold; + case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: + return body_angular_velocity_sleep_threshold; + case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: + return body_time_to_sleep; + case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: + return constraint_bias; + case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: + return test_motion_min_contact_depth; } return 0; } void Space2DSW::lock() { - locked = true; } void Space2DSW::unlock() { - locked = false; } bool Space2DSW::is_locked() const { - return locked; } PhysicsDirectSpaceState2DSW *Space2DSW::get_direct_state() { - return direct_access; } Space2DSW::Space2DSW() { - collision_pairs = 0; active_objects = 0; island_count = 0; @@ -1356,12 +1344,12 @@ Space2DSW::Space2DSW() { direct_access = memnew(PhysicsDirectSpaceState2DSW); direct_access->space = this; - for (int i = 0; i < ELAPSED_TIME_MAX; i++) + for (int i = 0; i < ELAPSED_TIME_MAX; i++) { elapsed_time[i] = 0; + } } Space2DSW::~Space2DSW() { - memdelete(broadphase); memdelete(direct_access); } diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index c6b324c928..0a96f2f495 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -42,7 +42,6 @@ #include "core/typedefs.h" class PhysicsDirectSpaceState2DSW : public PhysicsDirectSpaceState2D { - GDCLASS(PhysicsDirectSpaceState2DSW, PhysicsDirectSpaceState2D); 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 = ObjectID()); @@ -62,7 +61,6 @@ public: }; class Space2DSW { - public: enum ElapsedTime { ELAPSED_TIME_INTEGRATE_FORCES, @@ -192,7 +190,9 @@ public: void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } _FORCE_INLINE_ void add_debug_contact(const Vector2 &p_contact) { - if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact; + if (contact_debug_count < contact_debug.size()) { + contact_debug.write[contact_debug_count++] = p_contact; + } } _FORCE_INLINE_ Vector<Vector2> get_debug_contacts() { return contact_debug; } _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp index 6f3bcfec13..c7711bcd1d 100644 --- a/servers/physics_2d/step_2d_sw.cpp +++ b/servers/physics_2d/step_2d_sw.cpp @@ -32,33 +32,33 @@ #include "core/os/os.h" void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constraint2DSW **p_constraint_island) { - p_body->set_island_step(_step); p_body->set_island_next(*p_island); *p_island = p_body; for (Map<Constraint2DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) { - Constraint2DSW *c = (Constraint2DSW *)E->key(); - if (c->get_island_step() == _step) + if (c->get_island_step() == _step) { continue; //already processed + } c->set_island_step(_step); c->set_island_next(*p_constraint_island); *p_constraint_island = c; for (int i = 0; i < c->get_body_count(); i++) { - if (i == E->get()) + if (i == E->get()) { continue; + } Body2DSW *b = c->get_body_ptr()[i]; - if (b->get_island_step() == _step || b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) + if (b->get_island_step() == _step || b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) { continue; //no go + } _populate_island(c->get_body_ptr()[i], p_island, p_constraint_island); } } } bool Step2DSW::_setup_island(Constraint2DSW *p_island, real_t p_delta) { - Constraint2DSW *ci = p_island; Constraint2DSW *prev_ci = nullptr; bool removed_root = false; @@ -83,9 +83,7 @@ bool Step2DSW::_setup_island(Constraint2DSW *p_island, real_t p_delta) { } void Step2DSW::_solve_island(Constraint2DSW *p_island, int p_iterations, real_t p_delta) { - for (int i = 0; i < p_iterations; i++) { - Constraint2DSW *ci = p_island; while (ci) { ci->solve(p_delta); @@ -95,19 +93,18 @@ void Step2DSW::_solve_island(Constraint2DSW *p_island, int p_iterations, real_t } void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) { - bool can_sleep = true; Body2DSW *b = p_island; while (b) { - if (b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) { b = b->get_island_next(); continue; //ignore for static } - if (!b->sleep_test(p_delta)) + if (!b->sleep_test(p_delta)) { can_sleep = false; + } b = b->get_island_next(); } @@ -116,7 +113,6 @@ void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) { b = p_island; while (b) { - if (b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) { b = b->get_island_next(); continue; //ignore for static @@ -124,15 +120,15 @@ void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) { bool active = b->is_active(); - if (active == can_sleep) + if (active == can_sleep) { b->set_active(!can_sleep); + } b = b->get_island_next(); } } void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { - p_space->lock(); // can't access space during this p_space->setup(); //update inertias, etc @@ -148,7 +144,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { const SelfList<Body2DSW> *b = body_list->first(); while (b) { - b->self()->integrate_forces(p_delta); b = b->next(); active_count++; @@ -174,7 +169,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { Body2DSW *body = b->self(); if (body->get_island_step() != _step) { - Body2DSW *island = nullptr; Constraint2DSW *constraint_island = nullptr; _populate_island(body, &island, &constraint_island); @@ -197,10 +191,10 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { while (aml.first()) { for (const Set<Constraint2DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - Constraint2DSW *c = E->get(); - if (c->get_island_step() == _step) + if (c->get_island_step() == _step) { continue; + } c->set_island_step(_step); c->set_island_next(nullptr); c->set_island_list_next(constraint_island_list); @@ -221,9 +215,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { Constraint2DSW *ci = constraint_island_list; Constraint2DSW *prev_ci = nullptr; while (ci) { - if (_setup_island(ci, p_delta)) { - //removed the root from the island graph because it is not to be processed Constraint2DSW *next = ci->get_island_next(); @@ -238,7 +230,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { } prev_ci = next; } else { - //list is empty, just skip if (prev_ci) { prev_ci->set_island_list_next(ci->get_island_list_next()); @@ -282,7 +273,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { b = body_list->first(); while (b) { - const SelfList<Body2DSW> *n = b->next(); b->self()->integrate_velocities(p_delta); b = n; // in case it shuts itself down @@ -293,7 +283,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { { Body2DSW *bi = island_list; while (bi) { - _check_suspend(bi, p_delta); bi = bi->get_island_list_next(); } @@ -311,6 +300,5 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) { } Step2DSW::Step2DSW() { - _step = 1; } diff --git a/servers/physics_2d/step_2d_sw.h b/servers/physics_2d/step_2d_sw.h index 22d59b729b..c1b2d01fb4 100644 --- a/servers/physics_2d/step_2d_sw.h +++ b/servers/physics_2d/step_2d_sw.h @@ -34,7 +34,6 @@ #include "space_2d_sw.h" class Step2DSW { - uint64_t _step; void _populate_island(Body2DSW *p_body, Body2DSW **p_island, Constraint2DSW **p_constraint_island); diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp index 911a664a10..98237dd91c 100644 --- a/servers/physics_3d/area_3d_sw.cpp +++ b/servers/physics_3d/area_3d_sw.cpp @@ -38,6 +38,7 @@ Area3DSW::BodyKey::BodyKey(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_a body_shape = p_body_shape; area_shape = p_area_shape; } + Area3DSW::BodyKey::BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { rid = p_body->get_self(); instance_id = p_body->get_instance_id(); @@ -46,27 +47,28 @@ Area3DSW::BodyKey::BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_a } void Area3DSW::_shapes_changed() { - - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area3DSW::set_transform(const Transform &p_transform) { - - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } _set_transform(p_transform); _set_inv_transform(p_transform.affine_inverse()); } void Area3DSW::set_space(Space3DSW *p_space) { - if (get_space()) { - if (monitor_query_list.in_list()) + if (monitor_query_list.in_list()) { get_space()->area_remove_from_monitor_query_list(&monitor_query_list); - if (moved_list.in_list()) + } + if (moved_list.in_list()) { get_space()->area_remove_from_moved_list(&moved_list); + } } monitored_bodies.clear(); @@ -76,7 +78,6 @@ void Area3DSW::set_space(Space3DSW *p_space) { } void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == monitor_callback_id) { monitor_callback_method = p_method; return; @@ -92,12 +93,12 @@ void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) { _shape_changed(); - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == area_monitor_callback_id) { area_monitor_callback_method = p_method; return; @@ -113,74 +114,97 @@ void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth _shape_changed(); - if (!moved_list.in_list() && get_space()) + if (!moved_list.in_list() && get_space()) { get_space()->area_add_to_moved_list(&moved_list); + } } void Area3DSW::set_space_override_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) { bool do_override = p_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; - if (do_override == (space_override_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)) + if (do_override == (space_override_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)) { return; + } _unregister_shapes(); space_override_mode = p_mode; _shape_changed(); } void Area3DSW::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) { - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: gravity = p_value; break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: gravity_vector = p_value; break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point = p_value; break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale = p_value; break; - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation = p_value; break; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: linear_damp = p_value; break; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: angular_damp = p_value; break; - case PhysicsServer3D::AREA_PARAM_PRIORITY: priority = p_value; break; + case PhysicsServer3D::AREA_PARAM_GRAVITY: + gravity = p_value; + break; + case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: + gravity_vector = p_value; + break; + case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: + gravity_is_point = p_value; + break; + case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: + gravity_distance_scale = p_value; + break; + case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: + point_attenuation = p_value; + break; + case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: + linear_damp = p_value; + break; + case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: + angular_damp = p_value; + break; + case PhysicsServer3D::AREA_PARAM_PRIORITY: + priority = p_value; + break; } } Variant Area3DSW::get_param(PhysicsServer3D::AreaParameter p_param) const { - switch (p_param) { - case PhysicsServer3D::AREA_PARAM_GRAVITY: return gravity; - case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector; - case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point; - case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale; - case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation; - case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: return linear_damp; - case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: return angular_damp; - case PhysicsServer3D::AREA_PARAM_PRIORITY: return priority; + case PhysicsServer3D::AREA_PARAM_GRAVITY: + return gravity; + case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: + return gravity_vector; + case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: + return gravity_is_point; + case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: + return gravity_distance_scale; + case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: + return point_attenuation; + case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: + return linear_damp; + case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: + return angular_damp; + case PhysicsServer3D::AREA_PARAM_PRIORITY: + return priority; } return Variant(); } void Area3DSW::_queue_monitor_update() { - ERR_FAIL_COND(!get_space()); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { get_space()->area_add_to_monitor_query_list(&monitor_query_list); + } } void Area3DSW::set_monitorable(bool p_monitorable) { - - if (monitorable == p_monitorable) + if (monitorable == p_monitorable) { return; + } monitorable = p_monitorable; _set_static(!monitorable); } void Area3DSW::call_queries() { - if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) { - Variant res[5]; Variant *resptr[5]; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { resptr[i] = &res[i]; + } Object *obj = ObjectDB::get_instance(monitor_callback_id); if (!obj) { @@ -190,9 +214,9 @@ void Area3DSW::call_queries() { } for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) { - - if (E->get().state == 0) + if (E->get().state == 0) { continue; //nothing happened + } res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; res[1] = E->key().rid; @@ -208,11 +232,11 @@ void Area3DSW::call_queries() { monitored_bodies.clear(); if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) { - Variant res[5]; Variant *resptr[5]; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { resptr[i] = &res[i]; + } Object *obj = ObjectDB::get_instance(area_monitor_callback_id); if (!obj) { @@ -222,9 +246,9 @@ void Area3DSW::call_queries() { } for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) { - - if (E->get().state == 0) + if (E->get().state == 0) { continue; //nothing happened + } res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; res[1] = E->key().rid; @@ -245,7 +269,6 @@ Area3DSW::Area3DSW() : CollisionObject3DSW(TYPE_AREA), monitor_query_list(this), moved_list(this) { - _set_static(true); //areas are never active space_override_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED; gravity = 9.80665; diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h index 05e74e63dc..6af3976167 100644 --- a/servers/physics_3d/area_3d_sw.h +++ b/servers/physics_3d/area_3d_sw.h @@ -41,7 +41,6 @@ class Body3DSW; class Constraint3DSW; class Area3DSW : public CollisionObject3DSW { - PhysicsServer3D::AreaSpaceOverrideMode space_override_mode; real_t gravity; Vector3 gravity_vector; @@ -63,23 +62,21 @@ class Area3DSW : public CollisionObject3DSW { SelfList<Area3DSW> moved_list; struct BodyKey { - RID rid; ObjectID instance_id; uint32_t body_shape; uint32_t area_shape; _FORCE_INLINE_ bool operator<(const BodyKey &p_key) const { - if (rid == p_key.rid) { - if (body_shape == p_key.body_shape) { - return area_shape < p_key.area_shape; - } else + } else { return body_shape < p_key.body_shape; - } else + } + } else { return rid < p_key.rid; + } } _FORCE_INLINE_ BodyKey() {} @@ -88,7 +85,6 @@ class Area3DSW : public CollisionObject3DSW { }; struct BodyState { - int state; _FORCE_INLINE_ void inc() { state++; } _FORCE_INLINE_ void dec() { state--; } @@ -171,33 +167,35 @@ public: }; void Area3DSW::add_body_to_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { - BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].inc(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } -void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { +void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) { BodyKey bk(p_body, p_body_shape, p_area_shape); monitored_bodies[bk].dec(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } void Area3DSW::add_area_to_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { - BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].inc(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } -void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { +void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) { BodyKey bk(p_area, p_area_shape, p_self_shape); monitored_areas[bk].dec(); - if (!monitor_query_list.in_list()) + if (!monitor_query_list.in_list()) { _queue_monitor_update(); + } } #endif // AREA__SW_H diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/area_pair_3d_sw.cpp index fa2fb2dabb..a5fb20fe2b 100644 --- a/servers/physics_3d/area_pair_3d_sw.cpp +++ b/servers/physics_3d/area_pair_3d_sw.cpp @@ -32,7 +32,6 @@ #include "collision_solver_3d_sw.h" bool AreaPair3DSW::setup(real_t p_step) { - bool result = false; if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) { @@ -42,20 +41,21 @@ bool AreaPair3DSW::setup(real_t p_step) { } if (result != colliding) { - if (result) { - - if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { body->add_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->add_body_to_query(body, body_shape, area_shape); + } } else { - - if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->remove_body_from_query(body, body_shape, area_shape); + } } colliding = result; @@ -68,7 +68,6 @@ void AreaPair3DSW::solve(real_t p_step) { } AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, int p_area_shape) { - body = p_body; area = p_area; body_shape = p_body_shape; @@ -76,18 +75,19 @@ AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, colliding = false; body->add_constraint(this, 0); area->add_constraint(this); - if (p_body->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) + if (p_body->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) { p_body->set_active(true); + } } AreaPair3DSW::~AreaPair3DSW() { - if (colliding) { - - if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) + if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) { body->remove_area(area); - if (area->has_monitor_callback()) + } + if (area->has_monitor_callback()) { area->remove_body_from_query(body, body_shape, area_shape); + } } body->remove_constraint(this); area->remove_constraint(this); @@ -96,7 +96,6 @@ AreaPair3DSW::~AreaPair3DSW() { //////////////////////////////////////////////////// bool Area2Pair3DSW::setup(real_t p_step) { - bool result = false; if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) { result = false; @@ -105,22 +104,23 @@ bool Area2Pair3DSW::setup(real_t p_step) { } if (result != colliding) { - if (result) { - - if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) { area_b->add_area_to_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_b->is_monitorable()) { area_a->add_area_to_query(area_b, shape_b, shape_a); + } } else { - - if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) { 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_b->is_monitorable()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); + } } colliding = result; @@ -133,7 +133,6 @@ void Area2Pair3DSW::solve(real_t p_step) { } Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area_b, int p_shape_b) { - area_a = p_area_a; area_b = p_area_b; shape_a = p_shape_a; @@ -144,14 +143,14 @@ Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area } Area2Pair3DSW::~Area2Pair3DSW() { - if (colliding) { - - if (area_b->has_area_monitor_callback()) + 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()) + if (area_a->has_area_monitor_callback()) { area_a->remove_area_from_query(area_b, shape_b, shape_a); + } } area_a->remove_constraint(this); diff --git a/servers/physics_3d/area_pair_3d_sw.h b/servers/physics_3d/area_pair_3d_sw.h index 3490f41c26..992d4747b9 100644 --- a/servers/physics_3d/area_pair_3d_sw.h +++ b/servers/physics_3d/area_pair_3d_sw.h @@ -36,7 +36,6 @@ #include "constraint_3d_sw.h" class AreaPair3DSW : public Constraint3DSW { - Body3DSW *body; Area3DSW *area; int body_shape; @@ -52,7 +51,6 @@ public: }; class Area2Pair3DSW : public Constraint3DSW { - Area3DSW *area_a; Area3DSW *area_b; int shape_a; diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp index fea5aed6ad..a3bdc96c9f 100644 --- a/servers/physics_3d/body_3d_sw.cpp +++ b/servers/physics_3d/body_3d_sw.cpp @@ -33,13 +33,12 @@ #include "space_3d_sw.h" void Body3DSW::_update_inertia() { - - if (get_space() && !inertia_update_list.in_list()) + if (get_space() && !inertia_update_list.in_list()) { get_space()->body_add_to_inertia_update_list(&inertia_update_list); + } } void Body3DSW::_update_transform_dependant() { - center_of_mass = get_transform().basis.xform(center_of_mass_local); principal_inertia_axes = get_transform().basis * principal_inertia_axes_local; @@ -52,18 +51,14 @@ void Body3DSW::_update_transform_dependant() { } void Body3DSW::update_inertias() { - //update shapes and motions switch (mode) { - case PhysicsServer3D::BODY_MODE_RIGID: { - //update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet) real_t total_area = 0; for (int i = 0; i < get_shape_count(); i++) { - total_area += get_shape_area(i); } @@ -86,7 +81,6 @@ void Body3DSW::update_inertias() { inertia_tensor.set_zero(); for (int i = 0; i < get_shape_count(); i++) { - if (is_shape_disabled(i)) { continue; } @@ -112,21 +106,20 @@ void Body3DSW::update_inertias() { principal_inertia_axes_local = inertia_tensor.diagonalize().transposed(); _inv_inertia = inertia_tensor.get_main_diagonal().inverse(); - if (mass) + if (mass) { _inv_mass = 1.0 / mass; - else + } else { _inv_mass = 0; + } } break; case PhysicsServer3D::BODY_MODE_KINEMATIC: case PhysicsServer3D::BODY_MODE_STATIC: { - _inv_inertia_tensor.set_zero(); _inv_mass = 0; } break; case PhysicsServer3D::BODY_MODE_CHARACTER: { - _inv_inertia_tensor.set_zero(); _inv_mass = 1.0 / mass; @@ -139,19 +132,22 @@ void Body3DSW::update_inertias() { } void Body3DSW::set_active(bool p_active) { - - if (active == p_active) + if (active == p_active) { return; + } active = p_active; if (!p_active) { - if (get_space()) + if (get_space()) { get_space()->body_remove_from_active_list(&active_list); + } } else { - if (mode == PhysicsServer3D::BODY_MODE_STATIC) + if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; //static bodies can't become active - if (get_space()) + } + if (get_space()) { get_space()->body_add_to_active_list(&active_list); + } //still_time=0; } @@ -169,14 +165,11 @@ void Body3DSW::set_active(bool p_active) { } void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) { - switch (p_param) { case PhysicsServer3D::BODY_PARAM_BOUNCE: { - bounce = p_value; } break; case PhysicsServer3D::BODY_PARAM_FRICTION: { - friction = p_value; } break; case PhysicsServer3D::BODY_PARAM_MASS: { @@ -189,11 +182,9 @@ void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) gravity_scale = p_value; } break; case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: { - linear_damp = p_value; } break; case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: { - angular_damp = p_value; } break; default: { @@ -202,14 +193,11 @@ void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) } real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const { - switch (p_param) { case PhysicsServer3D::BODY_PARAM_BOUNCE: { - return bounce; } break; case PhysicsServer3D::BODY_PARAM_FRICTION: { - return friction; } break; case PhysicsServer3D::BODY_PARAM_MASS: { @@ -219,11 +207,9 @@ real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const { return gravity_scale; } break; case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: { - return linear_damp; } break; case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: { - return angular_damp; } break; @@ -235,7 +221,6 @@ real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const { } void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { - PhysicsServer3D::BodyMode prev = mode; mode = p_mode; @@ -243,7 +228,6 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { //CLEAR UP EVERYTHING IN CASE IT NOT WORKS! case PhysicsServer3D::BODY_MODE_STATIC: case PhysicsServer3D::BODY_MODE_KINEMATIC: { - _set_inv_transform(get_transform().affine_inverse()); _inv_mass = 0; _set_static(p_mode == PhysicsServer3D::BODY_MODE_STATIC); @@ -257,14 +241,12 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { } break; case PhysicsServer3D::BODY_MODE_RIGID: { - _inv_mass = mass > 0 ? (1.0 / mass) : 0; _set_static(false); set_active(true); } break; case PhysicsServer3D::BODY_MODE_CHARACTER: { - _inv_mass = mass > 0 ? (1.0 / mass) : 0; _set_static(false); set_active(true); @@ -278,21 +260,18 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) { _update_queries(); */ } -PhysicsServer3D::BodyMode Body3DSW::get_mode() const { +PhysicsServer3D::BodyMode Body3DSW::get_mode() const { return mode; } void Body3DSW::_shapes_changed() { - _update_inertia(); } void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) { - switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { - if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { new_transform = p_variant; //wakeup_neighbours(); @@ -311,8 +290,9 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va Transform t = p_variant; t.orthonormalize(); new_transform = get_transform(); //used as old to compute motion - if (new_transform == t) + if (new_transform == t) { break; + } _set_transform(t); _set_inv_transform(get_transform().inverse()); } @@ -320,7 +300,6 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } break; case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: { - /* if (mode==PhysicsServer3D::BODY_MODE_STATIC) break; @@ -339,8 +318,9 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } break; case PhysicsServer3D::BODY_STATE_SLEEPING: { //? - if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) + if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { break; + } bool do_sleep = p_variant; if (do_sleep) { linear_velocity = Vector3(); @@ -354,14 +334,15 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va } break; case PhysicsServer3D::BODY_STATE_CAN_SLEEP: { can_sleep = p_variant; - if (mode == PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep) + if (mode == PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep) { set_active(true); + } } break; } } -Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const { +Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const { switch (p_state) { case PhysicsServer3D::BODY_STATE_TRANSFORM: { return get_transform(); @@ -384,24 +365,25 @@ Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const { } void Body3DSW::set_space(Space3DSW *p_space) { - if (get_space()) { - - if (inertia_update_list.in_list()) + if (inertia_update_list.in_list()) { get_space()->body_remove_from_inertia_update_list(&inertia_update_list); - if (active_list.in_list()) + } + if (active_list.in_list()) { get_space()->body_remove_from_active_list(&active_list); - if (direct_state_query_list.in_list()) + } + if (direct_state_query_list.in_list()) { get_space()->body_remove_from_state_query_list(&direct_state_query_list); + } } _set_space(p_space); if (get_space()) { - _update_inertia(); - if (active) + if (active) { get_space()->body_add_to_active_list(&active_list); + } /* _update_queries(); if (is_active()) { @@ -415,7 +397,6 @@ void Body3DSW::set_space(Space3DSW *p_space) { } void Body3DSW::_compute_area_gravity_and_dampenings(const Area3DSW *p_area) { - if (p_area->is_gravity_point()) { if (p_area->get_gravity_distance_scale() > 0) { Vector3 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin(); @@ -444,9 +425,9 @@ bool Body3DSW::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const { } void Body3DSW::integrate_forces(real_t p_step) { - - if (mode == PhysicsServer3D::BODY_MODE_STATIC) + if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; + } Area3DSW *def_area = get_space()->get_default_area(); // AreaSW *damp_area = def_area; @@ -491,15 +472,17 @@ void Body3DSW::integrate_forces(real_t p_step) { gravity *= gravity_scale; // If less than 0, override dampenings with that of the Body - if (angular_damp >= 0) + if (angular_damp >= 0) { area_angular_damp = angular_damp; + } /* else area_angular_damp=damp_area->get_angular_damp(); */ - if (linear_damp >= 0) + if (linear_damp >= 0) { area_linear_damp = linear_damp; + } /* else area_linear_damp=damp_area->get_linear_damp(); @@ -509,7 +492,6 @@ void Body3DSW::integrate_forces(real_t p_step) { bool do_motion = false; if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { - //compute motion, angular and etc. velocities from prev transform linear_velocity = (new_transform.origin - get_transform().origin) / p_step; @@ -535,13 +517,15 @@ void Body3DSW::integrate_forces(real_t p_step) { real_t damp = 1.0 - p_step * area_linear_damp; - if (damp < 0) // reached zero in the given time + if (damp < 0) { // reached zero in the given time damp = 0; + } real_t angular_damp = 1.0 - p_step * area_angular_damp; - if (angular_damp < 0) // reached zero in the given time + if (angular_damp < 0) { // reached zero in the given time angular_damp = 0; + } linear_velocity *= damp; angular_velocity *= angular_damp; @@ -574,12 +558,13 @@ void Body3DSW::integrate_forces(real_t p_step) { } void Body3DSW::integrate_velocities(real_t p_step) { - - if (mode == PhysicsServer3D::BODY_MODE_STATIC) + if (mode == PhysicsServer3D::BODY_MODE_STATIC) { return; + } - if (fi_callback) + if (fi_callback) { get_space()->body_add_to_state_query_list(&direct_state_query_list); + } //apply axis lock linear for (int i = 0; i < 3; i++) { @@ -598,11 +583,11 @@ void Body3DSW::integrate_velocities(real_t p_step) { } if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { - _set_transform(new_transform, false); _set_inv_transform(new_transform.affine_inverse()); - if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3()) + if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3()) { set_active(false); //stopped moving, deactivate + } return; } @@ -673,34 +658,33 @@ void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) { } + */ void Body3DSW::wakeup_neighbours() { - for (Map<Constraint3DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) { - const Constraint3DSW *c = E->key(); Body3DSW **n = c->get_body_ptr(); int bc = c->get_body_count(); for (int i = 0; i < bc; i++) { - - if (i == E->get()) + if (i == E->get()) { continue; + } Body3DSW *b = n[i]; - if (b->mode != PhysicsServer3D::BODY_MODE_RIGID) + if (b->mode != PhysicsServer3D::BODY_MODE_RIGID) { continue; + } - if (!b->is_active()) + if (!b->is_active()) { b->set_active(true); + } } } } void Body3DSW::call_queries() { - if (fi_callback) { - PhysicsDirectBodyState3DSW *dbs = PhysicsDirectBodyState3DSW::singleton; dbs->body = this; @@ -708,7 +692,6 @@ void Body3DSW::call_queries() { Object *obj = ObjectDB::get_instance(fi_callback->id); if (!obj) { - set_force_integration_callback(ObjectID(), StringName()); } else { const Variant *vp[2] = { &v, &fi_callback->udata }; @@ -721,36 +704,31 @@ void Body3DSW::call_queries() { } bool Body3DSW::sleep_test(real_t p_step) { - - if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) + if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { return true; // - else if (mode == PhysicsServer3D::BODY_MODE_CHARACTER) + } else if (mode == PhysicsServer3D::BODY_MODE_CHARACTER) { return !active; // characters don't sleep unless asked to sleep - else if (!can_sleep) + } else if (!can_sleep) { return false; + } if (Math::abs(angular_velocity.length()) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) { - still_time += p_step; return still_time > get_space()->get_body_time_to_sleep(); } else { - still_time = 0; //maybe this should be set to 0 on set_active? return false; } } void Body3DSW::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) { - if (fi_callback) { - memdelete(fi_callback); fi_callback = nullptr; } if (p_id.is_valid()) { - fi_callback = memnew(ForceIntegrationCallback); fi_callback->id = p_id; fi_callback->method = p_method; @@ -764,11 +742,10 @@ void Body3DSW::set_kinematic_margin(real_t p_margin) { Body3DSW::Body3DSW() : CollisionObject3DSW(TYPE_BODY), - locked_axis(0), + active_list(this), inertia_update_list(this), direct_state_query_list(this) { - mode = PhysicsServer3D::BODY_MODE_RIGID; active = true; @@ -801,14 +778,13 @@ Body3DSW::Body3DSW() : } Body3DSW::~Body3DSW() { - - if (fi_callback) + if (fi_callback) { memdelete(fi_callback); + } } PhysicsDirectBodyState3DSW *PhysicsDirectBodyState3DSW::singleton = nullptr; PhysicsDirectSpaceState3D *PhysicsDirectBodyState3DSW::get_space_state() { - return body->get_space()->get_direct_state(); } diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h index 2bd335e6c0..483ea58620 100644 --- a/servers/physics_3d/body_3d_sw.h +++ b/servers/physics_3d/body_3d_sw.h @@ -38,7 +38,6 @@ class Constraint3DSW; class Body3DSW : public CollisionObject3DSW { - PhysicsServer3D::BodyMode mode; Vector3 linear_velocity; @@ -54,7 +53,7 @@ class Body3DSW : public CollisionObject3DSW { real_t angular_damp; real_t gravity_scale; - uint16_t locked_axis; + uint16_t locked_axis = 0; real_t kinematic_safe_margin; real_t _inv_mass; @@ -99,7 +98,6 @@ class Body3DSW : public CollisionObject3DSW { Map<Constraint3DSW *, int> constraint_map; struct AreaCMP { - Area3DSW *area; int refCount; _FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); } @@ -114,7 +112,6 @@ class Body3DSW : public CollisionObject3DSW { Vector<AreaCMP> areas; struct Contact { - Vector3 local_pos; Vector3 local_normal; real_t depth; @@ -130,7 +127,6 @@ class Body3DSW : public CollisionObject3DSW { int contact_count; struct ForceIntegrationCallback { - ObjectID id; StringName method; Variant udata; @@ -167,15 +163,18 @@ public: int index = areas.find(AreaCMP(p_area)); if (index > -1) { areas.write[index].refCount -= 1; - if (areas[index].refCount < 1) + if (areas[index].refCount < 1) { areas.remove(index); + } } } _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count = 0; - if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && p_size) set_active(true); + if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && p_size) { + set_active(true); + } } _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); } @@ -222,18 +221,15 @@ public: } _FORCE_INLINE_ void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) { - linear_velocity += p_j * _inv_mass; angular_velocity += _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j)); } _FORCE_INLINE_ void apply_torque_impulse(const Vector3 &p_j) { - angular_velocity += _inv_inertia_tensor.xform(p_j); } _FORCE_INLINE_ void apply_bias_impulse(const Vector3 &p_pos, const Vector3 &p_j, real_t p_max_delta_av = -1.0) { - biased_linear_velocity += p_j * _inv_mass; if (p_max_delta_av != 0.0) { Vector3 delta_av = _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j)); @@ -245,17 +241,14 @@ public: } _FORCE_INLINE_ void apply_bias_torque_impulse(const Vector3 &p_j) { - biased_angular_velocity += _inv_inertia_tensor.xform(p_j); } _FORCE_INLINE_ void add_central_force(const Vector3 &p_force) { - applied_force += p_force; } _FORCE_INLINE_ void add_force(const Vector3 &p_force, const Vector3 &p_pos) { - applied_force += p_force; applied_torque += (p_pos - center_of_mass).cross(p_force); } @@ -268,8 +261,9 @@ public: _FORCE_INLINE_ bool is_active() const { return active; } _FORCE_INLINE_ void wakeup() { - if ((!get_space()) || mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) + if ((!get_space()) || mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) { return; + } set_active(true); } @@ -309,12 +303,10 @@ public: void integrate_velocities(real_t p_step); _FORCE_INLINE_ Vector3 get_velocity_in_local_point(const Vector3 &rel_pos) const { - return linear_velocity + angular_velocity.cross(rel_pos - center_of_mass); } _FORCE_INLINE_ real_t compute_impulse_denominator(const Vector3 &p_pos, const Vector3 &p_normal) const { - Vector3 r0 = p_pos - get_transform().origin - center_of_mass; Vector3 c0 = (r0).cross(p_normal); @@ -325,7 +317,6 @@ public: } _FORCE_INLINE_ real_t compute_angular_impulse_denominator(const Vector3 &p_axis) const { - return p_axis.dot(_inv_inertia_tensor.xform_inv(p_axis)); } @@ -342,11 +333,11 @@ public: //add contact inline void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_normal, real_t p_depth, int p_local_shape, const Vector3 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector3 &p_collider_velocity_at_pos) { - int c_max = contacts.size(); - if (c_max == 0) + if (c_max == 0) { return; + } Contact *c = contacts.ptrw(); @@ -355,11 +346,9 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no if (contact_count < c_max) { idx = contact_count++; } else { - real_t least_depth = 1e20; int least_deep = -1; for (int i = 0; i < c_max; i++) { - if (i == 0 || c[i].depth < least_depth) { least_deep = i; least_depth = c[i].depth; @@ -367,11 +356,11 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no } if (least_deep >= 0 && least_depth < p_depth) { - idx = least_deep; } - if (idx == -1) + if (idx == -1) { return; //none least deepe than this + } } c[idx].local_pos = p_local_pos; @@ -386,7 +375,6 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no } class PhysicsDirectBodyState3DSW : public PhysicsDirectBodyState3D { - GDCLASS(PhysicsDirectBodyState3DSW, PhysicsDirectBodyState3D); public: diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/body_pair_3d_sw.cpp index 245fb3449c..a4f86badbe 100644 --- a/servers/physics_3d/body_pair_3d_sw.cpp +++ b/servers/physics_3d/body_pair_3d_sw.cpp @@ -50,13 +50,11 @@ #define MAX_BIAS_ROTATION (Math_PI / 8) void BodyPair3DSW::_contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { - BodyPair3DSW *pair = (BodyPair3DSW *)p_userdata; pair->contact_added_callback(p_point_A, p_point_B); } void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B) { - // check if we already have the contact //Vector3 local_A = A->get_inv_transform().xform(p_point_A); @@ -84,11 +82,9 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector real_t contact_recycle_radius = space->get_contact_recycle_radius(); for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; if (c.local_A.distance_squared_to(local_A) < (contact_recycle_radius * contact_recycle_radius) && c.local_B.distance_squared_to(local_B) < (contact_recycle_radius * contact_recycle_radius)) { - contact.acc_normal_impulse = c.acc_normal_impulse; contact.acc_bias_impulse = c.acc_bias_impulse; contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass; @@ -101,14 +97,12 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector // figure out if the contact amount must be reduced to fit the new contact if (new_index == MAX_CONTACTS) { - // remove the contact with the minimum depth int least_deep = -1; real_t min_depth = 1e10; for (int i = 0; i <= contact_count; i++) { - Contact &c = (i == contact_count) ? contact : contacts[i]; Vector3 global_A = A->get_transform().basis.xform(c.local_A); Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B; @@ -117,7 +111,6 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector real_t depth = axis.dot(c.normal); if (depth < min_depth) { - min_depth = depth; least_deep = i; } @@ -136,18 +129,15 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector contacts[new_index] = contact; if (new_index == contact_count) { - contact_count++; } } void BodyPair3DSW::validate_contacts() { - //make sure to erase contacts that are no longer valid real_t contact_max_separation = space->get_contact_max_separation(); for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; Vector3 global_A = A->get_transform().basis.xform(c.local_A); @@ -170,11 +160,11 @@ void BodyPair3DSW::validate_contacts() { } bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform &p_xform_B) { - Vector3 motion = p_A->get_linear_velocity() * p_step; real_t mlen = motion.length(); - if (mlen < CMP_EPSILON) + if (mlen < CMP_EPSILON) { return false; + } Vector3 mnormal = motion / mlen; @@ -220,7 +210,6 @@ real_t combine_friction(Body3DSW *A, Body3DSW *B) { } bool BodyPair3DSW::setup(real_t p_step) { - //cannot collide if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC && A->get_max_contacts_reported() == 0 && B->get_max_contacts_reported() == 0)) { collided = false; @@ -251,7 +240,6 @@ bool BodyPair3DSW::setup(real_t p_step) { this->collided = collided; if (!collided) { - //test ccd (currently just a raycast) if (A->is_continuous_collision_detection_enabled() && A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC) { @@ -270,19 +258,18 @@ bool BodyPair3DSW::setup(real_t p_step) { real_t bias = (real_t)0.3; if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) { - - if (shape_A_ptr->get_custom_bias() == 0) + if (shape_A_ptr->get_custom_bias() == 0) { bias = shape_B_ptr->get_custom_bias(); - else if (shape_B_ptr->get_custom_bias() == 0) + } else if (shape_B_ptr->get_custom_bias() == 0) { bias = shape_A_ptr->get_custom_bias(); - else + } else { bias = (shape_B_ptr->get_custom_bias() + shape_A_ptr->get_custom_bias()) * 0.5; + } } real_t inv_dt = 1.0 / p_step; for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; c.active = false; @@ -341,7 +328,6 @@ bool BodyPair3DSW::setup(real_t p_step) { c.bounce = combine_bounce(A, B); if (c.bounce) { - Vector3 crA = A->get_angular_velocity().cross(c.rA); Vector3 crB = B->get_angular_velocity().cross(c.rB); Vector3 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA; @@ -354,15 +340,15 @@ bool BodyPair3DSW::setup(real_t p_step) { } void BodyPair3DSW::solve(real_t p_step) { - - if (!collided) + if (!collided) { return; + } for (int i = 0; i < contact_count; i++) { - Contact &c = contacts[i]; - if (!c.active) + if (!c.active) { continue; + } c.active = false; //try to deactivate, will activate itself if still needed @@ -375,7 +361,6 @@ void BodyPair3DSW::solve(real_t p_step) { real_t vbn = dbv.dot(c.normal); if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) { - real_t jbn = (-vbn + c.bias) * c.mass_normal; real_t jbnOld = c.acc_bias_impulse; c.acc_bias_impulse = MAX(jbnOld + jbn, 0.0f); @@ -392,7 +377,6 @@ void BodyPair3DSW::solve(real_t p_step) { vbn = dbv.dot(c.normal); if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) { - real_t jbn_com = (-vbn + c.bias) / (A->get_inv_mass() + B->get_inv_mass()); real_t jbnOld_com = c.acc_bias_impulse_center_of_mass; c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f); @@ -414,7 +398,6 @@ void BodyPair3DSW::solve(real_t p_step) { real_t vn = dv.dot(c.normal); if (Math::abs(vn) > MIN_VELOCITY) { - real_t jn = -(c.bounce + vn) * c.mass_normal; real_t jnOld = c.acc_normal_impulse; c.acc_normal_impulse = MAX(jnOld + jn, 0.0f); @@ -442,7 +425,6 @@ void BodyPair3DSW::solve(real_t p_step) { real_t tvl = tv.length(); if (tvl > MIN_VELOCITY) { - tv /= tvl; Vector3 temp1 = A->get_inv_inertia_tensor().xform(c.rA.cross(tv)); @@ -460,7 +442,6 @@ void BodyPair3DSW::solve(real_t p_step) { real_t jtMax = c.acc_normal_impulse * friction; if (fi_len > CMP_EPSILON && fi_len > jtMax) { - c.acc_tangent_impulse *= jtMax / fi_len; } @@ -476,7 +457,6 @@ void BodyPair3DSW::solve(real_t p_step) { BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_shape_B) : Constraint3DSW(_arr, 2) { - A = p_A; B = p_B; shape_A = p_shape_A; @@ -489,7 +469,6 @@ BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_sh } BodyPair3DSW::~BodyPair3DSW() { - A->remove_constraint(this); B->remove_constraint(this); } diff --git a/servers/physics_3d/body_pair_3d_sw.h b/servers/physics_3d/body_pair_3d_sw.h index 7f4afb9dca..59e36e7ea5 100644 --- a/servers/physics_3d/body_pair_3d_sw.h +++ b/servers/physics_3d/body_pair_3d_sw.h @@ -53,7 +53,6 @@ class BodyPair3DSW : public Constraint3DSW { int shape_B; struct Contact { - Vector3 position; Vector3 normal; Vector3 local_A, local_B; diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp index 08ea219869..f5ea1897a9 100644 --- a/servers/physics_3d/broad_phase_3d_basic.cpp +++ b/servers/physics_3d/broad_phase_3d_basic.cpp @@ -33,7 +33,6 @@ #include "core/print_string.h" BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int p_subindex) { - ERR_FAIL_COND_V(p_object == nullptr, 0); current++; @@ -48,27 +47,24 @@ BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int } void BroadPhase3DBasic::move(ID p_id, const AABB &p_aabb) { - Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); E->get().aabb = p_aabb; } -void BroadPhase3DBasic::set_static(ID p_id, bool p_static) { +void BroadPhase3DBasic::set_static(ID p_id, bool p_static) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); E->get()._static = p_static; } -void BroadPhase3DBasic::remove(ID p_id) { +void BroadPhase3DBasic::remove(ID p_id) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); List<PairKey> to_erase; //unpair must be done immediately on removal to avoid potential invalid pointers for (Map<PairKey, void *>::Element *F = pair_map.front(); F; F = F->next()) { - if (F->key().a == p_id || F->key().b == p_id) { - if (unpair_callback) { Element *elem_A = &element_map[F->key().a]; Element *elem_B = &element_map[F->key().b]; @@ -78,7 +74,6 @@ void BroadPhase3DBasic::remove(ID p_id) { } } while (to_erase.size()) { - pair_map.erase(to_erase.front()->get()); to_erase.pop_front(); } @@ -86,38 +81,35 @@ void BroadPhase3DBasic::remove(ID p_id) { } CollisionObject3DSW *BroadPhase3DBasic::get_object(ID p_id) const { - const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, nullptr); return E->get().owner; } -bool BroadPhase3DBasic::is_static(ID p_id) const { +bool BroadPhase3DBasic::is_static(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, false); return E->get()._static; } -int BroadPhase3DBasic::get_subindex(ID p_id) const { +int BroadPhase3DBasic::get_subindex(ID p_id) const { const Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND_V(!E, -1); return E->get().subindex; } int BroadPhase3DBasic::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; if (aabb.has_point(p_point)) { - p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; - if (rc >= p_max_results) + if (rc >= p_max_results) { break; + } } } @@ -125,38 +117,35 @@ int BroadPhase3DBasic::cull_point(const Vector3 &p_point, CollisionObject3DSW ** } int BroadPhase3DBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; if (aabb.intersects_segment(p_from, p_to)) { - p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; - if (rc >= p_max_results) + if (rc >= p_max_results) { break; + } } } return rc; } -int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const AABB aabb = E->get().aabb; if (aabb.intersects(p_aabb)) { - p_results[rc] = E->get().owner; p_result_indices[rc] = E->get().subindex; rc++; - if (rc >= p_max_results) + if (rc >= p_max_results) { break; + } } } @@ -164,28 +153,25 @@ int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_res } void BroadPhase3DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_userdata = p_userdata; pair_callback = p_pair_callback; } -void BroadPhase3DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void BroadPhase3DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_userdata = p_userdata; unpair_callback = p_unpair_callback; } void BroadPhase3DBasic::update() { - // recompute pairs for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) { - for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) { - Element *elem_A = &I->get(); Element *elem_B = &J->get(); - if (elem_A->owner == elem_B->owner) + if (elem_A->owner == elem_B->owner) { continue; + } bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static); @@ -194,29 +180,30 @@ void BroadPhase3DBasic::update() { Map<PairKey, void *>::Element *E = pair_map.find(key); if (!pair_ok && E) { - if (unpair_callback) + if (unpair_callback) { unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata); + } pair_map.erase(key); } if (pair_ok && !E) { - void *data = nullptr; - if (pair_callback) + if (pair_callback) { data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata); - pair_map.insert(key, data); + if (data) { + pair_map.insert(key, data); + } + } } } } } BroadPhase3DSW *BroadPhase3DBasic::_create() { - return memnew(BroadPhase3DBasic); } BroadPhase3DBasic::BroadPhase3DBasic() { - current = 1; unpair_callback = nullptr; unpair_userdata = nullptr; diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/servers/physics_3d/broad_phase_3d_basic.h index 563dda6931..4b644bf818 100644 --- a/servers/physics_3d/broad_phase_3d_basic.h +++ b/servers/physics_3d/broad_phase_3d_basic.h @@ -35,9 +35,7 @@ #include "core/map.h" class BroadPhase3DBasic : public BroadPhase3DSW { - struct Element { - CollisionObject3DSW *owner; bool _static; AABB aabb; @@ -49,7 +47,6 @@ class BroadPhase3DBasic : public BroadPhase3DSW { ID current; struct PairKey { - union { struct { ID a; diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/broad_phase_3d_sw.h index 5950489619..081e75810f 100644 --- a/servers/physics_3d/broad_phase_3d_sw.h +++ b/servers/physics_3d/broad_phase_3d_sw.h @@ -37,7 +37,6 @@ class CollisionObject3DSW; class BroadPhase3DSW { - public: typedef BroadPhase3DSW *(*CreateFunction)(); diff --git a/servers/physics_3d/broad_phase_octree.cpp b/servers/physics_3d/broad_phase_octree.cpp index 264ab21e1e..1ace1a4fcf 100644 --- a/servers/physics_3d/broad_phase_octree.cpp +++ b/servers/physics_3d/broad_phase_octree.cpp @@ -32,81 +32,73 @@ #include "collision_object_3d_sw.h" BroadPhase3DSW::ID BroadPhaseOctree::create(CollisionObject3DSW *p_object, int p_subindex) { - ID oid = octree.create(p_object, AABB(), p_subindex, false, 1 << p_object->get_type(), 0); return oid; } void BroadPhaseOctree::move(ID p_id, const AABB &p_aabb) { - octree.move(p_id, p_aabb); } void BroadPhaseOctree::set_static(ID p_id, bool p_static) { - CollisionObject3DSW *it = octree.get(p_id); octree.set_pairable(p_id, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF); //pair everything, don't care 1? } -void BroadPhaseOctree::remove(ID p_id) { +void BroadPhaseOctree::remove(ID p_id) { octree.erase(p_id); } CollisionObject3DSW *BroadPhaseOctree::get_object(ID p_id) const { - CollisionObject3DSW *it = octree.get(p_id); ERR_FAIL_COND_V(!it, nullptr); return it; } -bool BroadPhaseOctree::is_static(ID p_id) const { +bool BroadPhaseOctree::is_static(ID p_id) const { return !octree.is_pairable(p_id); } -int BroadPhaseOctree::get_subindex(ID p_id) const { +int BroadPhaseOctree::get_subindex(ID p_id) const { return octree.get_subindex(p_id); } int BroadPhaseOctree::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_point(p_point, p_results, p_max_results, p_result_indices); } int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } int BroadPhaseOctree::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) { - return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B) { - BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self); - if (!bpo->pair_callback) + if (!bpo->pair_callback) { return nullptr; + } return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata); } void BroadPhaseOctree::_unpair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B, void *pairdata) { - BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self); - if (!bpo->unpair_callback) + if (!bpo->unpair_callback) { return; + } bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata); } void BroadPhaseOctree::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) { - pair_callback = p_pair_callback; pair_userdata = p_userdata; } -void BroadPhaseOctree::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { +void BroadPhaseOctree::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) { unpair_callback = p_unpair_callback; unpair_userdata = p_userdata; } @@ -116,7 +108,6 @@ void BroadPhaseOctree::update() { } BroadPhase3DSW *BroadPhaseOctree::_create() { - return memnew(BroadPhaseOctree); } diff --git a/servers/physics_3d/broad_phase_octree.h b/servers/physics_3d/broad_phase_octree.h index 0ad59d8b0c..761a90a051 100644 --- a/servers/physics_3d/broad_phase_octree.h +++ b/servers/physics_3d/broad_phase_octree.h @@ -35,7 +35,6 @@ #include "core/math/octree.h" class BroadPhaseOctree : public BroadPhase3DSW { - Octree<CollisionObject3DSW, true> octree; static void *_pair_callback(void *, OctreeElementID, CollisionObject3DSW *, int, OctreeElementID, CollisionObject3DSW *, int); diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp index 24715d211d..e12f0659e2 100644 --- a/servers/physics_3d/collision_object_3d_sw.cpp +++ b/servers/physics_3d/collision_object_3d_sw.cpp @@ -33,7 +33,6 @@ #include "space_3d_sw.h" void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_transform, bool p_disabled) { - Shape s; s.shape = p_shape; s.xform = p_transform; @@ -51,7 +50,6 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_trans } void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { - ERR_FAIL_INDEX(p_index, shapes.size()); shapes[p_index].shape->remove_owner(this); shapes.write[p_index].shape = p_shape; @@ -63,8 +61,8 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) { //_update_shapes(); //_shapes_changed(); } -void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_transform) { +void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes.write[p_index].xform = p_transform; @@ -84,10 +82,8 @@ void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) { } void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) { - //remove a shape, all the times it appears for (int i = 0; i < shapes.size(); i++) { - if (shapes[i].shape == p_shape) { remove_shape(i); i--; @@ -96,13 +92,12 @@ void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) { } void CollisionObject3DSW::remove_shape(int p_index) { - //remove anything from shape to be erased to end, so subindices don't change ERR_FAIL_INDEX(p_index, shapes.size()); for (int i = p_index; i < shapes.size(); i++) { - - if (shapes[i].bpid == 0) + if (shapes[i].bpid == 0) { continue; + } //should never get here with a null owner space->get_broadphase()->remove(shapes[i].bpid); shapes.write[i].bpid = 0; @@ -118,12 +113,14 @@ void CollisionObject3DSW::remove_shape(int p_index) { } void CollisionObject3DSW::_set_static(bool p_static) { - if (_static == p_static) + if (_static == p_static) { return; + } _static = p_static; - if (!space) + if (!space) { return; + } for (int i = 0; i < get_shape_count(); i++) { const Shape &s = shapes[i]; if (s.bpid > 0) { @@ -133,9 +130,7 @@ void CollisionObject3DSW::_set_static(bool p_static) { } void CollisionObject3DSW::_unregister_shapes() { - for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid > 0) { space->get_broadphase()->remove(s.bpid); @@ -145,12 +140,11 @@ void CollisionObject3DSW::_unregister_shapes() { } void CollisionObject3DSW::_update_shapes() { - - if (!space) + if (!space) { return; + } for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid == 0) { s.bpid = space->get_broadphase()->create(this, i); @@ -172,12 +166,11 @@ void CollisionObject3DSW::_update_shapes() { } void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { - - if (!space) + if (!space) { return; + } for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid == 0) { s.bpid = space->get_broadphase()->create(this, i); @@ -196,13 +189,10 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) { } void CollisionObject3DSW::_set_space(Space3DSW *p_space) { - if (space) { - space->remove_object(this); for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes.write[i]; if (s.bpid) { space->get_broadphase()->remove(s.bpid); @@ -214,21 +204,18 @@ void CollisionObject3DSW::_set_space(Space3DSW *p_space) { space = p_space; if (space) { - space->add_object(this); _update_shapes(); } } void CollisionObject3DSW::_shape_changed() { - _update_shapes(); _shapes_changed(); } CollisionObject3DSW::CollisionObject3DSW(Type p_type) : pending_shape_update_list(this) { - _static = true; type = p_type; space = nullptr; diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h index c5773d0c61..9506f14402 100644 --- a/servers/physics_3d/collision_object_3d_sw.h +++ b/servers/physics_3d/collision_object_3d_sw.h @@ -59,7 +59,6 @@ private: uint32_t collision_mask; struct Shape { - Transform xform; Transform xform_inv; BroadPhase3DSW::ID bpid; @@ -92,7 +91,9 @@ protected: #endif transform = p_transform; - if (p_update_shapes) _update_shapes(); + if (p_update_shapes) { + _update_shapes(); + } } _FORCE_INLINE_ void _set_inv_transform(const Transform &p_transform) { inv_transform = p_transform; } void _set_static(bool p_static); diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp index 5096b080ab..85f55ad66d 100644 --- a/servers/physics_3d/collision_solver_3d_sat.cpp +++ b/servers/physics_3d/collision_solver_3d_sat.cpp @@ -29,12 +29,11 @@ /*************************************************************************/ #include "collision_solver_3d_sat.h" -#include "core/math/geometry.h" +#include "core/math/geometry_3d.h" #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02 struct _CollectorCallback { - CollisionSolver3DSW::CallbackResult callback; void *userdata; bool swap; @@ -43,18 +42,17 @@ struct _CollectorCallback { Vector3 *prev_axis; _FORCE_INLINE_ void call(const Vector3 &p_point_A, const Vector3 &p_point_B) { - - if (swap) + if (swap) { callback(p_point_B, p_point_A, userdata); - else + } else { callback(p_point_A, p_point_B, userdata); + } } }; typedef void (*GenerateContactsFunc)(const Vector3 *, int, const Vector3 *, int, _CollectorCallback *); static void _generate_contacts_point_point(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 1); ERR_FAIL_COND(p_point_count_B != 1); @@ -64,18 +62,16 @@ static void _generate_contacts_point_point(const Vector3 *p_points_A, int p_poin } static void _generate_contacts_point_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 1); ERR_FAIL_COND(p_point_count_B != 2); #endif - Vector3 closest_B = Geometry::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B); + Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(*p_points_A, p_points_B); p_callback->call(*p_points_A, closest_B); } static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 1); ERR_FAIL_COND(p_point_count_B < 3); @@ -87,7 +83,6 @@ static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point } static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A != 2); ERR_FAIL_COND(p_point_count_B != 2); // circle is actually a 4x3 matrix @@ -99,7 +94,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::is_zero_approx(rel_A.dot(c))) { - // should handle somehow.. //ERR_PRINT("TODO FIX"); //return; @@ -123,18 +117,18 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ real_t d = (c.dot(p_points_B[0]) - p_points_A[0].dot(c)) / rel_A.dot(c); - if (d < 0.0) + if (d < 0.0) { d = 0.0; - else if (d > 1.0) + } else if (d > 1.0) { d = 1.0; + } Vector3 closest_A = p_points_A[0] + rel_A * d; - Vector3 closest_B = Geometry::get_closest_point_to_segment_uncapped(closest_A, p_points_B); + Vector3 closest_B = Geometry3D::get_closest_point_to_segment_uncapped(closest_A, p_points_B); p_callback->call(closest_A, closest_B); } static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 2); ERR_FAIL_COND(p_point_count_B < 3); @@ -150,7 +144,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ // copy A points to clipbuf_src for (int i = 0; i < p_point_count_A; i++) { - clipbuf_src[i] = p_points_A[i]; } @@ -158,7 +151,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ // go through all of B points for (int i = 0; i < p_point_count_B; i++) { - int i_n = (i + 1) % p_point_count_B; Vector3 edge0_B = p_points_B[i]; @@ -172,7 +164,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ int dst_idx = 0; bool edge = clipbuf_len == 2; for (int j = 0; j < clipbuf_len; j++) { - int j_n = (j + 1) % clipbuf_len; Vector3 edge0_A = clipbuf_src[j]; @@ -190,7 +181,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ // check for different sides and non coplanar //if ( (dist0*dist1) < -CMP_EPSILON && !(edge && j)) { if ((dist0 * dist1) < 0 && !(edge && j)) { - // calculate intersection Vector3 rel = edge1_A - edge0_A; real_t den = clip.normal.dot(rel); @@ -211,7 +201,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ //Plane plane_A(p_points_A[0],p_points_A[1],p_points_A[2]); for (int i = 0; i < clipbuf_len; i++) { - real_t d = plane_B.distance_to(clipbuf_src[i]); /* if (d>CMP_EPSILON) @@ -220,15 +209,15 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ Vector3 closest_B = clipbuf_src[i] - plane_B.normal * d; - if (p_callback->normal.dot(clipbuf_src[i]) >= p_callback->normal.dot(closest_B)) + if (p_callback->normal.dot(clipbuf_src[i]) >= p_callback->normal.dot(closest_B)) { continue; + } p_callback->call(clipbuf_src[i], closest_B); } } static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) { - #ifdef DEBUG_ENABLED ERR_FAIL_COND(p_point_count_A < 1); ERR_FAIL_COND(p_point_count_B < 1); @@ -267,7 +256,6 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po points_A = p_points_B; points_B = p_points_A; } else { - pointcount_B = p_point_count_B; pointcount_A = p_point_count_A; points_A = p_points_A; @@ -284,7 +272,6 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po template <class ShapeA, class ShapeB, bool withMargin = false> class SeparatorAxisTest { - const ShapeA *shape_A; const ShapeB *shape_B; const Transform *transform_A; @@ -298,15 +285,14 @@ class SeparatorAxisTest { public: _FORCE_INLINE_ bool test_previous_axis() { - - if (callback && callback->prev_axis && *callback->prev_axis != Vector3()) + if (callback && callback->prev_axis && *callback->prev_axis != Vector3()) { return test_axis(*callback->prev_axis); - else + } else { return true; + } } _FORCE_INLINE_ bool test_axis(const Vector3 &p_axis) { - Vector3 axis = p_axis; if (Math::abs(axis.x) < CMP_EPSILON && @@ -361,16 +347,17 @@ public: } _FORCE_INLINE_ void generate_contacts() { - // nothing to do, don't generate - if (best_axis == Vector3(0.0, 0.0, 0.0)) + if (best_axis == Vector3(0.0, 0.0, 0.0)) { return; + } if (!callback->callback) { //just was checking intersection? callback->collided = true; - if (callback->prev_axis) + if (callback->prev_axis) { *callback->prev_axis = best_axis; + } return; } @@ -384,7 +371,6 @@ public: } if (withMargin) { - for (int i = 0; i < support_count_A; i++) { supports_A[i] += -best_axis * margin_A; } @@ -398,15 +384,15 @@ public: } if (withMargin) { - for (int i = 0; i < support_count_B; i++) { supports_B[i] += best_axis * margin_B; } } callback->normal = best_axis; - if (callback->prev_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; @@ -430,7 +416,6 @@ typedef void (*CollisionFunc)(const Shape3DSW *, const Transform &, const Shape3 template <bool withMargin> static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const SphereShape3DSW *sphere_B = static_cast<const SphereShape3DSW *>(p_b); @@ -438,34 +423,36 @@ static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_tr // previous axis - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - if (!separator.test_axis((p_transform_a.origin - p_transform_b.origin).normalized())) + if (!separator.test_axis((p_transform_a.origin - p_transform_b.origin).normalized())) { return; + } separator.generate_contacts(); } template <bool withMargin> static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); SeparatorAxisTest<SphereShape3DSW, BoxShape3DSW, withMargin> separator(sphere_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } // test faces for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_b.basis.get_axis(i).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // calculate closest point to sphere @@ -481,17 +468,18 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_trans // use point to test axis Vector3 point_axis = (p_transform_a.origin - cpoint).normalized(); - if (!separator.test_axis(point_axis)) + if (!separator.test_axis(point_axis)) { return; + } // test edges for (int i = 0; i < 3; i++) { - Vector3 axis = point_axis.cross(p_transform_b.basis.get_axis(i)).cross(p_transform_b.basis.get_axis(i)).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } separator.generate_contacts(); @@ -499,14 +487,14 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_trans template <bool withMargin> static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); SeparatorAxisTest<SphereShape3DSW, CapsuleShape3DSW, withMargin> separator(sphere_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } //capsule sphere 1, sphere @@ -514,15 +502,17 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t Vector3 capsule_ball_1 = p_transform_b.origin + capsule_axis; - if (!separator.test_axis((capsule_ball_1 - p_transform_a.origin).normalized())) + if (!separator.test_axis((capsule_ball_1 - p_transform_a.origin).normalized())) { return; + } //capsule sphere 2, sphere Vector3 capsule_ball_2 = p_transform_b.origin - capsule_axis; - if (!separator.test_axis((capsule_ball_2 - p_transform_a.origin).normalized())) + if (!separator.test_axis((capsule_ball_2 - p_transform_a.origin).normalized())) { return; + } //capsule edge, sphere @@ -530,8 +520,9 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t Vector3 axis = b2a.cross(capsule_axis).cross(capsule_axis).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } separator.generate_contacts(); } @@ -542,36 +533,35 @@ static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_ template <bool withMargin> static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); SeparatorAxisTest<SphereShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(sphere_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - const Geometry::MeshData &mesh = convex_polygon_B->get_mesh(); + const Geometry3D::MeshData &mesh = convex_polygon_B->get_mesh(); - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int face_count = mesh.faces.size(); - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int edge_count = mesh.edges.size(); const Vector3 *vertices = mesh.vertices.ptr(); int vertex_count = mesh.vertices.size(); // faces of B for (int i = 0; i < face_count; i++) { - Vector3 axis = p_transform_b.xform(faces[i].plane).normal; - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // edges of B for (int i = 0; i < edge_count; i++) { - Vector3 v1 = p_transform_b.xform(vertices[edges[i].a]); Vector3 v2 = p_transform_b.xform(vertices[edges[i].b]); Vector3 v3 = p_transform_a.origin; @@ -581,20 +571,21 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo Vector3 axis = n1.cross(n2).cross(n1).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // vertices of B for (int i = 0; i < vertex_count; i++) { - Vector3 v1 = p_transform_b.xform(vertices[i]); Vector3 v2 = p_transform_a.origin; Vector3 axis = (v2 - v1).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } separator.generate_contacts(); @@ -602,7 +593,6 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo template <bool withMargin> static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -614,12 +604,12 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_tran p_transform_b.xform(face_B->vertex[2]), }; - if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { return; + } // edges and points of B for (int i = 0; i < 3; i++) { - Vector3 n1 = vertex[i] - p_transform_a.origin; if (!separator.test_axis(n1.normalized())) { @@ -640,44 +630,43 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_tran template <bool withMargin> static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b); SeparatorAxisTest<BoxShape3DSW, BoxShape3DSW, withMargin> separator(box_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } // test faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // test faces of B for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_b.basis.get_axis(i).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // test combined edges for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - Vector3 axis = p_transform_a.basis.get_axis(i).cross(p_transform_b.basis.get_axis(j)); - if (Math::is_zero_approx(axis.length_squared())) + if (Math::is_zero_approx(axis.length_squared())) { continue; + } axis.normalize(); if (!separator.test_axis(axis)) { @@ -718,18 +707,19 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transfor //now try edges, which become cylinders! for (int i = 0; i < 3; i++) { - //a ->b Vector3 axis_a = p_transform_a.basis.get_axis(i); - if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) + if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) { return; + } //b ->a Vector3 axis_b = p_transform_b.basis.get_axis(i); - if (!separator.test_axis(axis_ab.cross(axis_b).cross(axis_b).normalized())) + if (!separator.test_axis(axis_ab.cross(axis_b).cross(axis_b).normalized())) { return; + } } } @@ -738,22 +728,22 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transfor template <bool withMargin> static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); SeparatorAxisTest<BoxShape3DSW, CapsuleShape3DSW, withMargin> separator(box_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } // faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } Vector3 cyl_axis = p_transform_b.basis.get_axis(2).normalized(); @@ -761,15 +751,16 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran // edges of A, capsule cylinder for (int i = 0; i < 3; i++) { - // cylinder Vector3 box_axis = p_transform_a.basis.get_axis(i); Vector3 axis = box_axis.cross(cyl_axis); - if (Math::is_zero_approx(axis.length_squared())) + if (Math::is_zero_approx(axis.length_squared())) { continue; + } - if (!separator.test_axis(axis.normalized())) + if (!separator.test_axis(axis.normalized())) { return; + } } // points of A, capsule cylinder @@ -783,14 +774,16 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran he.y *= (j * 2 - 1); he.z *= (k * 2 - 1); Vector3 point = p_transform_a.origin; - for (int l = 0; l < 3; l++) + for (int l = 0; l < 3; l++) { point += p_transform_a.basis.get_axis(l) * he[l]; + } //Vector3 axis = (point - cyl_axis * cyl_axis.dot(point)).normalized(); Vector3 axis = Plane(cyl_axis, 0).project(point).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } } @@ -798,7 +791,6 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran // capsule balls, edges of A for (int i = 0; i < 2; i++) { - Vector3 capsule_axis = p_transform_b.basis.get_axis(2) * (capsule_B->get_height() * 0.5); Vector3 sphere_pos = p_transform_b.origin + ((i == 0) ? capsule_axis : -capsule_axis); @@ -814,17 +806,18 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran // use point to test axis Vector3 point_axis = (sphere_pos - cpoint).normalized(); - if (!separator.test_axis(point_axis)) + if (!separator.test_axis(point_axis)) { return; + } // test edges of A for (int j = 0; j < 3; j++) { - Vector3 axis = point_axis.cross(p_transform_a.basis.get_axis(j)).cross(p_transform_a.basis.get_axis(j)).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } @@ -837,63 +830,60 @@ static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_tra template <bool withMargin> static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); SeparatorAxisTest<BoxShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(box_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - const Geometry::MeshData &mesh = convex_polygon_B->get_mesh(); + const Geometry3D::MeshData &mesh = convex_polygon_B->get_mesh(); - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int face_count = mesh.faces.size(); - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int edge_count = mesh.edges.size(); const Vector3 *vertices = mesh.vertices.ptr(); int vertex_count = mesh.vertices.size(); // faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // faces of B for (int i = 0; i < face_count; i++) { - Vector3 axis = p_transform_b.xform(faces[i].plane).normal; - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // A<->B edges for (int i = 0; i < 3; i++) { - Vector3 e1 = p_transform_a.basis.get_axis(i); for (int j = 0; j < edge_count; j++) { - Vector3 e2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]); Vector3 axis = e1.cross(e2).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } if (withMargin) { - // calculate closest points between vertices and box edges for (int v = 0; v < vertex_count; v++) { - Vector3 vtxb = p_transform_b.xform(vertices[v]); Vector3 ab_vec = vtxb - p_transform_a.origin; @@ -914,12 +904,12 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform //now try edges, which become cylinders! for (int i = 0; i < 3; i++) { - //a ->b Vector3 axis_a = p_transform_a.basis.get_axis(i); - if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) + if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) { return; + } } } @@ -932,17 +922,18 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform he.y *= (j * 2 - 1); he.z *= (k * 2 - 1); Vector3 point = p_transform_a.origin; - for (int l = 0; l < 3; l++) + for (int l = 0; l < 3; l++) { point += p_transform_a.basis.get_axis(l) * he[l]; + } for (int e = 0; e < edge_count; e++) { - Vector3 p1 = p_transform_b.xform(vertices[edges[e].a]); Vector3 p2 = p_transform_b.xform(vertices[edges[e].b]); Vector3 n = (p2 - p1); - if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) + if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) { return; + } } } } @@ -954,7 +945,6 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform template <bool withMargin> static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -966,38 +956,36 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo p_transform_b.xform(face_B->vertex[2]), }; - if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { return; + } // faces of A for (int i = 0; i < 3; i++) { - Vector3 axis = p_transform_a.basis.get_axis(i).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // combined edges for (int i = 0; i < 3; i++) { - Vector3 e = vertex[i] - vertex[(i + 1) % 3]; for (int j = 0; j < 3; j++) { - Vector3 axis = p_transform_a.basis.get_axis(j); - if (!separator.test_axis(e.cross(axis).normalized())) + if (!separator.test_axis(e.cross(axis).normalized())) { return; + } } } if (withMargin) { - // calculate closest points between vertices and box edges for (int v = 0; v < 3; v++) { - Vector3 ab_vec = vertex[v] - p_transform_a.origin; Vector3 cnormal_a = p_transform_a.basis.xform_inv(ab_vec); @@ -1017,12 +1005,12 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo //now try edges, which become cylinders! for (int i = 0; i < 3; i++) { - //a ->b Vector3 axis_a = p_transform_a.basis.get_axis(i); - if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) + if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) { return; + } } } @@ -1035,18 +1023,19 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo he.y *= (j * 2 - 1); he.z *= (k * 2 - 1); Vector3 point = p_transform_a.origin; - for (int l = 0; l < 3; l++) + for (int l = 0; l < 3; l++) { point += p_transform_a.basis.get_axis(l) * he[l]; + } for (int e = 0; e < 3; e++) { - Vector3 p1 = vertex[e]; Vector3 p2 = vertex[(e + 1) % 3]; Vector3 n = (p2 - p1); - if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) + if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) { return; + } } } } @@ -1058,14 +1047,14 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo template <bool withMargin> static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b); SeparatorAxisTest<CapsuleShape3DSW, CapsuleShape3DSW, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } // some values @@ -1079,34 +1068,43 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_ //balls-balls - if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).normalized())) + if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).normalized())) { return; - if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).normalized())) + } + if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).normalized())) { return; + } - if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_1).normalized())) + if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_1).normalized())) { return; - if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_2).normalized())) + } + if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_2).normalized())) { return; + } // edges-balls - if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) + if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) { return; + } - if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) + if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) { return; + } - if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_1).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) + if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_1).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) { return; + } - if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_2).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) + if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_2).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) { return; + } // edges - if (!separator.test_axis(capsule_A_axis.cross(capsule_B_axis).normalized())) + if (!separator.test_axis(capsule_A_axis.cross(capsule_B_axis).normalized())) { return; + } separator.generate_contacts(); } @@ -1117,48 +1115,47 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p template <bool withMargin> static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); SeparatorAxisTest<CapsuleShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(capsule_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - const Geometry::MeshData &mesh = convex_polygon_B->get_mesh(); + const Geometry3D::MeshData &mesh = convex_polygon_B->get_mesh(); - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int face_count = mesh.faces.size(); - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int edge_count = mesh.edges.size(); const Vector3 *vertices = mesh.vertices.ptr(); // faces of B for (int i = 0; i < face_count; i++) { - Vector3 axis = p_transform_b.xform(faces[i].plane).normal; - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // edges of B, capsule cylinder for (int i = 0; i < edge_count; i++) { - // cylinder Vector3 edge_axis = p_transform_b.basis.xform(vertices[edges[i].a]) - p_transform_b.basis.xform(vertices[edges[i].b]); Vector3 axis = edge_axis.cross(p_transform_a.basis.get_axis(2)).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // capsule balls, edges of B for (int i = 0; i < 2; i++) { - // edges of B, capsule cylinder Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5); @@ -1166,14 +1163,14 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf Vector3 sphere_pos = p_transform_a.origin + ((i == 0) ? capsule_axis : -capsule_axis); for (int j = 0; j < edge_count; j++) { - Vector3 n1 = sphere_pos - p_transform_b.xform(vertices[edges[j].a]); Vector3 n2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]); Vector3 axis = n1.cross(n2).cross(n2).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } @@ -1182,7 +1179,6 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf template <bool withMargin> static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); @@ -1194,41 +1190,44 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra p_transform_b.xform(face_B->vertex[2]), }; - if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { return; + } // edges of B, capsule cylinder Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5); for (int i = 0; i < 3; i++) { - // edge-cylinder Vector3 edge_axis = vertex[i] - vertex[(i + 1) % 3]; Vector3 axis = edge_axis.cross(capsule_axis).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } - if (!separator.test_axis((p_transform_a.origin - vertex[i]).cross(capsule_axis).cross(capsule_axis).normalized())) + if (!separator.test_axis((p_transform_a.origin - vertex[i]).cross(capsule_axis).cross(capsule_axis).normalized())) { return; + } for (int j = 0; j < 2; j++) { - // point-spheres Vector3 sphere_pos = p_transform_a.origin + ((j == 0) ? capsule_axis : -capsule_axis); Vector3 n1 = sphere_pos - vertex[i]; - if (!separator.test_axis(n1.normalized())) + if (!separator.test_axis(n1.normalized())) { return; + } Vector3 n2 = edge_axis; axis = n1.cross(n2).cross(n2); - if (!separator.test_axis(axis.normalized())) + if (!separator.test_axis(axis.normalized())) { return; + } } } @@ -1249,111 +1248,106 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_tr template <bool withMargin> static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b); SeparatorAxisTest<ConvexPolygonShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(convex_polygon_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - if (!separator.test_previous_axis()) + if (!separator.test_previous_axis()) { return; + } - const Geometry::MeshData &mesh_A = convex_polygon_A->get_mesh(); + const Geometry3D::MeshData &mesh_A = convex_polygon_A->get_mesh(); - const Geometry::MeshData::Face *faces_A = mesh_A.faces.ptr(); + const Geometry3D::MeshData::Face *faces_A = mesh_A.faces.ptr(); int face_count_A = mesh_A.faces.size(); - const Geometry::MeshData::Edge *edges_A = mesh_A.edges.ptr(); + const Geometry3D::MeshData::Edge *edges_A = mesh_A.edges.ptr(); int edge_count_A = mesh_A.edges.size(); const Vector3 *vertices_A = mesh_A.vertices.ptr(); int vertex_count_A = mesh_A.vertices.size(); - const Geometry::MeshData &mesh_B = convex_polygon_B->get_mesh(); + const Geometry3D::MeshData &mesh_B = convex_polygon_B->get_mesh(); - const Geometry::MeshData::Face *faces_B = mesh_B.faces.ptr(); + const Geometry3D::MeshData::Face *faces_B = mesh_B.faces.ptr(); int face_count_B = mesh_B.faces.size(); - const Geometry::MeshData::Edge *edges_B = mesh_B.edges.ptr(); + const Geometry3D::MeshData::Edge *edges_B = mesh_B.edges.ptr(); int edge_count_B = mesh_B.edges.size(); const Vector3 *vertices_B = mesh_B.vertices.ptr(); int vertex_count_B = mesh_B.vertices.size(); // faces of A for (int i = 0; i < face_count_A; i++) { - Vector3 axis = p_transform_a.xform(faces_A[i].plane).normal; //Vector3 axis = p_transform_a.basis.xform( faces_A[i].plane.normal ).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // faces of B for (int i = 0; i < face_count_B; i++) { - Vector3 axis = p_transform_b.xform(faces_B[i].plane).normal; //Vector3 axis = p_transform_b.basis.xform( faces_B[i].plane.normal ).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // A<->B edges for (int i = 0; i < edge_count_A; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]) - p_transform_a.basis.xform(vertices_A[edges_A[i].b]); for (int j = 0; j < edge_count_B; j++) { - Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[j].a]) - p_transform_b.basis.xform(vertices_B[edges_B[j].b]); Vector3 axis = e1.cross(e2).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } if (withMargin) { - //vertex-vertex for (int i = 0; i < vertex_count_A; i++) { - Vector3 va = p_transform_a.xform(vertices_A[i]); for (int j = 0; j < vertex_count_B; j++) { - - if (!separator.test_axis((va - p_transform_b.xform(vertices_B[j])).normalized())) + if (!separator.test_axis((va - p_transform_b.xform(vertices_B[j])).normalized())) { return; + } } } //edge-vertex (shell) for (int i = 0; i < edge_count_A; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]); Vector3 e2 = p_transform_a.basis.xform(vertices_A[edges_A[i].b]); Vector3 n = (e2 - e1); for (int j = 0; j < vertex_count_B; j++) { - Vector3 e3 = p_transform_b.xform(vertices_B[j]); - if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) + if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) { return; + } } } for (int i = 0; i < edge_count_B; i++) { - Vector3 e1 = p_transform_b.basis.xform(vertices_B[edges_B[i].a]); Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[i].b]); Vector3 n = (e2 - e1); for (int j = 0; j < vertex_count_A; j++) { - Vector3 e3 = p_transform_a.xform(vertices_A[j]); - if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) + if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) { return; + } } } } @@ -1363,17 +1357,16 @@ static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const template <bool withMargin> static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) { - const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a); const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b); SeparatorAxisTest<ConvexPolygonShape3DSW, FaceShape3DSW, withMargin> separator(convex_polygon_A, p_transform_a, face_B, p_transform_b, p_collector, p_margin_a, p_margin_b); - const Geometry::MeshData &mesh = convex_polygon_A->get_mesh(); + const Geometry3D::MeshData &mesh = convex_polygon_A->get_mesh(); - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int face_count = mesh.faces.size(); - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int edge_count = mesh.edges.size(); const Vector3 *vertices = mesh.vertices.ptr(); int vertex_count = mesh.vertices.size(); @@ -1384,77 +1377,73 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform p_transform_b.xform(face_B->vertex[2]), }; - if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) + if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) { return; + } // faces of A for (int i = 0; i < face_count; i++) { - //Vector3 axis = p_transform_a.xform( faces[i].plane ).normal; Vector3 axis = p_transform_a.basis.xform(faces[i].plane.normal).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } // A<->B edges for (int i = 0; i < edge_count; i++) { - Vector3 e1 = p_transform_a.xform(vertices[edges[i].a]) - p_transform_a.xform(vertices[edges[i].b]); for (int j = 0; j < 3; j++) { - Vector3 e2 = vertex[j] - vertex[(j + 1) % 3]; Vector3 axis = e1.cross(e2).normalized(); - if (!separator.test_axis(axis)) + if (!separator.test_axis(axis)) { return; + } } } if (withMargin) { - //vertex-vertex for (int i = 0; i < vertex_count; i++) { - Vector3 va = p_transform_a.xform(vertices[i]); for (int j = 0; j < 3; j++) { - - if (!separator.test_axis((va - vertex[j]).normalized())) + if (!separator.test_axis((va - vertex[j]).normalized())) { return; + } } } //edge-vertex (shell) for (int i = 0; i < edge_count; i++) { - Vector3 e1 = p_transform_a.basis.xform(vertices[edges[i].a]); Vector3 e2 = p_transform_a.basis.xform(vertices[edges[i].b]); Vector3 n = (e2 - e1); for (int j = 0; j < 3; j++) { - Vector3 e3 = vertex[j]; - if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) + if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) { return; + } } } for (int i = 0; i < 3; i++) { - Vector3 e1 = vertex[i]; Vector3 e2 = vertex[(i + 1) % 3]; Vector3 n = (e2 - e1); for (int j = 0; j < vertex_count; j++) { - Vector3 e3 = p_transform_a.xform(vertices[j]); - if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) + if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) { return; + } } } } @@ -1463,7 +1452,6 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform } bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) { - PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_PLANE, false); diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp index 5d31e1f546..e2bfaf990d 100644 --- a/servers/physics_3d/collision_solver_3d_sw.cpp +++ b/servers/physics_3d/collision_solver_3d_sw.cpp @@ -37,10 +37,10 @@ //#define collision_solver gjk_epa_calculate_penetration bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A); - if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) + if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) { return false; + } Plane p = p_transform_A.xform(plane->get_plane()); static const int max_supports = 16; @@ -52,19 +52,20 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T bool found = false; for (int i = 0; i < support_count; i++) { - supports[i] = p_transform_B.xform(supports[i]); - if (p.distance_to(supports[i]) >= 0) + if (p.distance_to(supports[i]) >= 0) { continue; + } found = true; Vector3 support_A = p.project(supports[i]); if (p_result_callback) { - if (p_swap_result) + if (p_swap_result) { p_result_callback(supports[i], support_A, p_userdata); - else + } else { p_result_callback(support_A, supports[i], p_userdata); + } } } @@ -72,7 +73,6 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T } bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) { - const RayShape3DSW *ray = static_cast<const RayShape3DSW *>(p_shape_A); Vector3 from = p_transform_A.origin; @@ -85,8 +85,9 @@ bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform to = ai.xform(to); Vector3 p, n; - if (!p_shape_B->intersect_segment(from, to, p, n)) + if (!p_shape_B->intersect_segment(from, to, p, n)) { return false; + } Vector3 support_B = p_transform_B.xform(p); if (ray->get_slips_on_slope()) { @@ -95,16 +96,16 @@ bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform } if (p_result_callback) { - if (p_swap_result) + if (p_swap_result) { p_result_callback(support_B, support_A, p_userdata); - else + } else { p_result_callback(support_A, support_B, p_userdata); + } } return true; } struct _ConcaveCollisionInfo { - const Transform *transform_A; const Shape3DSW *shape_A; const Transform *transform_B; @@ -121,20 +122,19 @@ struct _ConcaveCollisionInfo { }; void CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex) { - _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, nullptr, cinfo.margin_A, cinfo.margin_B); - if (!collided) + if (!collided) { return; + } cinfo.collided = true; cinfo.collisions++; } bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) { - const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B); _ConcaveCollisionInfo cinfo; @@ -158,7 +158,6 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf AABB local_aabb; for (int i = 0; i < 3; i++) { - Vector3 axis(p_transform_B.basis.get_axis(i)); real_t axis_scale = 1.0 / axis.length(); axis *= axis_scale; @@ -180,7 +179,6 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf } bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { - PhysicsServer3D::ShapeType type_A = p_shape_A->get_type(); PhysicsServer3D::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); @@ -195,9 +193,9 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo } if (type_A == PhysicsServer3D::SHAPE_PLANE) { - - if (type_B == PhysicsServer3D::SHAPE_PLANE) + if (type_B == PhysicsServer3D::SHAPE_PLANE) { return false; + } if (type_B == PhysicsServer3D::SHAPE_RAY) { return false; } @@ -209,9 +207,9 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo } } else if (type_A == PhysicsServer3D::SHAPE_RAY) { - - if (type_B == PhysicsServer3D::SHAPE_RAY) + if (type_B == PhysicsServer3D::SHAPE_RAY) { return false; + } if (swap) { return solve_ray(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); @@ -220,35 +218,35 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo } } else if (concave_B) { - - if (concave_A) + if (concave_A) { return false; + } - if (!swap) + if (!swap) { return solve_concave(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, p_margin_A, p_margin_B); - else + } else { return solve_concave(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, p_margin_A, p_margin_B); + } } else { - return collision_solver(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, r_sep_axis, p_margin_A, p_margin_B); } } void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW *p_convex) { - _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; - if (cinfo.collided) + if (cinfo.collided) { return; + } Vector3 close_A, close_B; cinfo.collided = !gjk_epa_calculate_distance(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, close_A, close_B); - if (cinfo.collided) + if (cinfo.collided) { return; + } if (!cinfo.tested || close_A.distance_squared_to(close_B) < cinfo.close_A.distance_squared_to(cinfo.close_B)) { - cinfo.close_A = close_A; cinfo.close_B = close_B; cinfo.tested = true; @@ -258,10 +256,10 @@ void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW } bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) { - const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A); - if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) + if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) { return false; + } Plane p = p_transform_A.xform(plane->get_plane()); static const int max_supports = 16; @@ -275,14 +273,14 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const real_t closest_d = 0; for (int i = 0; i < support_count; i++) { - supports[i] = p_transform_B.xform(supports[i]); real_t d = p.distance_to(supports[i]); if (i == 0 || d < closest_d) { closest = supports[i]; closest_d = d; - if (d <= 0) + if (d <= 0) { collided = true; + } } } @@ -293,12 +291,11 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const } bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { - - if (p_shape_A->is_concave()) + if (p_shape_A->is_concave()) { return false; + } if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) { - Vector3 a, b; bool col = solve_distance_plane(p_shape_B, p_transform_B, p_shape_A, p_transform_A, a, b); r_point_A = b; @@ -306,9 +303,9 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans return !col; } else if (p_shape_B->is_concave()) { - - if (p_shape_A->is_concave()) + if (p_shape_A->is_concave()) { return false; + } const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B); @@ -338,7 +335,6 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans AABB local_aabb; for (int i = 0; i < 3; i++) { - Vector3 axis(p_transform_B.basis.get_axis(i)); real_t axis_scale = ((real_t)1.0) / axis.length(); axis *= axis_scale; @@ -366,7 +362,6 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans return !cinfo.collided; } else { - return gjk_epa_calculate_distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, r_point_A, r_point_B); //should pass sepaxis.. } } diff --git a/servers/physics_3d/constraint_3d_sw.h b/servers/physics_3d/constraint_3d_sw.h index 5e2b00404b..081ddb0382 100644 --- a/servers/physics_3d/constraint_3d_sw.h +++ b/servers/physics_3d/constraint_3d_sw.h @@ -34,7 +34,6 @@ #include "body_3d_sw.h" class Constraint3DSW { - Body3DSW **_body_ptr; int _body_count; uint64_t island_step; diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index db37f261ce..d99a2532f8 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -123,10 +123,12 @@ struct MinkowskiDiff { _FORCE_INLINE_ Vector3 Support ( const Vector3& d,U index ) const { - if ( index ) + if ( index ) { return ( Support1 ( d ) ); - else + } else { return ( Support0 ( d ) ); + +} } }; @@ -278,7 +280,9 @@ struct GJK m_free[m_nfree++] = cs.c[i]; } } - if(mask==15) m_status=eStatus::Inside; + if(mask==15) { m_status=eStatus::Inside; + +} } else {/* Return old simplex */ @@ -307,10 +311,14 @@ struct GJK Vector3 axis=Vector3(0,0,0); axis[i]=1; appendvertice(*m_simplex, axis); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); appendvertice(*m_simplex,-axis); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); } } @@ -326,10 +334,14 @@ struct GJK if(p.length_squared()>0) { appendvertice(*m_simplex, p); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); appendvertice(*m_simplex,-p); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); } } @@ -342,10 +354,14 @@ struct GJK if(n.length_squared()>0) { appendvertice(*m_simplex,n); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); appendvertice(*m_simplex,-n); - if(EncloseOrigin()) return(true); + if(EncloseOrigin()) { return(true); + +} removevertice(*m_simplex); } } @@ -354,8 +370,10 @@ struct GJK { if(Math::abs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, m_simplex->c[1]->w-m_simplex->c[3]->w, - m_simplex->c[2]->w-m_simplex->c[3]->w))>0) + m_simplex->c[2]->w-m_simplex->c[3]->w))>0) { return(true); + +} } break; } @@ -513,16 +531,16 @@ struct GJK }; struct sList { - sFace* root; - U count; - sList() : root(nullptr),count(0) {} + sFace* root = nullptr; + U count = 0; + sList() {} }; struct sHorizon { - sFace* cf; - sFace* ff; - U nf; - sHorizon() : cf(nullptr),ff(nullptr),nf(0) {} + sFace* cf = nullptr; + sFace* ff = nullptr; + U nf = 0; + sHorizon() {} }; struct eStatus { enum _ { Valid, @@ -561,15 +579,23 @@ struct GJK { face->l[0] = nullptr; face->l[1] = list.root; - if(list.root) list.root->l[0]=face; + if(list.root) { list.root->l[0]=face; + +} list.root = face; ++list.count; } static inline void remove(sList& list,sFace* face) { - if(face->l[1]) face->l[1]->l[0]=face->l[0]; - if(face->l[0]) face->l[0]->l[1]=face->l[1]; - if(face==list.root) list.root=face->l[1]; + if(face->l[1]) { face->l[1]->l[0]=face->l[0]; + +} + if(face->l[0]) { face->l[0]->l[1]=face->l[1]; + +} + if(face==list.root) { list.root=face->l[1]; + +} --list.count; } @@ -650,7 +676,9 @@ struct GJK remove(m_hull,best); append(m_stock,best); best=findbest(); - if(best->p>=outer.p) outer=*best; + if(best->p>=outer.p) { outer=*best; + +} } else { m_status=eStatus::InvalidHull;break; } } else { m_status=eStatus::AccuraryReached;break; } } else { m_status=eStatus::OutOfVertices;break; } @@ -679,10 +707,12 @@ struct GJK m_status = eStatus::FallBack; m_normal = -guess; const real_t nl=m_normal.length(); - if(nl>0) + if(nl>0) { m_normal = m_normal/nl; - else + } else { m_normal = Vector3(1,0,0); + +} m_depth = 0; m_result.rank=1; m_result.c[0]=simplex.c[0]; @@ -716,8 +746,12 @@ struct GJK if(forced||(face->d>=-EPA_PLANE_EPS)) { return(face); - } else m_status=eStatus::NonConvex; - } else m_status=eStatus::Degenerated; + } else { m_status=eStatus::NonConvex; + +} + } else { m_status=eStatus::Degenerated; + +} remove(m_hull,face); append(m_stock,face); return(nullptr); @@ -758,7 +792,9 @@ struct GJK if(nf) { bind(nf,0,f,e); - if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; + if(horizon.cf) { bind(horizon.cf,1,nf,2); } else { horizon.ff=nf; + +} horizon.cf=nf; ++horizon.nf; return(true); @@ -847,6 +883,7 @@ bool Distance( const Shape3DSW* shape0, } } + // bool Penetration( const Shape3DSW* shape0, const Transform& wtrs0, @@ -879,7 +916,9 @@ bool Penetration( const Shape3DSW* shape0, results.normal = -epa.m_normal; results.distance = -epa.m_depth; return(true); - } else results.status=sResults::EPA_Failed; + } else { results.status=sResults::EPA_Failed; + +} } break; case GJK::eStatus::Failed: @@ -891,6 +930,7 @@ bool Penetration( const Shape3DSW* shape0, } + /* Symbols cleanup */ #undef GJK_MAX_ITERATIONS @@ -915,11 +955,9 @@ bool Penetration( const Shape3DSW* shape0, /* clang-format on */ bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) { - GjkEpa2::sResults res; if (GjkEpa2::Distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_transform_B.origin - p_transform_A.origin, res)) { - r_result_A = res.witnesses[0]; r_result_B = res.witnesses[1]; return true; @@ -929,15 +967,15 @@ bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_t } bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap) { - GjkEpa2::sResults res; if (GjkEpa2::Penetration(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_transform_B.origin - p_transform_A.origin, res)) { if (p_result_callback) { - if (p_swap) + if (p_swap) { p_result_callback(res.witnesses[1], res.witnesses[0], p_userdata); - else + } else { p_result_callback(res.witnesses[0], res.witnesses[1], p_userdata); + } } return true; } diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp index a072c1f3a0..9d10ede608 100644 --- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp @@ -52,7 +52,6 @@ Written by: Marcus Hennix #include "cone_twist_joint_3d_sw.h" static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { - if (Math::abs(n.z) > Math_SQRT12) { // choose p in y-z plane real_t a = n[1] * n[1] + n[2] * n[2]; @@ -87,7 +86,6 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &rbAFrame, const Transform &rbBFrame) : Joint3DSW(_arr, 2) { - A = rbA; B = rbB; @@ -238,7 +236,6 @@ bool ConeTwistJoint3DSW::setup(real_t p_timestep) { } void ConeTwistJoint3DSW::solve(real_t p_timestep) { - Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin); Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin); @@ -309,57 +306,47 @@ void ConeTwistJoint3DSW::solve(real_t p_timestep) { } void ConeTwistJoint3DSW::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) { - switch (p_param) { case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: { - m_swingSpan1 = p_value; m_swingSpan2 = p_value; } break; case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: { - m_twistSpan = p_value; } break; case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: { - m_biasFactor = p_value; } break; case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: { - m_limitSoftness = p_value; } break; case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: { - m_relaxationFactor = p_value; } break; - case PhysicsServer3D::CONE_TWIST_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::CONE_TWIST_MAX: + break; // Can't happen, but silences warning } } real_t ConeTwistJoint3DSW::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const { - switch (p_param) { case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: { - return m_swingSpan1; } break; case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: { - return m_twistSpan; } break; case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: { - return m_biasFactor; } break; case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: { - return m_limitSoftness; } break; case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: { - return m_relaxationFactor; } break; - case PhysicsServer3D::CONE_TWIST_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::CONE_TWIST_MAX: + break; // Can't happen, but silences warning } return 0; diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp index e15aeca842..423bbc0dfd 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp @@ -83,7 +83,9 @@ int G6DOFRotationalLimitMotor3DSW::testLimitValue(real_t test_value) { real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits( real_t timeStep, Vector3 &axis, real_t jacDiagABInv, Body3DSW *body0, Body3DSW *body1) { - if (!needApplyTorques()) return 0.0f; + if (!needApplyTorques()) { + return 0.0f; + } real_t target_velocity = m_targetVelocity; real_t maxMotorForce = m_maxMotorForce; @@ -137,7 +139,9 @@ real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits( Vector3 motorImp = clippedMotorImpulse * axis; body0->apply_torque_impulse(motorImp); - if (body1) body1->apply_torque_impulse(-motorImp); + if (body1) { + body1->apply_torque_impulse(-motorImp); + } return clippedMotorImpulse; } @@ -153,7 +157,6 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis( int limit_index, const Vector3 &axis_normal_on_a, const Vector3 &anchorPos) { - ///find relative velocity // Vector3 rel_pos1 = pointInA - body1->get_transform().origin; // Vector3 rel_pos2 = pointInB - body2->get_transform().origin; @@ -301,7 +304,6 @@ bool Generic6DOFJoint3DSW::testAngularLimitMotor(int axis_index) { } bool Generic6DOFJoint3DSW::setup(real_t p_timestep) { - // Clear accumulated impulses for the next simulation step m_linearLimits.m_accumulatedImpulse = Vector3(real_t(0.), real_t(0.), real_t(0.)); int i; @@ -325,10 +327,11 @@ bool Generic6DOFJoint3DSW::setup(real_t p_timestep) { //linear part for (i = 0; i < 3; i++) { if (m_linearLimits.enable_limit[i] && m_linearLimits.isLimited(i)) { - if (m_useLinearReferenceFrameA) + if (m_useLinearReferenceFrameA) { normalWorld = m_calculatedTransformA.basis.get_axis(i); - else + } else { normalWorld = m_calculatedTransformB.basis.get_axis(i); + } buildLinearJacobian( m_jacLinear[i], normalWorld, @@ -367,10 +370,11 @@ void Generic6DOFJoint3DSW::solve(real_t p_timestep) { if (m_linearLimits.enable_limit[i] && m_linearLimits.isLimited(i)) { jacDiagABInv = real_t(1.) / m_jacLinear[i].getDiagonal(); - if (m_useLinearReferenceFrameA) + if (m_useLinearReferenceFrameA) { linear_axis = m_calculatedTransformA.basis.get_axis(i); - else + } else { linear_axis = m_calculatedTransformB.basis.get_axis(i); + } m_linearLimits.solveLinearAxis( m_timeStep, @@ -386,7 +390,6 @@ void Generic6DOFJoint3DSW::solve(real_t p_timestep) { real_t angularJacDiagABInv; for (i = 0; i < 3; i++) { if (m_angularLimits[i].m_enableLimit && m_angularLimits[i].needApplyTorques()) { - // get axis angular_axis = getAxis(i); @@ -409,7 +412,7 @@ real_t Generic6DOFJoint3DSW::getAngle(int axis_index) const { return m_calculatedAxisAngleDiff[axis_index]; } -void Generic6DOFJoint3DSW::calcAnchorPos(void) { +void Generic6DOFJoint3DSW::calcAnchorPos() { real_t imA = A->get_inv_mass(); real_t imB = B->get_inv_mass(); real_t weight; @@ -424,75 +427,60 @@ void Generic6DOFJoint3DSW::calcAnchorPos(void) { } // Generic6DOFJointSW::calcAnchorPos() void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) { - ERR_FAIL_INDEX(p_axis, 3); switch (p_param) { case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: { - m_linearLimits.m_lowerLimit[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: { - m_linearLimits.m_upperLimit[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS: { - m_linearLimits.m_limitSoftness[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION: { - m_linearLimits.m_restitution[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING: { - m_linearLimits.m_damping[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: { - m_angularLimits[p_axis].m_loLimit = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: { - m_angularLimits[p_axis].m_hiLimit = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS: { - m_angularLimits[p_axis].m_limitSoftness = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING: { - m_angularLimits[p_axis].m_damping = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: { - m_angularLimits[p_axis].m_bounce = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_FORCE_LIMIT: { - m_angularLimits[p_axis].m_maxLimitForce = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: { - m_angularLimits[p_axis].m_ERP = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: { - m_angularLimits[p_axis].m_targetVelocity = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: { - m_angularLimits[p_axis].m_maxLimitForce = p_value; } break; @@ -520,7 +508,8 @@ void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DO case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: { // Not implemented in GodotPhysics3D backend } break; - case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::G6DOF_JOINT_MAX: + break; // Can't happen, but silences warning } } @@ -528,71 +517,57 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6 ERR_FAIL_INDEX_V(p_axis, 3, 0); switch (p_param) { case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: { - return m_linearLimits.m_lowerLimit[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: { - return m_linearLimits.m_upperLimit[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS: { - return m_linearLimits.m_limitSoftness[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION: { - return m_linearLimits.m_restitution[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING: { - return m_linearLimits.m_damping[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: { - return m_angularLimits[p_axis].m_loLimit; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: { - return m_angularLimits[p_axis].m_hiLimit; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS: { - return m_angularLimits[p_axis].m_limitSoftness; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING: { - return m_angularLimits[p_axis].m_damping; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: { - return m_angularLimits[p_axis].m_bounce; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_FORCE_LIMIT: { - return m_angularLimits[p_axis].m_maxLimitForce; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: { - return m_angularLimits[p_axis].m_ERP; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: { - return m_angularLimits[p_axis].m_targetVelocity; } break; case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: { - return m_angularLimits[p_axis].m_maxMotorForce; } break; @@ -620,26 +595,23 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6 case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: { // Not implemented in GodotPhysics3D backend } break; - case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::G6DOF_JOINT_MAX: + break; // Can't happen, but silences warning } return 0; } void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) { - ERR_FAIL_INDEX(p_axis, 3); switch (p_flag) { case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: { - m_linearLimits.enable_limit[p_axis] = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: { - m_angularLimits[p_axis].m_enableLimit = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR: { - m_angularLimits[p_axis].m_enableMotor = p_value; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: { @@ -651,23 +623,21 @@ void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: { // Not implemented in GodotPhysics3D backend } break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: + break; // Can't happen, but silences warning } } -bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { +bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const { ERR_FAIL_INDEX_V(p_axis, 3, 0); switch (p_flag) { case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: { - return m_linearLimits.enable_limit[p_axis]; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: { - return m_angularLimits[p_axis].m_enableLimit; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR: { - return m_angularLimits[p_axis].m_enableMotor; } break; case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: { @@ -679,8 +649,9 @@ bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: { // Not implemented in GodotPhysics3D backend } break; - case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: + break; // Can't happen, but silences warning } - return 0; + return false; } diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h index f7aa607901..cc1423a1cb 100644 --- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h +++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h @@ -389,7 +389,7 @@ public: return B; } - virtual void calcAnchorPos(void); // overridable + virtual void calcAnchorPos(); // overridable void set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value); real_t get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const; diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp index e76d366422..a879b4ca7f 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp @@ -50,7 +50,6 @@ subject to the following restrictions: #include "hinge_joint_3d_sw.h" static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { - if (Math::abs(n.z) > Math_SQRT12) { // choose p in y-z plane real_t a = n[1] * n[1] + n[2] * n[2]; @@ -70,7 +69,6 @@ static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) { HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameA, const Transform &frameB) : Joint3DSW(_arr, 2) { - A = rbA; B = rbB; @@ -103,7 +101,6 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &fr HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB) : Joint3DSW(_arr, 2) { - A = rbA; B = rbB; @@ -158,7 +155,6 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivo } bool HingeJoint3DSW::setup(real_t p_step) { - m_appliedImpulse = real_t(0.); if (!m_angularOnly) { @@ -254,7 +250,6 @@ bool HingeJoint3DSW::setup(real_t p_step) { } void HingeJoint3DSW::solve(real_t p_step) { - Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin); Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin); @@ -365,12 +360,14 @@ void HingeJoint3DSW::solve(real_t p_step) { } } } + /* void HingeJointSW::updateRHS(real_t timeStep) { (void)timeStep; } + */ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) { @@ -397,53 +394,82 @@ real_t HingeJoint3DSW::get_hinge_angle() { } void HingeJoint3DSW::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) { - switch (p_param) { - - case PhysicsServer3D::HINGE_JOINT_BIAS: tau = p_value; break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: m_upperLimit = p_value; break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: m_lowerLimit = p_value; break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: m_biasFactor = p_value; break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: m_limitSoftness = p_value; break; - case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: m_relaxationFactor = p_value; break; - case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: m_motorTargetVelocity = p_value; break; - case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: m_maxMotorImpulse = p_value; break; - case PhysicsServer3D::HINGE_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::HINGE_JOINT_BIAS: + tau = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: + m_upperLimit = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: + m_lowerLimit = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: + m_biasFactor = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: + m_limitSoftness = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: + m_relaxationFactor = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: + m_motorTargetVelocity = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: + m_maxMotorImpulse = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_MAX: + break; // Can't happen, but silences warning } } real_t HingeJoint3DSW::get_param(PhysicsServer3D::HingeJointParam p_param) const { - switch (p_param) { - - case PhysicsServer3D::HINGE_JOINT_BIAS: return tau; - case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: return m_upperLimit; - case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: return m_lowerLimit; - case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: return m_biasFactor; - case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: return m_limitSoftness; - case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: return m_relaxationFactor; - case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: return m_motorTargetVelocity; - case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: return m_maxMotorImpulse; - case PhysicsServer3D::HINGE_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::HINGE_JOINT_BIAS: + return tau; + case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: + return m_upperLimit; + case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: + return m_lowerLimit; + case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: + return m_biasFactor; + case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: + return m_limitSoftness; + case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: + return m_relaxationFactor; + case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: + return m_motorTargetVelocity; + case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: + return m_maxMotorImpulse; + case PhysicsServer3D::HINGE_JOINT_MAX: + break; // Can't happen, but silences warning } return 0; } void HingeJoint3DSW::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) { - switch (p_flag) { - case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: m_useLimit = p_value; break; - case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: m_enableAngularMotor = p_value; break; - case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: + m_useLimit = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: + m_enableAngularMotor = p_value; + break; + case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: + break; // Can't happen, but silences warning } } -bool HingeJoint3DSW::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const { +bool HingeJoint3DSW::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const { switch (p_flag) { - case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: return m_useLimit; - case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: return m_enableAngularMotor; - case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: + return m_useLimit; + case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: + return m_enableAngularMotor; + case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: + break; // Can't happen, but silences warning } return false; diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h index eebead20b8..c5af888eca 100644 --- a/servers/physics_3d/joints/hinge_joint_3d_sw.h +++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h @@ -54,7 +54,6 @@ subject to the following restrictions: */ class HingeJoint3DSW : public Joint3DSW { - union { struct { Body3DSW *A; diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/jacobian_entry_3d_sw.h index 7e605ab173..1737c21b3d 100644 --- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h +++ b/servers/physics_3d/joints/jacobian_entry_3d_sw.h @@ -54,7 +54,7 @@ subject to the following restrictions: class JacobianEntry3DSW { public: - JacobianEntry3DSW(){}; + JacobianEntry3DSW() {} //constraint between two different rigidbodies JacobianEntry3DSW( const Basis &world2A, diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.cpp b/servers/physics_3d/joints/pin_joint_3d_sw.cpp index 95c01bc463..230904408b 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/pin_joint_3d_sw.cpp @@ -50,7 +50,6 @@ subject to the following restrictions: #include "pin_joint_3d_sw.h" bool PinJoint3DSW::setup(real_t p_step) { - m_appliedImpulse = real_t(0.); Vector3 normal(0, 0, 0); @@ -74,7 +73,6 @@ bool PinJoint3DSW::setup(real_t p_step) { } void PinJoint3DSW::solve(real_t p_step) { - Vector3 pivotAInW = A->get_transform().xform(m_pivotInA); Vector3 pivotBInW = B->get_transform().xform(m_pivotInB); @@ -111,10 +109,12 @@ void PinJoint3DSW::solve(real_t p_step) { real_t impulseClamp = m_impulseClamp; if (impulseClamp > 0) { - if (impulse < -impulseClamp) + if (impulse < -impulseClamp) { impulse = -impulseClamp; - if (impulse > impulseClamp) + } + if (impulse > impulseClamp) { impulse = impulseClamp; + } } m_appliedImpulse += impulse; @@ -127,20 +127,27 @@ void PinJoint3DSW::solve(real_t p_step) { } void PinJoint3DSW::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::PIN_JOINT_BIAS: m_tau = p_value; break; - case PhysicsServer3D::PIN_JOINT_DAMPING: m_damping = p_value; break; - case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: m_impulseClamp = p_value; break; + case PhysicsServer3D::PIN_JOINT_BIAS: + m_tau = p_value; + break; + case PhysicsServer3D::PIN_JOINT_DAMPING: + m_damping = p_value; + break; + case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: + m_impulseClamp = p_value; + break; } } real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::PIN_JOINT_BIAS: return m_tau; - case PhysicsServer3D::PIN_JOINT_DAMPING: return m_damping; - case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: return m_impulseClamp; + case PhysicsServer3D::PIN_JOINT_BIAS: + return m_tau; + case PhysicsServer3D::PIN_JOINT_DAMPING: + return m_damping; + case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: + return m_impulseClamp; } return 0; @@ -148,7 +155,6 @@ real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const { PinJoint3DSW::PinJoint3DSW(Body3DSW *p_body_a, const Vector3 &p_pos_a, Body3DSW *p_body_b, const Vector3 &p_pos_b) : Joint3DSW(_arr, 2) { - A = p_body_a; B = p_body_b; m_pivotInA = p_pos_a; diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h index 8e81ccf5e0..0181a4455b 100644 --- a/servers/physics_3d/joints/pin_joint_3d_sw.h +++ b/servers/physics_3d/joints/pin_joint_3d_sw.h @@ -54,7 +54,6 @@ subject to the following restrictions: */ class PinJoint3DSW : public Joint3DSW { - union { struct { Body3DSW *A; diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp index 066c30e0f3..5b4609f24e 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp +++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp @@ -116,7 +116,6 @@ SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform & Joint3DSW(_arr, 2), m_frameInA(frameInA), m_frameInB(frameInB) { - A = rbA; B = rbB; @@ -129,7 +128,6 @@ SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform & //----------------------------------------------------------------------------- bool SliderJoint3DSW::setup(real_t p_step) { - //calculate transforms m_calculatedTransformA = A->get_transform() * m_frameInA; m_calculatedTransformB = B->get_transform() * m_frameInB; @@ -182,7 +180,6 @@ bool SliderJoint3DSW::setup(real_t p_step) { //----------------------------------------------------------------------------- void SliderJoint3DSW::solve(real_t p_step) { - int i; // linear Vector3 velA = A->get_velocity_in_local_point(m_relPosA); @@ -304,7 +301,7 @@ void SliderJoint3DSW::solve(real_t p_step) { //----------------------------------------------------------------------------- -void SliderJoint3DSW::calculateTransforms(void) { +void SliderJoint3DSW::calculateTransforms() { m_calculatedTransformA = A->get_transform() * m_frameInA; m_calculatedTransformB = B->get_transform() * m_frameInB; m_realPivotAInW = m_calculatedTransformA.origin; @@ -323,7 +320,7 @@ void SliderJoint3DSW::calculateTransforms(void) { //----------------------------------------------------------------------------- -void SliderJoint3DSW::testLinLimits(void) { +void SliderJoint3DSW::testLinLimits() { m_solveLinLim = false; m_linPos = m_depth[0]; if (m_lowerLinLimit <= m_upperLinLimit) { @@ -343,7 +340,7 @@ void SliderJoint3DSW::testLinLimits(void) { //----------------------------------------------------------------------------- -void SliderJoint3DSW::testAngLimits(void) { +void SliderJoint3DSW::testAngLimits() { m_angDepth = real_t(0.); m_solveAngLim = false; if (m_lowerAngLimit <= m_upperAngLimit) { @@ -363,7 +360,7 @@ void SliderJoint3DSW::testAngLimits(void) { //----------------------------------------------------------------------------- -Vector3 SliderJoint3DSW::getAncorInA(void) { +Vector3 SliderJoint3DSW::getAncorInA() { Vector3 ancorInA; ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * real_t(0.5) * m_sliderAxis; ancorInA = A->get_transform().inverse().xform(ancorInA); @@ -372,71 +369,137 @@ Vector3 SliderJoint3DSW::getAncorInA(void) { //----------------------------------------------------------------------------- -Vector3 SliderJoint3DSW::getAncorInB(void) { +Vector3 SliderJoint3DSW::getAncorInB() { Vector3 ancorInB; ancorInB = m_frameInB.origin; return ancorInB; } // SliderJointSW::getAncorInB(); void SliderJoint3DSW::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) { - switch (p_param) { - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: m_upperLinLimit = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: m_lowerLinLimit = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: m_softnessLimLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: m_restitutionLimLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: m_dampingLimLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: m_softnessDirLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: m_restitutionDirLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: m_dampingDirLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: m_softnessOrthoLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: m_restitutionOrthoLin = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: m_dampingOrthoLin = p_value; break; - - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: m_upperAngLimit = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: m_lowerAngLimit = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: m_softnessLimAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: m_restitutionLimAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: m_dampingLimAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: m_softnessDirAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: m_restitutionDirAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: m_dampingDirAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: m_softnessOrthoAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: m_restitutionOrthoAng = p_value; break; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: m_dampingOrthoAng = p_value; break; - - case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: + m_upperLinLimit = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: + m_lowerLinLimit = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: + m_softnessLimLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: + m_restitutionLimLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: + m_dampingLimLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: + m_softnessDirLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: + m_restitutionDirLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: + m_dampingDirLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: + m_softnessOrthoLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: + m_restitutionOrthoLin = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: + m_dampingOrthoLin = p_value; + break; + + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: + m_upperAngLimit = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: + m_lowerAngLimit = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: + m_softnessLimAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: + m_restitutionLimAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: + m_dampingLimAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: + m_softnessDirAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: + m_restitutionDirAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: + m_dampingDirAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: + m_softnessOrthoAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: + m_restitutionOrthoAng = p_value; + break; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: + m_dampingOrthoAng = p_value; + break; + + case PhysicsServer3D::SLIDER_JOINT_MAX: + break; // Can't happen, but silences warning } } real_t SliderJoint3DSW::get_param(PhysicsServer3D::SliderJointParam p_param) const { - switch (p_param) { - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return m_upperLinLimit; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return m_lowerLinLimit; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return m_softnessLimLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return m_restitutionLimLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return m_dampingLimLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return m_softnessDirLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return m_restitutionDirLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return m_dampingDirLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return m_softnessOrthoLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return m_restitutionOrthoLin; - case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return m_dampingOrthoLin; - - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return m_upperAngLimit; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return m_lowerAngLimit; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return m_softnessLimAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return m_restitutionLimAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return m_dampingLimAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return m_softnessDirAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return m_restitutionDirAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return m_dampingDirAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return m_softnessOrthoAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return m_restitutionOrthoAng; - case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return m_dampingOrthoAng; - - case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: + return m_upperLinLimit; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: + return m_lowerLinLimit; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: + return m_softnessLimLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: + return m_restitutionLimLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: + return m_dampingLimLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: + return m_softnessDirLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: + return m_restitutionDirLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: + return m_dampingDirLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: + return m_softnessOrthoLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: + return m_restitutionOrthoLin; + case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: + return m_dampingOrthoLin; + + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: + return m_upperAngLimit; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: + return m_lowerAngLimit; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: + return m_softnessLimAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: + return m_restitutionLimAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: + return m_dampingLimAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: + return m_softnessDirAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: + return m_restitutionDirAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: + return m_dampingDirAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: + return m_softnessOrthoAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: + return m_restitutionOrthoAng; + case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: + return m_dampingOrthoAng; + + case PhysicsServer3D::SLIDER_JOINT_MAX: + break; // Can't happen, but silences warning } return 0; diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h index 18287db9c2..37394a1580 100644 --- a/servers/physics_3d/joints/slider_joint_3d_sw.h +++ b/servers/physics_3d/joints/slider_joint_3d_sw.h @@ -230,12 +230,12 @@ public: bool getSolveAngLimit() { return m_solveAngLim; } real_t getAngDepth() { return m_angDepth; } // shared code used by ODE solver - void calculateTransforms(void); - void testLinLimits(void); - void testAngLimits(void); + void calculateTransforms(); + void testLinLimits(); + void testAngLimits(); // access for PE Solver - Vector3 getAncorInA(void); - Vector3 getAncorInB(void); + Vector3 getAncorInA(); + Vector3 getAncorInB(); void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value); real_t get_param(PhysicsServer3D::SliderJointParam p_param) const; diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h index 0f2d4892a8..6a010ee771 100644 --- a/servers/physics_3d/joints_3d_sw.h +++ b/servers/physics_3d/joints_3d_sw.h @@ -35,7 +35,6 @@ #include "constraint_3d_sw.h" class Joint3DSW : public Constraint3DSW { - public: virtual PhysicsServer3D::JointType get_type() const = 0; _FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) : diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp index d8da6e715b..1c2329f2dc 100644 --- a/servers/physics_3d/physics_server_3d_sw.cpp +++ b/servers/physics_3d/physics_server_3d_sw.cpp @@ -44,48 +44,36 @@ ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead."); RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { - Shape3DSW *shape = nullptr; switch (p_shape) { - case SHAPE_PLANE: { - shape = memnew(PlaneShape3DSW); } break; case SHAPE_RAY: { - shape = memnew(RayShape3DSW); } break; case SHAPE_SPHERE: { - shape = memnew(SphereShape3DSW); } break; case SHAPE_BOX: { - shape = memnew(BoxShape3DSW); } break; case SHAPE_CAPSULE: { - shape = memnew(CapsuleShape3DSW); } break; case SHAPE_CYLINDER: { - ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings."); } break; case SHAPE_CONVEX_POLYGON: { - shape = memnew(ConvexPolygonShape3DSW); } break; case SHAPE_CONCAVE_POLYGON: { - shape = memnew(ConcavePolygonShape3DSW); } break; case SHAPE_HEIGHTMAP: { - shape = memnew(HeightMapShape3DSW); } break; case SHAPE_CUSTOM: { - ERR_FAIL_V(RID()); } break; @@ -98,28 +86,24 @@ RID PhysicsServer3DSW::shape_create(ShapeType p_shape) { }; void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) { - Shape3DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); }; void PhysicsServer3DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) { - Shape3DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_custom_bias(p_bias); } PhysicsServer3D::ShapeType PhysicsServer3DSW::shape_get_type(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM); return shape->get_type(); }; Variant PhysicsServer3DSW::shape_get_data(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, Variant()); ERR_FAIL_COND_V(!shape->is_configured(), Variant()); @@ -134,14 +118,12 @@ real_t PhysicsServer3DSW::shape_get_margin(RID p_shape) const { } real_t PhysicsServer3DSW::shape_get_custom_solver_bias(RID p_shape) const { - const Shape3DSW *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); return shape->get_custom_bias(); } RID PhysicsServer3DSW::space_create() { - Space3DSW *space = memnew(Space3DSW); RID id = space_owner.make_rid(space); space->set_self(id); @@ -160,17 +142,16 @@ RID PhysicsServer3DSW::space_create() { }; void PhysicsServer3DSW::space_set_active(RID p_space, bool p_active) { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); - if (p_active) + if (p_active) { active_spaces.insert(space); - else + } else { active_spaces.erase(space); + } } bool PhysicsServer3DSW::space_is_active(RID p_space) const { - const Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, false); @@ -178,7 +159,6 @@ bool PhysicsServer3DSW::space_is_active(RID p_space) const { } void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); @@ -186,14 +166,12 @@ void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, rea } real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) const { - const Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, nullptr); ERR_FAIL_COND_V_MSG(!doing_sync || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification."); @@ -202,28 +180,24 @@ PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space } void PhysicsServer3DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector3> PhysicsServer3DSW::space_get_contacts(RID p_space) const { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, Vector<Vector3>()); return space->get_debug_contacts(); } int PhysicsServer3DSW::space_get_contact_count(RID p_space) const { - Space3DSW *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); } RID PhysicsServer3DSW::area_create() { - Area3DSW *area = memnew(Area3DSW); RID rid = area_owner.make_rid(area); area->set_self(rid); @@ -231,7 +205,6 @@ RID PhysicsServer3DSW::area_create() { }; void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -241,26 +214,26 @@ void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) { ERR_FAIL_COND(!space); } - if (area->get_space() == space) + if (area->get_space() == space) { return; //pointless + } area->clear_constraints(); area->set_space(space); }; RID PhysicsServer3DSW::area_get_space(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, RID()); Space3DSW *space = area->get_space(); - if (!space) + if (!space) { return RID(); + } return space->get_self(); }; void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -268,7 +241,6 @@ void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverri } PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_override_mode(RID p_area) const { - const Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED); @@ -276,7 +248,6 @@ PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_overrid } void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -287,7 +258,6 @@ void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform } void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -299,7 +269,6 @@ void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) } void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -307,14 +276,13 @@ void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, co } int PhysicsServer3DSW::area_get_shape_count(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, -1); return area->get_shape_count(); } -RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { +RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, RID()); @@ -323,8 +291,8 @@ RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const { return shape->get_self(); } -Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { +Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const { Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform()); @@ -332,7 +300,6 @@ Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_id } void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -340,16 +307,15 @@ void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) { } void PhysicsServer3DSW::area_clear_shapes(RID p_area) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - while (area->get_shape_count()) + while (area->get_shape_count()) { area->remove_shape(0); + } } void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count()); @@ -358,7 +324,6 @@ void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, boo } void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) { - if (space_owner.owns(p_area)) { Space3DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -367,8 +332,8 @@ void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id ERR_FAIL_COND(!area); area->set_instance_id(p_id); } -ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const { +ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { Space3DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -379,7 +344,6 @@ ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const { } void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { - if (space_owner.owns(p_area)) { Space3DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -390,14 +354,12 @@ void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const }; void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform &p_transform) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); }; Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) const { - if (space_owner.owns(p_area)) { Space3DSW *space = space_owner.getornull(p_area); p_area = space->get_default_area()->get_self(); @@ -409,7 +371,6 @@ Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) con }; Transform PhysicsServer3DSW::area_get_transform(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform()); @@ -417,7 +378,6 @@ Transform PhysicsServer3DSW::area_get_transform(RID p_area) const { }; void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -425,7 +385,6 @@ void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) { } void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -433,7 +392,6 @@ void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) { } void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); FLUSH_QUERY_CHECK(area); @@ -442,7 +400,6 @@ void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) { } void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -450,7 +407,6 @@ void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver } void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -458,7 +414,6 @@ void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) { } bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, false); @@ -466,7 +421,6 @@ bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const { } void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - Area3DSW *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); @@ -476,19 +430,19 @@ void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec /* BODY API */ RID PhysicsServer3DSW::body_create(BodyMode p_mode, bool p_init_sleeping) { - Body3DSW *body = memnew(Body3DSW); - if (p_mode != BODY_MODE_RIGID) + if (p_mode != BODY_MODE_RIGID) { body->set_mode(p_mode); - if (p_init_sleeping) + } + if (p_init_sleeping) { body->set_state(BODY_STATE_SLEEPING, p_init_sleeping); + } RID rid = body_owner.make_rid(body); body->set_self(rid); return rid; }; void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -498,26 +452,26 @@ void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) { ERR_FAIL_COND(!space); } - if (body->get_space() == space) + if (body->get_space() == space) { return; //pointless + } body->clear_constraint_map(); body->set_space(space); }; RID PhysicsServer3DSW::body_get_space(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); Space3DSW *space = body->get_space(); - if (!space) + if (!space) { return RID(); + } return space->get_self(); }; void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -525,7 +479,6 @@ void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) { }; PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); @@ -533,7 +486,6 @@ PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const { }; void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -544,7 +496,6 @@ void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform } void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -554,8 +505,8 @@ void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) body->set_shape(p_shape_idx, shape); } -void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) { +void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -563,14 +514,13 @@ void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, co } int PhysicsServer3DSW::body_get_shape_count(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_shape_count(); } -RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { +RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); @@ -581,7 +531,6 @@ RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const { } void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count()); @@ -591,7 +540,6 @@ void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo } Transform PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Transform()); @@ -599,7 +547,6 @@ Transform PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_id } void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -607,16 +554,15 @@ void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) { } void PhysicsServer3DSW::body_clear_shapes(RID p_body) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); - while (body->get_shape_count()) + while (body->get_shape_count()) { body->remove_shape(0); + } } void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -624,7 +570,6 @@ void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_bod } bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); @@ -632,7 +577,6 @@ bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_bod } void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -641,7 +585,6 @@ void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) { } uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const { - const Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -649,7 +592,6 @@ uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const { } void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -658,7 +600,6 @@ void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { } uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const { - const Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -666,7 +607,6 @@ uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const { } void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -674,7 +614,6 @@ void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id }; ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, ObjectID()); @@ -682,13 +621,11 @@ ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const { }; void PhysicsServer3DSW::body_set_user_flags(RID p_body, uint32_t p_flags) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); }; uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -696,7 +633,6 @@ uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const { }; void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -704,7 +640,6 @@ void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, real_t }; real_t PhysicsServer3DSW::body_get_param(RID p_body, BodyParameter p_param) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); @@ -725,7 +660,6 @@ real_t PhysicsServer3DSW::body_get_kinematic_safe_margin(RID p_body) const { } void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -733,7 +667,6 @@ void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Vari }; Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Variant()); @@ -741,7 +674,6 @@ Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const { }; void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_force) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -750,14 +682,12 @@ void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_forc }; Vector3 PhysicsServer3DSW::body_get_applied_force(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_force(); }; void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -766,7 +696,6 @@ void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_tor }; Vector3 PhysicsServer3DSW::body_get_applied_torque(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3()); @@ -808,7 +737,6 @@ void PhysicsServer3DSW::body_apply_central_impulse(RID p_body, const Vector3 &p_ } void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -819,7 +747,6 @@ void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, con }; void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -830,7 +757,6 @@ void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_i }; void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -845,7 +771,6 @@ void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis }; void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -854,14 +779,12 @@ void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_l } bool PhysicsServer3DSW::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->is_axis_locked(p_axis); } void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -870,7 +793,6 @@ void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) { }; void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -879,7 +801,6 @@ void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b }; void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -889,20 +810,17 @@ void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e }; void PhysicsServer3DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); }; real_t PhysicsServer3DSW::body_get_contacts_reported_depth_threshold(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return 0; }; void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); @@ -910,49 +828,42 @@ void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit) }; bool PhysicsServer3DSW::body_is_omitting_force_integration(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_force_integration(); }; void PhysicsServer3DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_max_contacts_reported(p_contacts); } int PhysicsServer3DSW::body_get_max_contacts_reported(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, -1); return body->get_max_contacts_reported(); } void PhysicsServer3DSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata); } void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } bool PhysicsServer3DSW::body_is_ray_pickable(RID p_body) const { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->is_ray_pickable(); } bool PhysicsServer3DSW::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) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -964,7 +875,6 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, co } int PhysicsServer3DSW::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) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -976,7 +886,6 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t } PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { - Body3DSW *body = body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, nullptr); ERR_FAIL_COND_V_MSG(!doing_sync || body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification."); @@ -988,7 +897,6 @@ PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) { /* JOINT API */ RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1009,15 +917,14 @@ RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, } void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_param(p_param, p_value); } -real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { +real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); @@ -1026,15 +933,14 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param } void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_a(p_A); } -Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { +Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); @@ -1043,15 +949,14 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const { } void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint); pin_joint->set_pos_b(p_B); } -Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { +Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); @@ -1060,7 +965,6 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const { } RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1081,7 +985,6 @@ RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame } RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1102,15 +1005,14 @@ RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_ } void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_param(p_param, p_value); } -real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { +real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); @@ -1119,15 +1021,14 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p } void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint); hinge_joint->set_flag(p_flag, p_value); } -bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { +bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); @@ -1136,14 +1037,12 @@ bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) } void PhysicsServer3DSW::joint_set_solver_priority(RID p_joint, int p_priority) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); joint->set_priority(p_priority); } int PhysicsServer3DSW::joint_get_solver_priority(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); return joint->get_priority(); @@ -1177,14 +1076,12 @@ bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint) } PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, JOINT_PIN); return joint->get_type(); } RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1205,15 +1102,14 @@ RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_loca } void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint); slider_joint->set_param(p_param, p_value); } -real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { +real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); @@ -1222,7 +1118,6 @@ real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p } RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1243,15 +1138,14 @@ RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_ } void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint); cone_twist_joint->set_param(p_param, p_value); } -real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { +real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0); @@ -1260,7 +1154,6 @@ real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJoint } RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - Body3DSW *body_A = body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); @@ -1281,15 +1174,14 @@ RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform & } void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_param(p_axis, p_param, p_value); } -real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { +real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); @@ -1298,15 +1190,14 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi } void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint); generic_6dof_joint->set_flag(p_axis, p_flag, p_enable); } -bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { +bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { Joint3DSW *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); @@ -1315,11 +1206,9 @@ bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p } void PhysicsServer3DSW::free(RID p_rid) { - _update_shapes(); //just in case if (shape_owner.owns(p_rid)) { - Shape3DSW *shape = shape_owner.getornull(p_rid); while (shape->get_owners().size()) { @@ -1330,7 +1219,6 @@ void PhysicsServer3DSW::free(RID p_rid) { shape_owner.free(p_rid); memdelete(shape); } else if (body_owner.owns(p_rid)) { - Body3DSW *body = body_owner.getornull(p_rid); /* @@ -1344,7 +1232,6 @@ void PhysicsServer3DSW::free(RID p_rid) { body->set_space(nullptr); while (body->get_shape_count()) { - body->remove_shape(0); } @@ -1352,7 +1239,6 @@ void PhysicsServer3DSW::free(RID p_rid) { memdelete(body); } else if (area_owner.owns(p_rid)) { - Area3DSW *area = area_owner.getornull(p_rid); /* @@ -1363,14 +1249,12 @@ void PhysicsServer3DSW::free(RID p_rid) { area->set_space(nullptr); while (area->get_shape_count()) { - area->remove_shape(0); } area_owner.free(p_rid); memdelete(area); } else if (space_owner.owns(p_rid)) { - Space3DSW *space = space_owner.getornull(p_rid); while (space->get_objects().size()) { @@ -1385,29 +1269,24 @@ void PhysicsServer3DSW::free(RID p_rid) { space_owner.free(p_rid); memdelete(space); } else if (joint_owner.owns(p_rid)) { - Joint3DSW *joint = joint_owner.getornull(p_rid); for (int i = 0; i < joint->get_body_count(); i++) { - joint->get_body_ptr()[i]->remove_constraint(joint); } joint_owner.free(p_rid); memdelete(joint); } else { - ERR_FAIL_MSG("Invalid ID."); } }; void PhysicsServer3DSW::set_active(bool p_active) { - active = p_active; }; void PhysicsServer3DSW::init() { - doing_sync = true; last_step = 0.001; iterations = 8; // 8? @@ -1416,11 +1295,11 @@ void PhysicsServer3DSW::init() { }; void PhysicsServer3DSW::step(real_t p_step) { - #ifndef _3D_DISABLED - if (!active) + if (!active) { return; + } _update_shapes(); @@ -1433,7 +1312,6 @@ void PhysicsServer3DSW::step(real_t p_step) { active_objects = 0; collision_pairs = 0; for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step((Space3DSW *)E->get(), p_step, iterations); island_count += E->get()->get_island_count(); active_objects += E->get()->get_active_objects(); @@ -1442,16 +1320,12 @@ void PhysicsServer3DSW::step(real_t p_step) { #endif } -void PhysicsServer3DSW::sync(){ - -}; - void PhysicsServer3DSW::flush_queries() { - #ifndef _3D_DISABLED - if (!active) + if (!active) { return; + } doing_sync = true; @@ -1460,7 +1334,6 @@ void PhysicsServer3DSW::flush_queries() { uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - Space3DSW *space = (Space3DSW *)E->get(); space->call_queries(); } @@ -1468,7 +1341,6 @@ void PhysicsServer3DSW::flush_queries() { flushing_queries = false; if (EngineDebugger::is_profiling("servers")) { - uint64_t total_time[Space3DSW::ELAPSED_TIME_MAX]; static const char *time_name[Space3DSW::ELAPSED_TIME_MAX] = { "integrate_forces", @@ -1483,7 +1355,6 @@ void PhysicsServer3DSW::flush_queries() { } for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) { - for (int i = 0; i < Space3DSW::ELAPSED_TIME_MAX; i++) { total_time[i] += E->get()->get_elapsed_time(Space3DSW::ElapsedTime(i)); } @@ -1499,30 +1370,25 @@ void PhysicsServer3DSW::flush_queries() { values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg)); values.push_front("physics"); - EngineDebugger::profiler_add_frame_data("server", values); + EngineDebugger::profiler_add_frame_data("servers", values); } #endif }; void PhysicsServer3DSW::finish() { - memdelete(stepper); memdelete(direct_state); }; int PhysicsServer3DSW::get_process_info(ProcessInfo p_info) { - switch (p_info) { - case INFO_ACTIVE_OBJECTS: { - return active_objects; } break; case INFO_COLLISION_PAIRS: { return collision_pairs; } break; case INFO_ISLAND_COUNT: { - return island_count; } break; } @@ -1531,7 +1397,6 @@ int PhysicsServer3DSW::get_process_info(ProcessInfo p_info) { } void PhysicsServer3DSW::_update_shapes() { - while (pending_shape_update_list.first()) { pending_shape_update_list.first()->self()->_shape_changed(); pending_shape_update_list.remove(pending_shape_update_list.first()); @@ -1539,18 +1404,17 @@ void PhysicsServer3DSW::_update_shapes() { } void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { - CollCbkData *cbk = (CollCbkData *)p_userdata; - if (cbk->max == 0) + if (cbk->max == 0) { return; + } if (cbk->amount == cbk->max) { //find least deep real_t min_depth = 1e20; int min_depth_idx = 0; for (int i = 0; i < cbk->amount; i++) { - real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]); if (d < min_depth) { min_depth = d; @@ -1559,13 +1423,13 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 & } real_t d = p_point_A.distance_squared_to(p_point_B); - if (d < min_depth) + if (d < min_depth) { return; + } cbk->ptr[min_depth_idx * 2 + 0] = p_point_A; cbk->ptr[min_depth_idx * 2 + 1] = p_point_B; } else { - cbk->ptr[cbk->amount * 2 + 0] = p_point_A; cbk->ptr[cbk->amount * 2 + 1] = p_point_B; cbk->amount++; @@ -1583,7 +1447,3 @@ PhysicsServer3DSW::PhysicsServer3DSW() { active = true; flushing_queries = false; }; - -PhysicsServer3DSW::~PhysicsServer3DSW(){ - -}; diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h index 6e79d9eceb..26230ef674 100644 --- a/servers/physics_3d/physics_server_3d_sw.h +++ b/servers/physics_3d/physics_server_3d_sw.h @@ -39,7 +39,6 @@ #include "step_3d_sw.h" class PhysicsServer3DSW : public PhysicsServer3D { - GDCLASS(PhysicsServer3DSW, PhysicsServer3D); friend class PhysicsDirectSpaceState3DSW; @@ -74,7 +73,6 @@ public: static PhysicsServer3DSW *singleton; struct CollCbkData { - int max; int amount; Vector3 *ptr; @@ -307,7 +305,7 @@ public: virtual void soft_body_remove_all_pinned_points(RID p_body) {} virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {} - virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return 0; } + virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return false; } /* JOINT API */ @@ -367,7 +365,7 @@ public: virtual void set_active(bool p_active); virtual void init(); virtual void step(real_t p_step); - virtual void sync(); + virtual void sync() {} virtual void flush_queries(); virtual void finish(); @@ -376,7 +374,7 @@ public: int get_process_info(ProcessInfo p_info); PhysicsServer3DSW(); - ~PhysicsServer3DSW(); + ~PhysicsServer3DSW() {} }; #endif diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp index 61c32b779a..ca33241d29 100644 --- a/servers/physics_3d/shape_3d_sw.cpp +++ b/servers/physics_3d/shape_3d_sw.cpp @@ -30,7 +30,7 @@ #include "shape_3d_sw.h" -#include "core/math/geometry.h" +#include "core/math/geometry_3d.h" #include "core/math/quick_hull.h" #include "core/sort_array.h" @@ -48,7 +48,6 @@ void Shape3DSW::configure(const AABB &p_aabb) { } Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { - Vector3 res; int amnt; get_supports(p_normal, 1, &res, amnt); @@ -56,7 +55,6 @@ Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const { } void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) { - Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner); if (E) { E->get()++; @@ -66,7 +64,6 @@ void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) { } void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) { - Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner); ERR_FAIL_COND(!E); E->get()--; @@ -76,7 +73,6 @@ void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) { } bool Shape3DSW::is_owner(ShapeOwner3DSW *p_owner) const { - return owners.has(p_owner); } @@ -85,48 +81,41 @@ const Map<ShapeOwner3DSW *, int> &Shape3DSW::get_owners() const { } Shape3DSW::Shape3DSW() { - custom_bias = 0; configured = false; } Shape3DSW::~Shape3DSW() { - ERR_FAIL_COND(owners.size()); } Plane PlaneShape3DSW::get_plane() const { - return plane; } void PlaneShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - // gibberish, a plane is infinity r_min = -1e7; r_max = 1e7; } Vector3 PlaneShape3DSW::get_support(const Vector3 &p_normal) const { - return p_normal * 1e15; } bool PlaneShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - bool inters = plane.intersects_segment(p_begin, p_end, &r_result); - if (inters) + if (inters) { r_normal = plane.normal; + } return inters; } bool PlaneShape3DSW::intersect_point(const Vector3 &p_point) const { - return plane.distance_to(p_point) < 0; } Vector3 PlaneShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - if (plane.is_point_over(p_point)) { return plane.project(p_point); } else { @@ -135,23 +124,19 @@ Vector3 PlaneShape3DSW::get_closest_point_to(const Vector3 &p_point) const { } Vector3 PlaneShape3DSW::get_moment_of_inertia(real_t p_mass) const { - return Vector3(); //wtf } void PlaneShape3DSW::_setup(const Plane &p_plane) { - plane = p_plane; configure(AABB(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); } void PlaneShape3DSW::set_data(const Variant &p_data) { - _setup(p_data); } Variant PlaneShape3DSW::get_data() const { - return plane; } @@ -161,7 +146,6 @@ PlaneShape3DSW::PlaneShape3DSW() { // real_t RayShape3DSW::get_length() const { - return length; } @@ -170,24 +154,21 @@ bool RayShape3DSW::get_slips_on_slope() const { } void RayShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - // don't think this will be even used r_min = 0; r_max = 1; } Vector3 RayShape3DSW::get_support(const Vector3 &p_normal) const { - - if (p_normal.z > 0) + if (p_normal.z > 0) { return Vector3(0, 0, length); - else + } else { return Vector3(0, 0, 0); + } } void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { - r_amount = 2; r_supports[0] = Vector3(0, 0, 0); r_supports[1] = Vector3(0, 0, length); @@ -201,45 +182,38 @@ void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s } bool RayShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - return false; //simply not possible } bool RayShape3DSW::intersect_point(const Vector3 &p_point) const { - return false; //simply not possible } Vector3 RayShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - Vector3 s[2] = { Vector3(0, 0, 0), Vector3(0, 0, length) }; - return Geometry::get_closest_point_to_segment(p_point, s); + return Geometry3D::get_closest_point_to_segment(p_point, s); } Vector3 RayShape3DSW::get_moment_of_inertia(real_t p_mass) const { - return Vector3(); } void RayShape3DSW::_setup(real_t p_length, bool p_slips_on_slope) { - length = p_length; slips_on_slope = p_slips_on_slope; configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); } void RayShape3DSW::set_data(const Variant &p_data) { - Dictionary d = p_data; _setup(d["length"], d["slips_on_slope"]); } Variant RayShape3DSW::get_data() const { - Dictionary d; d["length"] = length; d["slips_on_slope"] = slips_on_slope; @@ -247,7 +221,6 @@ Variant RayShape3DSW::get_data() const { } RayShape3DSW::RayShape3DSW() { - length = 1; slips_on_slope = false; } @@ -255,12 +228,10 @@ RayShape3DSW::RayShape3DSW() { /********** SPHERE *************/ real_t SphereShape3DSW::get_radius() const { - return radius; } void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - real_t d = p_normal.dot(p_transform.origin); // figure out scale at point @@ -272,66 +243,56 @@ void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_ } Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const { - return p_normal * radius; } void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - *r_supports = p_normal * radius; r_amount = 1; } bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - - return Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal); + return Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal); } bool SphereShape3DSW::intersect_point(const Vector3 &p_point) const { - return p_point.length() < radius; } Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - Vector3 p = p_point; float l = p.length(); - if (l < radius) + if (l < radius) { return p_point; + } return (p / l) * radius; } Vector3 SphereShape3DSW::get_moment_of_inertia(real_t p_mass) const { - real_t s = 0.4 * p_mass * radius * radius; return Vector3(s, s, s); } void SphereShape3DSW::_setup(real_t p_radius) { - radius = p_radius; configure(AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); } void SphereShape3DSW::set_data(const Variant &p_data) { - _setup(p_data); } Variant SphereShape3DSW::get_data() const { - return radius; } SphereShape3DSW::SphereShape3DSW() { - radius = 0; } /********** BOX *************/ void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - // no matter the angle, the box is mirrored anyway Vector3 local_normal = p_transform.basis.xform_inv(p_normal); @@ -343,7 +304,6 @@ void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_tra } Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { - Vector3 point( (p_normal.x < 0) ? -half_extents.x : half_extents.x, (p_normal.y < 0) ? -half_extents.y : half_extents.y, @@ -353,17 +313,14 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const { } void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - static const int next[3] = { 1, 2, 0 }; static const int next2[3] = { 2, 0, 1 }; for (int i = 0; i < 3; i++) { - Vector3 axis; axis[i] = 1.0; real_t dot = p_normal.dot(axis); if (Math::abs(dot) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { - //Vector3 axis_b; bool neg = dot < 0; @@ -384,7 +341,6 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s }; for (int j = 0; j < 4; j++) { - point[i_n] = sign[j][0] * half_extents[i_n]; point[i_n2] = sign[j][1] * half_extents[i_n2]; r_supports[j] = neg ? -point : point; @@ -402,12 +358,10 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s } for (int i = 0; i < 3; i++) { - Vector3 axis; axis[i] = 1.0; if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { - r_amount = 2; int i_n = next[i]; @@ -440,24 +394,20 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s } bool BoxShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - AABB aabb(-half_extents, half_extents * 2.0); return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal); } bool BoxShape3DSW::intersect_point(const Vector3 &p_point) const { - return (Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y && Math::abs(p_point.z) < half_extents.z); } Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - int outside = 0; Vector3 min_point; for (int i = 0; i < 3; i++) { - if (Math::abs(p_point[i]) > half_extents[i]) { outside++; if (outside == 1) { @@ -471,11 +421,13 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { } } - if (!outside) + if (!outside) { return p_point; //it's inside, don't do anything else + } - if (outside == 1) //if only above one plane, this plane clearly wins + if (outside == 1) { //if only above one plane, this plane clearly wins return min_point; + } //check segments float min_distance = 1e20; @@ -486,11 +438,10 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { }; for (int i = 0; i < 3; i++) { - s[1] = closest_vertex; s[1][i] = -s[1][i]; //edge - Vector3 closest_edge = Geometry::get_closest_point_to_segment(p_point, s); + Vector3 closest_edge = Geometry3D::get_closest_point_to_segment(p_point, s); float d = p_point.distance_to(closest_edge); if (d < min_distance) { @@ -503,7 +454,6 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const { } Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const { - real_t lx = half_extents.x; real_t ly = half_extents.y; real_t lz = half_extents.z; @@ -512,19 +462,16 @@ Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const { } void BoxShape3DSW::_setup(const Vector3 &p_half_extents) { - half_extents = p_half_extents.abs(); configure(AABB(-half_extents, half_extents * 2)); } void BoxShape3DSW::set_data(const Variant &p_data) { - _setup(p_data); } Variant BoxShape3DSW::get_data() const { - return half_extents; } @@ -534,7 +481,6 @@ BoxShape3DSW::BoxShape3DSW() { /********** CAPSULE *************/ void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - Vector3 n = p_transform.basis.xform_inv(p_normal).normalized(); real_t h = (n.z > 0) ? height : -height; @@ -546,7 +492,6 @@ void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p } Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { - Vector3 n = p_normal; real_t h = (n.z > 0) ? height : -height; @@ -557,13 +502,11 @@ Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const { } void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - Vector3 n = p_normal; real_t d = n.z; if (Math::abs(d) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { - // make it flat n.z = 0.0; n.normalize(); @@ -576,7 +519,6 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 r_supports[1].z -= height * 0.5; } else { - real_t h = (d > 0) ? height : -height; n *= radius; @@ -587,7 +529,6 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 } bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - Vector3 norm = (p_end - p_begin).normalized(); real_t min_d = 1e20; @@ -599,7 +540,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & // test against cylinder and spheres :-| - collided = Geometry::segment_intersects_cylinder(p_begin, p_end, height, radius, &auxres, &auxn); + collided = Geometry3D::segment_intersects_cylinder(p_begin, p_end, height, radius, &auxres, &auxn); if (collided) { real_t d = norm.dot(auxres); @@ -611,7 +552,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & } } - collided = Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * 0.5), radius, &auxres, &auxn); + collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * 0.5), radius, &auxres, &auxn); if (collided) { real_t d = norm.dot(auxres); @@ -623,7 +564,7 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & } } - collided = Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * -0.5), radius, &auxres, &auxn); + collided = Geometry3D::segment_intersects_sphere(p_begin, p_end, Vector3(0, 0, height * -0.5), radius, &auxres, &auxn); if (collided) { real_t d = norm.dot(auxres); @@ -637,7 +578,6 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & } if (collision) { - r_result = res; r_normal = n; } @@ -645,7 +585,6 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 & } bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const { - if (Math::abs(p_point.z) < height * 0.5) { return Vector3(p_point.x, p_point.y, 0).length() < radius; } else { @@ -656,22 +595,21 @@ bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const { } Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - Vector3 s[2] = { Vector3(0, 0, -height * 0.5), Vector3(0, 0, height * 0.5), }; - Vector3 p = Geometry::get_closest_point_to_segment(p_point, s); + Vector3 p = Geometry3D::get_closest_point_to_segment(p_point, s); - if (p.distance_to(p_point) < radius) + if (p.distance_to(p_point) < radius) { return p_point; + } return p + (p_point - p).normalized() * radius; } Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const { - // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -682,14 +620,12 @@ Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const { } void CapsuleShape3DSW::_setup(real_t p_height, real_t p_radius) { - height = p_height; radius = p_radius; configure(AABB(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0))); } void CapsuleShape3DSW::set_data(const Variant &p_data) { - Dictionary d = p_data; ERR_FAIL_COND(!d.has("radius")); ERR_FAIL_COND(!d.has("height")); @@ -697,7 +633,6 @@ void CapsuleShape3DSW::set_data(const Variant &p_data) { } Variant CapsuleShape3DSW::get_data() const { - Dictionary d; d["radius"] = radius; d["height"] = height; @@ -705,46 +640,45 @@ Variant CapsuleShape3DSW::get_data() const { } CapsuleShape3DSW::CapsuleShape3DSW() { - height = radius = 0; } /********** CONVEX POLYGON *************/ void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - int vertex_count = mesh.vertices.size(); - if (vertex_count == 0) + if (vertex_count == 0) { return; + } const Vector3 *vrts = &mesh.vertices[0]; for (int i = 0; i < vertex_count; i++) { - real_t d = p_normal.dot(p_transform.xform(vrts[i])); - if (i == 0 || d > r_max) + if (i == 0 || d > r_max) { r_max = d; - if (i == 0 || d < r_min) + } + if (i == 0 || d < r_min) { r_min = d; + } } } Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { - Vector3 n = p_normal; int vert_support_idx = -1; real_t support_max = 0; int vertex_count = mesh.vertices.size(); - if (vertex_count == 0) + if (vertex_count == 0) { return Vector3(); + } const Vector3 *vrts = &mesh.vertices[0]; for (int i = 0; i < vertex_count; i++) { - real_t d = n.dot(vrts[i]); if (i == 0 || d > support_max) { @@ -757,11 +691,10 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const { } void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int ec = mesh.edges.size(); const Vector3 *vertices = mesh.vertices.ptr(); @@ -772,7 +705,6 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve int vtx = 0; for (int i = 0; i < vc; i++) { - real_t d = p_normal.dot(vertices[i]); if (i == 0 || d > max) { @@ -782,9 +714,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve } for (int i = 0; i < fc; i++) { - if (faces[i].plane.normal.dot(p_normal) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { - int ic = faces[i].indices.size(); const int *ind = faces[i].indices.ptr(); @@ -796,12 +726,12 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve } } - if (!valid) + if (!valid) { continue; + } int m = MIN(p_max, ic); for (int j = 0; j < m; j++) { - r_supports[j] = vertices[ind[j]]; } r_amount = m; @@ -810,11 +740,9 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve } for (int i = 0; i < ec; i++) { - real_t dot = (vertices[edges[i].a] - vertices[edges[i].b]).normalized().dot(p_normal); dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) { - r_amount = 2; r_supports[0] = vertices[edges[i].a]; r_supports[1] = vertices[edges[i].b]; @@ -827,8 +755,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve } bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); const Vector3 *vertices = mesh.vertices.ptr(); @@ -838,15 +765,14 @@ bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec bool col = false; for (int i = 0; i < fc; i++) { - - if (faces[i].plane.normal.dot(n) > 0) + if (faces[i].plane.normal.dot(n) > 0) { continue; //opposing face + } int ic = faces[i].indices.size(); const int *ind = faces[i].indices.ptr(); for (int j = 1; j < ic - 1; j++) { - Face3 f(vertices[ind[0]], vertices[ind[j]], vertices[ind[j + 1]]); Vector3 result; if (f.intersects_segment(p_begin, p_end, &result)) { @@ -867,30 +793,28 @@ bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec } bool ConvexPolygonShape3DSW::intersect_point(const Vector3 &p_point) const { - - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); for (int i = 0; i < fc; i++) { - - if (faces[i].plane.distance_to(p_point) >= 0) + if (faces[i].plane.distance_to(p_point) >= 0) { return false; + } } return true; } Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - - const Geometry::MeshData::Face *faces = mesh.faces.ptr(); + const Geometry3D::MeshData::Face *faces = mesh.faces.ptr(); int fc = mesh.faces.size(); const Vector3 *vertices = mesh.vertices.ptr(); bool all_inside = true; for (int i = 0; i < fc; i++) { - - if (!faces[i].plane.is_point_over(p_point)) + if (!faces[i].plane.is_point_over(p_point)) { continue; + } all_inside = false; bool is_inside = true; @@ -898,7 +822,6 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con const int *indices = faces[i].indices.ptr(); for (int j = 0; j < ic; j++) { - Vector3 a = vertices[indices[j]]; Vector3 b = vertices[indices[(j + 1) % ic]]; Vector3 n = (a - b).cross(faces[i].plane.normal).normalized(); @@ -921,16 +844,15 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con Vector3 min_point; //check edges - const Geometry::MeshData::Edge *edges = mesh.edges.ptr(); + const Geometry3D::MeshData::Edge *edges = mesh.edges.ptr(); int ec = mesh.edges.size(); for (int i = 0; i < ec; i++) { - Vector3 s[2] = { vertices[edges[i].a], vertices[edges[i].b] }; - Vector3 closest = Geometry::get_closest_point_to_segment(p_point, s); + Vector3 closest = Geometry3D::get_closest_point_to_segment(p_point, s); float d = closest.distance_to(p_point); if (d < min_distance) { min_distance = d; @@ -942,7 +864,6 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con } Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { - // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -953,31 +874,29 @@ Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { } void ConvexPolygonShape3DSW::_setup(const Vector<Vector3> &p_vertices) { - Error err = QuickHull::build(p_vertices, mesh); - if (err != OK) + if (err != OK) { ERR_PRINT("Failed to build QuickHull"); + } AABB _aabb; for (int i = 0; i < mesh.vertices.size(); i++) { - - if (i == 0) + if (i == 0) { _aabb.position = mesh.vertices[i]; - else + } else { _aabb.expand_to(mesh.vertices[i]); + } } configure(_aabb); } void ConvexPolygonShape3DSW::set_data(const Variant &p_data) { - _setup(p_data); } Variant ConvexPolygonShape3DSW::get_data() const { - return mesh.vertices; } @@ -987,27 +906,25 @@ ConvexPolygonShape3DSW::ConvexPolygonShape3DSW() { /********** FACE POLYGON *************/ void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - for (int i = 0; i < 3; i++) { - Vector3 v = p_transform.xform(vertex[i]); real_t d = p_normal.dot(v); - if (i == 0 || d > r_max) + if (i == 0 || d > r_max) { r_max = d; + } - if (i == 0 || d < r_min) + if (i == 0 || d < r_min) { r_min = d; + } } } Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { - int vert_support_idx = -1; real_t support_max = 0; for (int i = 0; i < 3; i++) { - real_t d = p_normal.dot(vertex[i]); if (i == 0 || d > support_max) { @@ -1020,15 +937,12 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const { } void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { - Vector3 n = p_normal; /** TEST FACE AS SUPPORT **/ if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { - r_amount = 3; for (int i = 0; i < 3; i++) { - r_supports[i] = vertex[i]; } return; @@ -1040,7 +954,6 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ real_t support_max = 0; for (int i = 0; i < 3; i++) { - real_t d = n.dot(vertex[i]); if (i == 0 || d > support_max) { @@ -1052,16 +965,15 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ /** TEST EDGES AS SUPPORT **/ for (int i = 0; i < 3; i++) { - int nx = (i + 1) % 3; - if (i != vert_support_idx && nx != vert_support_idx) + if (i != vert_support_idx && nx != vert_support_idx) { continue; + } // check if edge is valid as a support real_t dot = (vertex[i] - vertex[nx]).normalized().dot(n); dot = ABS(dot); if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { - r_amount = 2; r_supports[0] = vertex[i]; r_supports[1] = vertex[nx]; @@ -1074,8 +986,7 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_ } bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - - bool c = Geometry::segment_intersects_triangle(p_begin, p_end, vertex[0], vertex[1], vertex[2], &r_result); + bool c = Geometry3D::segment_intersects_triangle(p_begin, p_end, vertex[0], vertex[1], vertex[2], &r_result); if (c) { r_normal = Plane(vertex[0], vertex[1], vertex[2]).normal; if (r_normal.dot(p_end - p_begin) > 0) { @@ -1087,36 +998,29 @@ bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_e } bool FaceShape3DSW::intersect_point(const Vector3 &p_point) const { - return false; //face is flat } Vector3 FaceShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - return Face3(vertex[0], vertex[1], vertex[2]).get_closest_point_to(p_point); } Vector3 FaceShape3DSW::get_moment_of_inertia(real_t p_mass) const { - return Vector3(); // Sorry, but i don't think anyone cares, FaceShape! } FaceShape3DSW::FaceShape3DSW() { - configure(AABB()); } Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const { - Vector<Vector3> rfaces; rfaces.resize(faces.size() * 3); for (int i = 0; i < faces.size(); i++) { - Face f = faces.get(i); for (int j = 0; j < 3; j++) { - rfaces.set(i * 3 + j, vertices.get(f.indices[j])); } } @@ -1125,7 +1029,6 @@ Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const { } void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - int count = vertices.size(); if (count == 0) { r_min = 0; @@ -1135,21 +1038,22 @@ void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Trans const Vector3 *vptr = vertices.ptr(); for (int i = 0; i < count; i++) { - real_t d = p_normal.dot(p_transform.xform(vptr[i])); - if (i == 0 || d > r_max) + if (i == 0 || d > r_max) { r_max = d; - if (i == 0 || d < r_min) + } + if (i == 0 || d < r_min) { r_min = d; + } } } Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const { - int count = vertices.size(); - if (count == 0) + if (count == 0) { return Vector3(); + } const Vector3 *vptr = vertices.ptr(); @@ -1159,7 +1063,6 @@ Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const { real_t support_max = 0; for (int i = 0; i < count; i++) { - real_t d = n.dot(vptr[i]); if (i == 0 || d > support_max) { @@ -1172,7 +1075,6 @@ Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const { } void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_params) const { - const BVH *bvh = &p_params->bvh[p_idx]; /* @@ -1182,12 +1084,10 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par //printf("addr: %p\n",bvh); if (!bvh->aabb.intersects_segment(p_params->from, p_params->to)) { - return; } if (bvh->face_index >= 0) { - Vector3 res; Vector3 vertices[3] = { p_params->vertices[p_params->faces[bvh->face_index].indices[0]], @@ -1195,18 +1095,16 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par p_params->vertices[p_params->faces[bvh->face_index].indices[2]] }; - if (Geometry::segment_intersects_triangle( + if (Geometry3D::segment_intersects_triangle( p_params->from, p_params->to, vertices[0], vertices[1], vertices[2], &res)) { - real_t d = p_params->dir.dot(res) - p_params->dir.dot(p_params->from); //TODO, seems segmen/triangle intersection is broken :( if (d > 0 && d < p_params->min_d) { - p_params->min_d = d; p_params->result = res; p_params->normal = Plane(vertices[0], vertices[1], vertices[2]).normal; @@ -1215,18 +1113,19 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par } } else { - - if (bvh->left >= 0) + if (bvh->left >= 0) { _cull_segment(bvh->left, p_params); - if (bvh->right >= 0) + } + if (bvh->right >= 0) { _cull_segment(bvh->right, p_params); + } } } bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - - if (faces.size() == 0) + if (faces.size() == 0) { return false; + } // unlock data const Face *fr = faces.ptr(); @@ -1248,35 +1147,30 @@ bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Ve _cull_segment(0, ¶ms); if (params.collisions > 0) { - r_result = params.result; r_normal = params.normal; return true; } else { - return false; } } bool ConcavePolygonShape3DSW::intersect_point(const Vector3 &p_point) const { - return false; //face is flat } Vector3 ConcavePolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - return Vector3(); } void ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const { - const BVH *bvh = &p_params->bvh[p_idx]; - if (!p_params->aabb.intersects(bvh->aabb)) + if (!p_params->aabb.intersects(bvh->aabb)) { return; + } if (bvh->face_index >= 0) { - const Face *f = &p_params->faces[bvh->face_index]; FaceShape3DSW *face = p_params->face; face->normal = f->normal; @@ -1286,24 +1180,21 @@ void ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const { p_params->callback(p_params->userdata, face); } else { - if (bvh->left >= 0) { - _cull(bvh->left, p_params); } if (bvh->right >= 0) { - _cull(bvh->right, p_params); } } } void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const { - // make matrix local to concave - if (faces.size() == 0) + if (faces.size() == 0) { return; + } AABB local_aabb = p_local_aabb; @@ -1328,7 +1219,6 @@ void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback } Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { - // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -1339,38 +1229,30 @@ Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const { } struct _VolumeSW_BVH_Element { - AABB aabb; Vector3 center; int face_index; }; struct _VolumeSW_BVH_CompareX { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { - return a.center.x < b.center.x; } }; struct _VolumeSW_BVH_CompareY { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { - return a.center.y < b.center.y; } }; struct _VolumeSW_BVH_CompareZ { - _FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const { - return a.center.z < b.center.z; } }; struct _VolumeSW_BVH { - AABB aabb; _VolumeSW_BVH *left; _VolumeSW_BVH *right; @@ -1379,7 +1261,6 @@ struct _VolumeSW_BVH { }; _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_size, int &count) { - _VolumeSW_BVH *bvh = memnew(_VolumeSW_BVH); if (p_size == 1) { @@ -1391,34 +1272,29 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz count++; return bvh; } else { - bvh->face_index = -1; } AABB aabb; for (int i = 0; i < p_size; i++) { - - if (i == 0) + if (i == 0) { aabb = p_elements[i].aabb; - else + } else { aabb.merge_with(p_elements[i].aabb); + } } bvh->aabb = aabb; switch (aabb.get_longest_axis_index()) { - case 0: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareX> sort_x; sort_x.sort(p_elements, p_size); } break; case 1: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareY> sort_y; sort_y.sort(p_elements, p_size); } break; case 2: { - SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareZ> sort_z; sort_z.sort(p_elements, p_size); } break; @@ -1434,7 +1310,6 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz } void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx) { - int idx = p_idx; p_bvh_array[idx].aabb = p_bvh_tree->aabb; @@ -1446,7 +1321,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar _fill_bvh(p_bvh_tree->left, p_bvh_array, p_idx); } else { - p_bvh_array[p_idx].left = -1; } @@ -1455,7 +1329,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar _fill_bvh(p_bvh_tree->right, p_bvh_array, p_idx); } else { - p_bvh_array[p_idx].right = -1; } @@ -1463,7 +1336,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar } void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) { - int src_face_count = p_faces.size(); if (src_face_count == 0) { configure(AABB()); @@ -1489,7 +1361,6 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) { AABB _aabb; for (int i = 0; i < src_face_count; i++) { - Face3 face(facesr[i * 3 + 0], facesr[i * 3 + 1], facesr[i * 3 + 2]); bvh_arrayw[i].aabb = face.get_aabb(); @@ -1502,10 +1373,11 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) { verticesw[i * 3 + 0] = face.vertex[0]; verticesw[i * 3 + 1] = face.vertex[1]; verticesw[i * 3 + 2] = face.vertex[2]; - if (i == 0) + if (i == 0) { _aabb = bvh_arrayw[i].aabb; - else + } else { _aabb.merge_with(bvh_arrayw[i].aabb); + } } int count = 0; @@ -1522,12 +1394,10 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) { } void ConcavePolygonShape3DSW::set_data(const Variant &p_data) { - _setup(p_data); } Variant ConcavePolygonShape3DSW::get_data() const { - return get_faces(); } @@ -1537,36 +1407,32 @@ ConcavePolygonShape3DSW::ConcavePolygonShape3DSW() { /* HEIGHT MAP SHAPE */ Vector<real_t> HeightMapShape3DSW::get_heights() const { - return heights; } -int HeightMapShape3DSW::get_width() const { +int HeightMapShape3DSW::get_width() const { return width; } -int HeightMapShape3DSW::get_depth() const { +int HeightMapShape3DSW::get_depth() const { return depth; } -real_t HeightMapShape3DSW::get_cell_size() const { +real_t HeightMapShape3DSW::get_cell_size() const { return cell_size; } void HeightMapShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - //not very useful, but not very used either p_transform.xform(get_aabb()).project_range_in_plane(Plane(p_normal, 0), r_min, r_max); } Vector3 HeightMapShape3DSW::get_support(const Vector3 &p_normal) const { - //not very useful, but not very used either return get_aabb().get_support(p_normal); } bool HeightMapShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const { - return false; } @@ -1575,7 +1441,6 @@ bool HeightMapShape3DSW::intersect_point(const Vector3 &p_point) const { } Vector3 HeightMapShape3DSW::get_closest_point_to(const Vector3 &p_point) const { - return Vector3(); } @@ -1583,7 +1448,6 @@ void HeightMapShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback, voi } Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const { - // use bad AABB approximation Vector3 extents = get_aabb().size * 0.5; @@ -1594,7 +1458,6 @@ Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const { } void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_depth, real_t p_cell_size) { - heights = p_heights; width = p_width; depth = p_depth; @@ -1605,16 +1468,15 @@ void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_dep AABB aabb; for (int i = 0; i < depth; i++) { - for (int j = 0; j < width; j++) { - real_t h = r[i * width + j]; Vector3 pos(j * cell_size, h, i * cell_size); - if (i == 0 || j == 0) + if (i == 0 || j == 0) { aabb.position = pos; - else + } else { aabb.expand_to(pos); + } } } @@ -1622,7 +1484,6 @@ void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_dep } void HeightMapShape3DSW::set_data(const Variant &p_data) { - ERR_FAIL_COND(p_data.get_type() != Variant::DICTIONARY); Dictionary d = p_data; ERR_FAIL_COND(!d.has("width")); @@ -1643,12 +1504,10 @@ void HeightMapShape3DSW::set_data(const Variant &p_data) { } Variant HeightMapShape3DSW::get_data() const { - ERR_FAIL_V(Variant()); } HeightMapShape3DSW::HeightMapShape3DSW() { - width = 0; depth = 0; cell_size = 0; diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h index dd29ec849b..2a2cd42255 100644 --- a/servers/physics_3d/shape_3d_sw.h +++ b/servers/physics_3d/shape_3d_sw.h @@ -31,7 +31,7 @@ #ifndef SHAPE_SW_H #define SHAPE_SW_H -#include "core/math/geometry.h" +#include "core/math/geometry_3d.h" #include "servers/physics_server_3d.h" /* @@ -56,7 +56,6 @@ public: }; class Shape3DSW { - RID self; AABB aabb; bool configured; @@ -108,7 +107,6 @@ public: }; class ConcaveShape3DSW : public Shape3DSW { - public: virtual bool is_concave() const { return true; } typedef void (*Callback)(void *p_userdata, Shape3DSW *p_convex); @@ -120,7 +118,6 @@ public: }; class PlaneShape3DSW : public Shape3DSW { - Plane plane; void _setup(const Plane &p_plane); @@ -146,7 +143,6 @@ public: }; class RayShape3DSW : public Shape3DSW { - real_t length; bool slips_on_slope; @@ -175,7 +171,6 @@ public: }; class SphereShape3DSW : public Shape3DSW { - real_t radius; void _setup(real_t p_radius); @@ -203,7 +198,6 @@ public: }; class BoxShape3DSW : public Shape3DSW { - Vector3 half_extents; void _setup(const Vector3 &p_half_extents); @@ -229,7 +223,6 @@ public: }; class CapsuleShape3DSW : public Shape3DSW { - real_t height; real_t radius; @@ -259,13 +252,12 @@ public: }; struct ConvexPolygonShape3DSW : public Shape3DSW { - - Geometry::MeshData mesh; + Geometry3D::MeshData mesh; void _setup(const Vector<Vector3> &p_vertices); public: - const Geometry::MeshData &get_mesh() const { return mesh; } + const Geometry3D::MeshData &get_mesh() const { return mesh; } virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; } @@ -291,7 +283,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { // always a trimesh struct Face { - Vector3 normal; int indices[3]; }; @@ -300,7 +291,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { Vector<Vector3> vertices; struct BVH { - AABB aabb; int left; int right; @@ -311,7 +301,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { Vector<BVH> bvh; struct _CullParams { - AABB aabb; Callback callback; void *userdata; @@ -322,7 +311,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW { }; struct _SegmentCullParams { - Vector3 from; Vector3 to; const Face *faces; @@ -366,7 +354,6 @@ public: }; struct HeightMapShape3DSW : public ConcaveShape3DSW { - Vector<real_t> heights; int width; int depth; @@ -403,7 +390,6 @@ public: //used internally struct FaceShape3DSW : public Shape3DSW { - Vector3 normal; //cache Vector3 vertex[3]; @@ -427,14 +413,12 @@ struct FaceShape3DSW : public Shape3DSW { }; struct MotionShape3DSW : public Shape3DSW { - Shape3DSW *shape; Vector3 motion; virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; } void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const { - Vector3 cast = p_transform.basis.xform(motion); real_t mina, maxa; real_t minb, maxb; @@ -447,7 +431,6 @@ struct MotionShape3DSW : public Shape3DSW { } Vector3 get_support(const Vector3 &p_normal) const { - Vector3 support = shape->get_support(p_normal); if (p_normal.dot(motion) > 0) { support += motion; diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp index bd8e89a8f5..48f250ba35 100644 --- a/servers/physics_3d/space_3d_sw.cpp +++ b/servers/physics_3d/space_3d_sw.cpp @@ -35,22 +35,22 @@ #include "physics_server_3d_sw.h" _FORCE_INLINE_ static bool _can_collide_with(CollisionObject3DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - if (!(p_object->get_collision_layer() & p_collision_mask)) { return false; } - if (p_object->get_type() == CollisionObject3DSW::TYPE_AREA && !p_collide_with_areas) + if (p_object->get_type() == CollisionObject3DSW::TYPE_AREA && !p_collide_with_areas) { return false; + } - if (p_object->get_type() == CollisionObject3DSW::TYPE_BODY && !p_collide_with_bodies) + if (p_object->get_type() == CollisionObject3DSW::TYPE_BODY && !p_collide_with_bodies) { return false; + } return true; } int PhysicsDirectSpaceState3DSW::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, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); int cc = 0; @@ -58,17 +58,19 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe //Transform ai = p_xform.affine_inverse(); for (int i = 0; i < amount; i++) { - - if (cc >= p_result_max) + if (cc >= p_result_max) { break; + } - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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) - if (p_exclude.has(space->intersection_query_results[i]->get_self())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; @@ -76,14 +78,16 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); inv_xform.affine_invert(); - if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point))) + if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point))) { continue; + } r_results[cc].collider_id = col_obj->get_instance_id(); - if (r_results[cc].collider_id.is_valid()) + if (r_results[cc].collider_id.is_valid()) { r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); - else + } else { r_results[cc].collider = nullptr; + } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; @@ -94,7 +98,6 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe } bool PhysicsDirectSpaceState3DSW::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); Vector3 begin, end; @@ -114,15 +117,17 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec real_t min_d = 1e10; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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 && !(space->intersection_query_results[i]->is_ray_pickable())) + if (p_pick_ray && !(space->intersection_query_results[i]->is_ray_pickable())) { continue; + } - if (p_exclude.has(space->intersection_query_results[i]->get_self())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; @@ -137,14 +142,12 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec Vector3 shape_point, shape_normal; if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) { - Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); shape_point = xform.xform(shape_point); real_t ld = normal.dot(shape_point); if (ld < min_d) { - min_d = ld; res_point = shape_point; res_normal = inv_xform.basis.xform_inv(shape_normal).normalized(); @@ -155,14 +158,16 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec } } - if (!collided) + if (!collided) { return false; + } r_result.collider_id = res_obj->get_instance_id(); - if (r_result.collider_id.is_valid()) + if (r_result.collider_id.is_valid()) { r_result.collider = ObjectDB::get_instance(r_result.collider_id); - else + } else { r_result.collider = nullptr; + } r_result.normal = res_normal; r_result.position = res_point; r_result.rid = res_obj->get_self(); @@ -172,9 +177,9 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec } int PhysicsDirectSpaceState3DSW::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) + if (p_result_max <= 0) { return 0; + } Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -188,30 +193,34 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans //Transform ai = p_xform.affine_inverse(); for (int i = 0; i < amount; i++) { - - if (cc >= p_result_max) + if (cc >= p_result_max) { break; + } - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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) - if (p_exclude.has(space->intersection_query_results[i]->get_self())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) + if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) { continue; + } if (r_results) { r_results[cc].collider_id = col_obj->get_instance_id(); - if (r_results[cc].collider_id.is_valid()) + if (r_results[cc].collider_id.is_valid()) { r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id); - else + } else { r_results[cc].collider = nullptr; + } r_results[cc].rid = col_obj->get_self(); r_results[cc].shape = shape_idx; } @@ -223,7 +232,6 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans } bool PhysicsDirectSpaceState3DSW::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) { - Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, false); @@ -246,12 +254,13 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor Vector3 closest_A, closest_B; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + 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())) + if (p_exclude.has(space->intersection_query_results[i]->get_self())) { continue; //ignore excluded + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; @@ -290,10 +299,8 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor bool collided = !CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep); if (collided) { - hi = ofs; } else { - point_A = lA; point_B = lB; low = ofs; @@ -329,9 +336,9 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor } bool PhysicsDirectSpaceState3DSW::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; + if (p_result_max <= 0) { + return false; + } Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -353,9 +360,9 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ PhysicsServer3DSW::CollCbkData *cbkptr = &cbk; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { continue; + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; @@ -375,7 +382,6 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_ } struct _RestCallbackData { - const CollisionObject3DSW *object; const CollisionObject3DSW *best_object; int shape; @@ -387,15 +393,16 @@ struct _RestCallbackData { }; static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { - _RestCallbackData *rd = (_RestCallbackData *)p_userdata; Vector3 contact_rel = p_point_B - p_point_A; real_t len = contact_rel.length(); - if (len < rd->min_allowed_depth) + if (len < rd->min_allowed_depth) { return; - if (len <= rd->best_len) + } + if (len <= rd->best_len) { return; + } rd->best_len = len; rd->best_contact = p_point_B; @@ -403,8 +410,8 @@ 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 PhysicsDirectSpaceState3DSW::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) { +bool PhysicsDirectSpaceState3DSW::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) { Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0); @@ -420,25 +427,28 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap rcd.min_allowed_depth = space->test_motion_min_contact_depth; for (int i = 0; i < amount; i++) { - - if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) + if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) { continue; + } const CollisionObject3DSW *col_obj = space->intersection_query_results[i]; int shape_idx = space->intersection_query_subindex_results[i]; - if (p_exclude.has(col_obj->get_self())) + if (p_exclude.has(col_obj->get_self())) { continue; + } rcd.object = col_obj; rcd.shape = shape_idx; bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); - if (!sc) + if (!sc) { continue; + } } - if (rcd.best_len == 0 || !rcd.best_object) + if (rcd.best_len == 0 || !rcd.best_object) { return false; + } r_info->collider_id = rcd.best_object->get_instance_id(); r_info->shape = rcd.best_shape; @@ -446,7 +456,6 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap r_info->point = rcd.best_contact; r_info->rid = rcd.best_object->get_self(); if (rcd.best_object->get_type() == CollisionObject3DSW::TYPE_BODY) { - const Body3DSW *body = static_cast<const Body3DSW *>(rcd.best_object); r_info->linear_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - rcd.best_contact); // * mPos); @@ -459,7 +468,6 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap } Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - CollisionObject3DSW *obj = PhysicsServer3DSW::singleton->area_owner.getornull(p_object); if (!obj) { obj = PhysicsServer3DSW::singleton->body_owner.getornull(p_object); @@ -474,9 +482,9 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob bool shapes_found = false; for (int i = 0; i < obj->get_shape_count(); i++) { - - if (obj->is_shape_set_as_disabled(i)) + if (obj->is_shape_set_as_disabled(i)) { continue; + } Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i); Shape3DSW *shape = obj->get_shape(i); @@ -500,33 +508,30 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob } PhysicsDirectSpaceState3DSW::PhysicsDirectSpaceState3DSW() { - space = nullptr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////// int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { - int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); for (int i = 0; i < amount; i++) { - bool keep = true; - if (intersection_query_results[i] == p_body) + if (intersection_query_results[i] == p_body) { keep = false; - else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_AREA) + } else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_AREA) { keep = false; - else if ((static_cast<Body3DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) + } else if ((static_cast<Body3DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) { keep = false; - else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) + } else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) { keep = false; - else if (static_cast<Body3DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) + } else if (static_cast<Body3DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) { keep = false; + } if (!keep) { - if (i < amount - 1) { SWAP(intersection_query_results[i], intersection_query_results[amount - 1]); SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]); @@ -541,15 +546,14 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) { } int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::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)) + if (p_body->is_shape_set_as_disabled(i)) { continue; + } if (!shapes_found) { body_aabb = p_body->get_shape_aabb(i); @@ -587,7 +591,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra CollisionSolver3DSW::CallbackResult cbkres = PhysicsServer3DSW::_shape_col_cbk; do { - Vector3 recover_motion; bool collided = false; @@ -595,18 +598,19 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra int amount = _cull_aabb_for_body(p_body, body_aabb); for (int j = 0; j < p_body->get_shape_count(); j++) { - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Shape3DSW *body_shape = p_body->get_shape(j); - if (body_shape->get_type() != PhysicsServer3D::SHAPE_RAY) + if (body_shape->get_type() != PhysicsServer3D::SHAPE_RAY) { continue; + } Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -649,7 +653,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra 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(); @@ -696,7 +699,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra } bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) { - //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -712,9 +714,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons bool shapes_found = false; for (int i = 0; i < p_body->get_shape_count(); i++) { - - if (p_body->is_shape_set_as_disabled(i)) + if (p_body->is_shape_set_as_disabled(i)) { continue; + } if (!shapes_found) { body_aabb = p_body->get_shape_aabb(i); @@ -747,7 +749,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons Vector3 sr[max_results * 2]; do { - PhysicsServer3DSW::CollCbkData cbk; cbk.max = max_results; cbk.amount = 0; @@ -761,8 +762,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons int amount = _cull_aabb_for_body(p_body, body_aabb); for (int j = 0; j < p_body->get_shape_count(); j++) { - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); Shape3DSW *body_shape = p_body->get_shape(j); @@ -771,7 +773,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -788,7 +789,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons Vector3 recover_motion; for (int i = 0; i < cbk.amount; i++) { - Vector3 a = sr[i * 2 + 0]; Vector3 b = sr[i * 2 + 1]; recover_motion += (b - a) * 0.4; @@ -821,9 +821,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons int amount = _cull_aabb_for_body(p_body, motion_aabb); for (int j = 0; j < p_body->get_shape_count(); j++) { - - if (p_body->is_shape_set_as_disabled(j)) + if (p_body->is_shape_set_as_disabled(j)) { continue; + } Transform body_shape_xform = body_transform * p_body->get_shape_transform(j); Shape3DSW *body_shape = p_body->get_shape(j); @@ -843,7 +843,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons real_t best_unsafe = 1; for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; @@ -881,10 +880,8 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons bool collided = !CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep); if (collided) { - hi = ofs; } else { - point_A = lA; point_B = lB; low = ofs; @@ -898,7 +895,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } if (stuck) { - safe = 0; unsafe = 0; best_shape = j; //sadly it's the best @@ -908,7 +904,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons continue; } if (best_safe < safe) { - safe = best_safe; unsafe = best_unsafe; best_shape = j; @@ -921,14 +916,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons //not collided collided = false; if (r_result) { - r_result->motion = p_motion; r_result->remainder = Vector3(); r_result->motion += (body_transform.get_origin() - p_from.get_origin()); } } else { - //it collided, let's get the rest info in unsafe advance Transform ugt = body_transform; ugt.origin += p_motion * unsafe; @@ -947,19 +940,18 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons int amount = _cull_aabb_for_body(p_body, body_aabb); for (int i = 0; i < amount; i++) { - const CollisionObject3DSW *col_obj = intersection_query_results[i]; int shape_idx = intersection_query_subindex_results[i]; rcd.object = col_obj; rcd.shape = shape_idx; bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin); - if (!sc) + if (!sc) { continue; + } } if (rcd.best_len != 0) { - if (r_result) { r_result->collider = rcd.best_object->get_self(); r_result->collider_id = rcd.best_object->get_instance_id(); @@ -982,7 +974,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons collided = true; } else { if (r_result) { - r_result->motion = p_motion; r_result->remainder = Vector3(); r_result->motion += (body_transform.get_origin() - p_from.get_origin()); @@ -996,11 +987,13 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons } void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_self) { + if (!A->test_collision_mask(B)) { + return nullptr; + } CollisionObject3DSW::Type type_A = A->get_type(); CollisionObject3DSW::Type type_B = B->get_type(); if (type_A > type_B) { - SWAP(A, B); SWAP(p_subindex_A, p_subindex_B); SWAP(type_A, type_B); @@ -1011,21 +1004,17 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll self->collision_pairs++; if (type_A == CollisionObject3DSW::TYPE_AREA) { - Area3DSW *area = static_cast<Area3DSW *>(A); if (type_B == CollisionObject3DSW::TYPE_AREA) { - Area3DSW *area_b = static_cast<Area3DSW *>(B); Area2Pair3DSW *area2_pair = memnew(Area2Pair3DSW(area_b, p_subindex_B, area, p_subindex_A)); return area2_pair; } else { - Body3DSW *body = static_cast<Body3DSW *>(B); AreaPair3DSW *area_pair = memnew(AreaPair3DSW(body, p_subindex_B, area, p_subindex_A)); return area_pair; } } else { - BodyPair3DSW *b = memnew(BodyPair3DSW((Body3DSW *)A, p_subindex_A, (Body3DSW *)B, p_subindex_B)); return b; } @@ -1034,6 +1023,9 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll } void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_self) { + if (!p_data) { + return; + } Space3DSW *self = (Space3DSW *)p_self; self->collision_pairs--; @@ -1042,94 +1034,79 @@ void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, Col } const SelfList<Body3DSW>::List &Space3DSW::get_active_body_list() const { - return active_list; } -void Space3DSW::body_add_to_active_list(SelfList<Body3DSW> *p_body) { +void Space3DSW::body_add_to_active_list(SelfList<Body3DSW> *p_body) { active_list.add(p_body); } -void Space3DSW::body_remove_from_active_list(SelfList<Body3DSW> *p_body) { +void Space3DSW::body_remove_from_active_list(SelfList<Body3DSW> *p_body) { active_list.remove(p_body); } void Space3DSW::body_add_to_inertia_update_list(SelfList<Body3DSW> *p_body) { - inertia_update_list.add(p_body); } void Space3DSW::body_remove_from_inertia_update_list(SelfList<Body3DSW> *p_body) { - inertia_update_list.remove(p_body); } BroadPhase3DSW *Space3DSW::get_broadphase() { - return broadphase; } void Space3DSW::add_object(CollisionObject3DSW *p_object) { - ERR_FAIL_COND(objects.has(p_object)); objects.insert(p_object); } void Space3DSW::remove_object(CollisionObject3DSW *p_object) { - ERR_FAIL_COND(!objects.has(p_object)); objects.erase(p_object); } const Set<CollisionObject3DSW *> &Space3DSW::get_objects() const { - return objects; } void Space3DSW::body_add_to_state_query_list(SelfList<Body3DSW> *p_body) { - state_query_list.add(p_body); } -void Space3DSW::body_remove_from_state_query_list(SelfList<Body3DSW> *p_body) { +void Space3DSW::body_remove_from_state_query_list(SelfList<Body3DSW> *p_body) { state_query_list.remove(p_body); } void Space3DSW::area_add_to_monitor_query_list(SelfList<Area3DSW> *p_area) { - monitor_query_list.add(p_area); } -void Space3DSW::area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area) { +void Space3DSW::area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area) { monitor_query_list.remove(p_area); } void Space3DSW::area_add_to_moved_list(SelfList<Area3DSW> *p_area) { - area_moved_list.add(p_area); } void Space3DSW::area_remove_from_moved_list(SelfList<Area3DSW> *p_area) { - area_moved_list.remove(p_area); } const SelfList<Area3DSW>::List &Space3DSW::get_moved_area_list() const { - return area_moved_list; } void Space3DSW::call_queries() { - while (state_query_list.first()) { - Body3DSW *b = state_query_list.first()->self(); state_query_list.remove(state_query_list.first()); b->call_queries(); } while (monitor_query_list.first()) { - Area3DSW *a = monitor_query_list.first()->self(); monitor_query_list.remove(monitor_query_list.first()); a->call_queries(); @@ -1137,7 +1114,6 @@ void Space3DSW::call_queries() { } void Space3DSW::setup() { - contact_debug_count = 0; while (inertia_update_list.first()) { inertia_update_list.first()->self()->update_inertias(); @@ -1146,65 +1122,82 @@ void Space3DSW::setup() { } void Space3DSW::update() { - broadphase->update(); } void Space3DSW::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) { - switch (p_param) { - - case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break; - case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break; - case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break; - case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break; - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break; - case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break; - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio = p_value; break; - case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break; - case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: test_motion_min_contact_depth = p_value; break; + case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: + contact_recycle_radius = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: + contact_max_separation = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: + contact_max_allowed_penetration = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: + body_linear_velocity_sleep_threshold = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: + body_angular_velocity_sleep_threshold = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: + body_time_to_sleep = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: + body_angular_velocity_damp_ratio = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: + constraint_bias = p_value; + break; + case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: + test_motion_min_contact_depth = p_value; + break; } } real_t Space3DSW::get_param(PhysicsServer3D::SpaceParameter p_param) const { - switch (p_param) { - - case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius; - case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation; - case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration; - case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold; - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold; - case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep; - case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio; - case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias; - case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: return test_motion_min_contact_depth; + case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: + return contact_recycle_radius; + case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: + return contact_max_separation; + case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: + return contact_max_allowed_penetration; + case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: + return body_linear_velocity_sleep_threshold; + case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: + return body_angular_velocity_sleep_threshold; + case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: + return body_time_to_sleep; + case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: + return body_angular_velocity_damp_ratio; + case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: + return constraint_bias; + case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: + return test_motion_min_contact_depth; } return 0; } void Space3DSW::lock() { - locked = true; } void Space3DSW::unlock() { - locked = false; } bool Space3DSW::is_locked() const { - return locked; } PhysicsDirectSpaceState3DSW *Space3DSW::get_direct_state() { - return direct_access; } Space3DSW::Space3DSW() { - collision_pairs = 0; active_objects = 0; island_count = 0; @@ -1231,12 +1224,12 @@ Space3DSW::Space3DSW() { direct_access = memnew(PhysicsDirectSpaceState3DSW); direct_access->space = this; - for (int i = 0; i < ELAPSED_TIME_MAX; i++) + for (int i = 0; i < ELAPSED_TIME_MAX; i++) { elapsed_time[i] = 0; + } } Space3DSW::~Space3DSW() { - memdelete(broadphase); memdelete(direct_access); } diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h index 3634834952..f9198e3d40 100644 --- a/servers/physics_3d/space_3d_sw.h +++ b/servers/physics_3d/space_3d_sw.h @@ -42,7 +42,6 @@ #include "core/typedefs.h" class PhysicsDirectSpaceState3DSW : public PhysicsDirectSpaceState3D { - GDCLASS(PhysicsDirectSpaceState3DSW, PhysicsDirectSpaceState3D); public: @@ -60,7 +59,6 @@ public: }; class Space3DSW { - public: enum ElapsedTime { ELAPSED_TIME_INTEGRATE_FORCES, @@ -187,7 +185,9 @@ public: void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } _FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) { - if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact; + if (contact_debug_count < contact_debug.size()) { + contact_debug.write[contact_debug_count++] = p_contact; + } } _FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contact_debug; } _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp index 1a7d5f8cec..9a2a0073a1 100644 --- a/servers/physics_3d/step_3d_sw.cpp +++ b/servers/physics_3d/step_3d_sw.cpp @@ -34,33 +34,33 @@ #include "core/os/os.h" void Step3DSW::_populate_island(Body3DSW *p_body, Body3DSW **p_island, Constraint3DSW **p_constraint_island) { - p_body->set_island_step(_step); p_body->set_island_next(*p_island); *p_island = p_body; for (Map<Constraint3DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) { - Constraint3DSW *c = (Constraint3DSW *)E->key(); - if (c->get_island_step() == _step) + if (c->get_island_step() == _step) { continue; //already processed + } c->set_island_step(_step); c->set_island_next(*p_constraint_island); *p_constraint_island = c; for (int i = 0; i < c->get_body_count(); i++) { - if (i == E->get()) + if (i == E->get()) { continue; + } Body3DSW *b = c->get_body_ptr()[i]; - if (b->get_island_step() == _step || b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) + if (b->get_island_step() == _step || b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) { continue; //no go + } _populate_island(c->get_body_ptr()[i], p_island, p_constraint_island); } } } void Step3DSW::_setup_island(Constraint3DSW *p_island, real_t p_delta) { - Constraint3DSW *ci = p_island; while (ci) { ci->setup(p_delta); @@ -70,13 +70,10 @@ void Step3DSW::_setup_island(Constraint3DSW *p_island, real_t p_delta) { } void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t p_delta) { - int at_priority = 1; while (p_island) { - for (int i = 0; i < p_iterations; i++) { - Constraint3DSW *ci = p_island; while (ci) { ci->solve(p_delta); @@ -97,7 +94,6 @@ void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t p_island = ci->get_island_next(); } } else { - prev = ci; } @@ -108,19 +104,18 @@ void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t } void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) { - bool can_sleep = true; Body3DSW *b = p_island; while (b) { - if (b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) { b = b->get_island_next(); continue; //ignore for static } - if (!b->sleep_test(p_delta)) + if (!b->sleep_test(p_delta)) { can_sleep = false; + } b = b->get_island_next(); } @@ -129,7 +124,6 @@ void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) { b = p_island; while (b) { - if (b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) { b = b->get_island_next(); continue; //ignore for static @@ -137,15 +131,15 @@ void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) { bool active = b->is_active(); - if (active == can_sleep) + if (active == can_sleep) { b->set_active(!can_sleep); + } b = b->get_island_next(); } } void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { - p_space->lock(); // can't access space during this p_space->setup(); //update inertias, etc @@ -161,7 +155,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { const SelfList<Body3DSW> *b = body_list->first(); while (b) { - b->self()->integrate_forces(p_delta); b = b->next(); active_count++; @@ -187,7 +180,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { Body3DSW *body = b->self(); if (body->get_island_step() != _step) { - Body3DSW *island = nullptr; Constraint3DSW *constraint_island = nullptr; _populate_island(body, &island, &constraint_island); @@ -210,10 +202,10 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { while (aml.first()) { for (const Set<Constraint3DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - Constraint3DSW *c = E->get(); - if (c->get_island_step() == _step) + if (c->get_island_step() == _step) { continue; + } c->set_island_step(_step); c->set_island_next(nullptr); c->set_island_list_next(constraint_island_list); @@ -233,7 +225,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { { Constraint3DSW *ci = constraint_island_list; while (ci) { - _setup_island(ci, p_delta); ci = ci->get_island_list_next(); } @@ -276,7 +267,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { { Body3DSW *bi = island_list; while (bi) { - _check_suspend(bi, p_delta); bi = bi->get_island_list_next(); } @@ -294,6 +284,5 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) { } Step3DSW::Step3DSW() { - _step = 1; } diff --git a/servers/physics_3d/step_3d_sw.h b/servers/physics_3d/step_3d_sw.h index c735688a9e..9dbb61308f 100644 --- a/servers/physics_3d/step_3d_sw.h +++ b/servers/physics_3d/step_3d_sw.h @@ -34,7 +34,6 @@ #include "space_3d_sw.h" class Step3DSW { - uint64_t _step; void _populate_island(Body3DSW *p_body, Body3DSW **p_island, Constraint3DSW **p_constraint_island); diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 48c51b5350..080b8c61ad 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -37,7 +37,6 @@ PhysicsServer2D *PhysicsServer2D::singleton = nullptr; void PhysicsDirectBodyState2D::integrate_forces() { - real_t step = get_step(); Vector2 lv = get_linear_velocity(); lv += get_total_gravity() * step; @@ -46,15 +45,17 @@ void PhysicsDirectBodyState2D::integrate_forces() { float damp = 1.0 - step * get_total_linear_damp(); - if (damp < 0) // reached zero in the given time + if (damp < 0) { // reached zero in the given time damp = 0; + } lv *= damp; damp = 1.0 - step * get_total_angular_damp(); - if (damp < 0) // reached zero in the given time + if (damp < 0) { // reached zero in the given time damp = 0; + } av *= damp; @@ -63,19 +64,16 @@ void PhysicsDirectBodyState2D::integrate_forces() { } Object *PhysicsDirectBodyState2D::get_contact_collider_object(int p_contact_idx) const { - ObjectID objid = get_contact_collider_id(p_contact_idx); Object *obj = ObjectDB::get_instance(objid); return obj; } PhysicsServer2D *PhysicsServer2D::get_singleton() { - return singleton; } void PhysicsDirectBodyState2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_total_gravity"), &PhysicsDirectBodyState2D::get_total_gravity); ClassDB::bind_method(D_METHOD("get_total_linear_damp"), &PhysicsDirectBodyState2D::get_total_linear_damp); ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState2D::get_total_angular_damp); @@ -135,66 +133,58 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {} /////////////////////////////////////////////////////// void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape) { - ERR_FAIL_COND(p_shape.is_null()); shape = p_shape->get_rid(); } void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) { - shape = p_shape; } RID PhysicsShapeQueryParameters2D::get_shape_rid() const { - return shape; } void PhysicsShapeQueryParameters2D::set_transform(const Transform2D &p_transform) { - transform = p_transform; } -Transform2D PhysicsShapeQueryParameters2D::get_transform() const { +Transform2D PhysicsShapeQueryParameters2D::get_transform() const { return transform; } void PhysicsShapeQueryParameters2D::set_motion(const Vector2 &p_motion) { - motion = p_motion; } -Vector2 PhysicsShapeQueryParameters2D::get_motion() const { +Vector2 PhysicsShapeQueryParameters2D::get_motion() const { return motion; } void PhysicsShapeQueryParameters2D::set_margin(float p_margin) { - margin = p_margin; } -float PhysicsShapeQueryParameters2D::get_margin() const { +float PhysicsShapeQueryParameters2D::get_margin() const { return margin; } void PhysicsShapeQueryParameters2D::set_collision_mask(int p_collision_mask) { - collision_mask = p_collision_mask; } -int PhysicsShapeQueryParameters2D::get_collision_mask() const { +int PhysicsShapeQueryParameters2D::get_collision_mask() const { return collision_mask; } void PhysicsShapeQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) { - exclude.clear(); - for (int i = 0; i < p_exclude.size(); i++) + for (int i = 0; i < p_exclude.size(); i++) { exclude.insert(p_exclude[i]); + } } Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const { - Vector<RID> ret; ret.resize(exclude.size()); int idx = 0; @@ -221,7 +211,6 @@ bool PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled() const { } void PhysicsShapeQueryParameters2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid); @@ -259,7 +248,6 @@ void PhysicsShapeQueryParameters2D::_bind_methods() { } PhysicsShapeQueryParameters2D::PhysicsShapeQueryParameters2D() { - margin = 0; collision_mask = 0x7FFFFFFF; collide_with_bodies = true; @@ -267,16 +255,17 @@ PhysicsShapeQueryParameters2D::PhysicsShapeQueryParameters2D() { } Dictionary PhysicsDirectSpaceState2D::_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++) + 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, p_collide_with_bodies, p_collide_with_areas); - if (!res) + if (!res) { return Dictionary(); + } Dictionary d; d["position"] = inters.position; @@ -291,7 +280,6 @@ Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Vector2 &p_from, cons } Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) { - ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); Vector<ShapeResult> sr; @@ -300,7 +288,6 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar Array ret; ret.resize(rc); for (int i = 0; i < rc; i++) { - Dictionary d; d["rid"] = sr[i].rid; d["collider_id"] = sr[i].collider_id; @@ -314,13 +301,13 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar } Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); - if (!res) + if (!res) { return Array(); + } Array ret; ret.resize(2); ret[0] = closest_safe; @@ -329,27 +316,28 @@ Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParamet } Array PhysicsDirectSpaceState2D::_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++) + for (int i = 0; i < p_exclude.size(); i++) { exclude.insert(p_exclude[i]); + } Vector<ShapeResult> ret; ret.resize(p_max_results); int rc; - if (p_filter_by_canvas) + 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 + } 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) + if (rc == 0) { return Array(); + } Array r; r.resize(rc); for (int i = 0; i < rc; i++) { - Dictionary d; d["rid"] = ret[i].rid; d["collider_id"] = ret[i].collider_id; @@ -362,41 +350,41 @@ Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, i } Array PhysicsDirectSpaceState2D::_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 PhysicsDirectSpaceState2D::_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 PhysicsDirectSpaceState2D::_collide_shape(const Ref<PhysicsShapeQueryParameters2D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); - if (!res) + if (!res) { return Array(); + } Array r; r.resize(rc * 2); - for (int i = 0; i < rc * 2; i++) + for (int i = 0; i < rc * 2; i++) { r[i] = ret[i]; + } return r; } -Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) { +Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQueryParameters2D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Dictionary r; - if (!res) + if (!res) { return r; + } r["point"] = sri.point; r["normal"] = sri.normal; @@ -413,7 +401,6 @@ PhysicsDirectSpaceState2D::PhysicsDirectSpaceState2D() { } void PhysicsDirectSpaceState2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_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"), &PhysicsDirectSpaceState2D::_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"), &PhysicsDirectSpaceState2D::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); @@ -424,23 +411,22 @@ void PhysicsDirectSpaceState2D::_bind_methods() { } int PhysicsShapeQueryResult2D::get_result_count() const { - return result.size(); } -RID PhysicsShapeQueryResult2D::get_result_rid(int p_idx) const { +RID PhysicsShapeQueryResult2D::get_result_rid(int p_idx) const { return result[p_idx].rid; } -ObjectID PhysicsShapeQueryResult2D::get_result_object_id(int p_idx) const { +ObjectID PhysicsShapeQueryResult2D::get_result_object_id(int p_idx) const { return result[p_idx].collider_id; } -Object *PhysicsShapeQueryResult2D::get_result_object(int p_idx) const { +Object *PhysicsShapeQueryResult2D::get_result_object(int p_idx) const { return result[p_idx].collider; } -int PhysicsShapeQueryResult2D::get_result_object_shape(int p_idx) const { +int PhysicsShapeQueryResult2D::get_result_object_shape(int p_idx) const { return result[p_idx].shape; } @@ -448,7 +434,6 @@ PhysicsShapeQueryResult2D::PhysicsShapeQueryResult2D() { } void PhysicsShapeQueryResult2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult2D::get_result_count); ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult2D::get_result_rid); ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult2D::get_result_object_id); @@ -459,32 +444,30 @@ void PhysicsShapeQueryResult2D::_bind_methods() { /////////////////////////////// Vector2 PhysicsTestMotionResult2D::get_motion() const { - return result.motion; } -Vector2 PhysicsTestMotionResult2D::get_motion_remainder() const { +Vector2 PhysicsTestMotionResult2D::get_motion_remainder() const { return result.remainder; } Vector2 PhysicsTestMotionResult2D::get_collision_point() const { - return result.collision_point; } -Vector2 PhysicsTestMotionResult2D::get_collision_normal() const { +Vector2 PhysicsTestMotionResult2D::get_collision_normal() const { return result.collision_normal; } -Vector2 PhysicsTestMotionResult2D::get_collider_velocity() const { +Vector2 PhysicsTestMotionResult2D::get_collider_velocity() const { return result.collider_velocity; } -ObjectID PhysicsTestMotionResult2D::get_collider_id() const { +ObjectID PhysicsTestMotionResult2D::get_collider_id() const { return result.collider_id; } -RID PhysicsTestMotionResult2D::get_collider_rid() const { +RID PhysicsTestMotionResult2D::get_collider_rid() const { return result.collider; } @@ -493,12 +476,10 @@ Object *PhysicsTestMotionResult2D::get_collider() const { } int PhysicsTestMotionResult2D::get_collider_shape() const { - return result.collider_shape; } void PhysicsTestMotionResult2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionResult2D::get_motion); ClassDB::bind_method(D_METHOD("get_motion_remainder"), &PhysicsTestMotionResult2D::get_motion_remainder); ClassDB::bind_method(D_METHOD("get_collision_point"), &PhysicsTestMotionResult2D::get_collision_point); @@ -521,7 +502,6 @@ void PhysicsTestMotionResult2D::_bind_methods() { } PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() { - colliding = false; result.collider_shape = 0; @@ -530,15 +510,14 @@ PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() { /////////////////////////////////////// bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) { - MotionResult *r = nullptr; - if (p_result.is_valid()) + if (p_result.is_valid()) { r = p_result->get_result_ptr(); + } return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r); } void PhysicsServer2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("line_shape_create"), &PhysicsServer2D::line_shape_create); ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer2D::ray_shape_create); ClassDB::bind_method(D_METHOD("segment_shape_create"), &PhysicsServer2D::segment_shape_create); @@ -675,8 +654,8 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("groove_joint_create", "groove1_a", "groove2_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::groove_joint_create, DEFVAL(RID()), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("damped_spring_joint_create", "anchor_a", "anchor_b", "body_a", "body_b"), &PhysicsServer2D::damped_spring_joint_create, DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("damped_string_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::damped_string_joint_set_param); - ClassDB::bind_method(D_METHOD("damped_string_joint_get_param", "joint", "param"), &PhysicsServer2D::damped_string_joint_get_param); + ClassDB::bind_method(D_METHOD("damped_spring_joint_set_param", "joint", "param", "value"), &PhysicsServer2D::damped_spring_joint_set_param); + ClassDB::bind_method(D_METHOD("damped_spring_joint_get_param", "joint", "param"), &PhysicsServer2D::damped_spring_joint_get_param); ClassDB::bind_method(D_METHOD("joint_get_type", "joint"), &PhysicsServer2D::joint_get_type); @@ -748,9 +727,9 @@ void PhysicsServer2D::_bind_methods() { BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_BIAS); BIND_ENUM_CONSTANT(JOINT_PARAM_MAX_FORCE); - BIND_ENUM_CONSTANT(DAMPED_STRING_REST_LENGTH); - BIND_ENUM_CONSTANT(DAMPED_STRING_STIFFNESS); - BIND_ENUM_CONSTANT(DAMPED_STRING_DAMPING); + BIND_ENUM_CONSTANT(DAMPED_SPRING_REST_LENGTH); + BIND_ENUM_CONSTANT(DAMPED_SPRING_STIFFNESS); + BIND_ENUM_CONSTANT(DAMPED_SPRING_DAMPING); BIND_ENUM_CONSTANT(CCD_MODE_DISABLED); BIND_ENUM_CONSTANT(CCD_MODE_CAST_RAY); @@ -765,12 +744,10 @@ void PhysicsServer2D::_bind_methods() { } PhysicsServer2D::PhysicsServer2D() { - singleton = this; } PhysicsServer2D::~PhysicsServer2D() { - singleton = nullptr; } @@ -780,7 +757,6 @@ int PhysicsServer2DManager::default_server_priority = -1; const String PhysicsServer2DManager::setting_property_name("physics/2d/physics_engine"); void PhysicsServer2DManager::on_servers_changed() { - String physics_servers("DEFAULT"); for (int i = get_servers_count() - 1; 0 <= i; --i) { physics_servers += "," + get_server_name(i); @@ -789,7 +765,6 @@ void PhysicsServer2DManager::on_servers_changed() { } void PhysicsServer2DManager::register_server(const String &p_name, CreatePhysicsServer2DCallback p_creat_callback) { - ERR_FAIL_COND(!p_creat_callback); ERR_FAIL_COND(find_server_id(p_name) != -1); physics_2d_servers.push_back(ClassInfo(p_name, p_creat_callback)); @@ -797,7 +772,6 @@ void PhysicsServer2DManager::register_server(const String &p_name, CreatePhysics } void PhysicsServer2DManager::set_default_server(const String &p_name, int p_priority) { - const int id = find_server_id(p_name); ERR_FAIL_COND(id == -1); // Not found if (default_server_priority < p_priority) { @@ -807,7 +781,6 @@ void PhysicsServer2DManager::set_default_server(const String &p_name, int p_prio } int PhysicsServer2DManager::find_server_id(const String &p_name) { - for (int i = physics_2d_servers.size() - 1; 0 <= i; --i) { if (p_name == physics_2d_servers[i].name) { return i; diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 8c833b390f..549a78aa1f 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -38,7 +38,6 @@ class PhysicsDirectSpaceState2D; class PhysicsDirectBodyState2D : public Object { - GDCLASS(PhysicsDirectBodyState2D, Object); protected: @@ -97,7 +96,6 @@ class PhysicsShapeQueryResult2D; //used for script class PhysicsShapeQueryParameters2D : public Reference { - GDCLASS(PhysicsShapeQueryParameters2D, Reference); friend class PhysicsDirectSpaceState2D; RID shape; @@ -143,7 +141,6 @@ public: }; class PhysicsDirectSpaceState2D : public Object { - GDCLASS(PhysicsDirectSpaceState2D, Object); 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); @@ -160,7 +157,6 @@ protected: public: struct RayResult { - Vector2 position; Vector2 normal; RID rid; @@ -173,7 +169,6 @@ public: 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 { - RID rid; ObjectID collider_id; Object *collider; @@ -191,7 +186,6 @@ public: 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 { - Vector2 point; Vector2 normal; RID rid; @@ -207,7 +201,6 @@ public: }; class PhysicsShapeQueryResult2D : public Reference { - GDCLASS(PhysicsShapeQueryResult2D, Reference); Vector<PhysicsDirectSpaceState2D::ShapeResult> result; @@ -230,7 +223,6 @@ public: class PhysicsTestMotionResult2D; class PhysicsServer2D : public Object { - GDCLASS(PhysicsServer2D, Object); static PhysicsServer2D *singleton; @@ -493,7 +485,6 @@ public: virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) = 0; struct MotionResult { - Vector2 motion; Vector2 remainder; @@ -516,7 +507,6 @@ public: virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { - float collision_depth; Vector2 collision_point; Vector2 collision_normal; @@ -562,13 +552,13 @@ public: virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) = 0; virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0; - enum DampedStringParam { - DAMPED_STRING_REST_LENGTH, - DAMPED_STRING_STIFFNESS, - DAMPED_STRING_DAMPING + enum DampedSpringParam { + DAMPED_SPRING_REST_LENGTH, + DAMPED_SPRING_STIFFNESS, + DAMPED_SPRING_DAMPING }; - virtual void damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) = 0; - virtual real_t damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const = 0; + virtual void damped_spring_joint_set_param(RID p_joint, DampedSpringParam p_param, real_t p_value) = 0; + virtual real_t damped_spring_joint_get_param(RID p_joint, DampedSpringParam p_param) const = 0; virtual JointType joint_get_type(RID p_joint) const = 0; @@ -607,7 +597,6 @@ public: }; class PhysicsTestMotionResult2D : public Reference { - GDCLASS(PhysicsTestMotionResult2D, Reference); PhysicsServer2D::MotionResult result; @@ -640,11 +629,9 @@ typedef PhysicsServer2D *(*CreatePhysicsServer2DCallback)(); class PhysicsServer2DManager { struct ClassInfo { String name; - CreatePhysicsServer2DCallback create_callback; + CreatePhysicsServer2DCallback create_callback = nullptr; - ClassInfo() : - name(""), - create_callback(nullptr) {} + ClassInfo() {} ClassInfo(String p_name, CreatePhysicsServer2DCallback p_create_callback) : name(p_name), @@ -691,7 +678,7 @@ VARIANT_ENUM_CAST(PhysicsServer2D::BodyState); VARIANT_ENUM_CAST(PhysicsServer2D::CCDMode); VARIANT_ENUM_CAST(PhysicsServer2D::JointParam); VARIANT_ENUM_CAST(PhysicsServer2D::JointType); -VARIANT_ENUM_CAST(PhysicsServer2D::DampedStringParam); +VARIANT_ENUM_CAST(PhysicsServer2D::DampedSpringParam); //VARIANT_ENUM_CAST( PhysicsServer2D::ObjectType ); VARIANT_ENUM_CAST(PhysicsServer2D::AreaBodyStatus); VARIANT_ENUM_CAST(PhysicsServer2D::ProcessInfo); diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index a5a02fd1bd..2dd8ea3edb 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -37,7 +37,6 @@ PhysicsServer3D *PhysicsServer3D::singleton = nullptr; void PhysicsDirectBodyState3D::integrate_forces() { - real_t step = get_step(); Vector3 lv = get_linear_velocity(); lv += get_total_gravity() * step; @@ -46,13 +45,15 @@ void PhysicsDirectBodyState3D::integrate_forces() { float linear_damp = 1.0 - step * get_total_linear_damp(); - if (linear_damp < 0) // reached zero in the given time + if (linear_damp < 0) { // reached zero in the given time linear_damp = 0; + } float angular_damp = 1.0 - step * get_total_angular_damp(); - if (angular_damp < 0) // reached zero in the given time + if (angular_damp < 0) { // reached zero in the given time angular_damp = 0; + } lv *= linear_damp; av *= angular_damp; @@ -62,19 +63,16 @@ void PhysicsDirectBodyState3D::integrate_forces() { } Object *PhysicsDirectBodyState3D::get_contact_collider_object(int p_contact_idx) const { - ObjectID objid = get_contact_collider_id(p_contact_idx); Object *obj = ObjectDB::get_instance(objid); return obj; } PhysicsServer3D *PhysicsServer3D::get_singleton() { - return singleton; } void PhysicsDirectBodyState3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_total_gravity"), &PhysicsDirectBodyState3D::get_total_gravity); ClassDB::bind_method(D_METHOD("get_total_linear_damp"), &PhysicsDirectBodyState3D::get_total_linear_damp); ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState3D::get_total_angular_damp); @@ -139,58 +137,50 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {} /////////////////////////////////////////////////////// void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape) { - ERR_FAIL_COND(p_shape.is_null()); shape = p_shape->get_rid(); } void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) { - shape = p_shape; } RID PhysicsShapeQueryParameters3D::get_shape_rid() const { - return shape; } void PhysicsShapeQueryParameters3D::set_transform(const Transform &p_transform) { - transform = p_transform; } -Transform PhysicsShapeQueryParameters3D::get_transform() const { +Transform PhysicsShapeQueryParameters3D::get_transform() const { return transform; } void PhysicsShapeQueryParameters3D::set_margin(float p_margin) { - margin = p_margin; } float PhysicsShapeQueryParameters3D::get_margin() const { - return margin; } void PhysicsShapeQueryParameters3D::set_collision_mask(int p_collision_mask) { - collision_mask = p_collision_mask; } -int PhysicsShapeQueryParameters3D::get_collision_mask() const { +int PhysicsShapeQueryParameters3D::get_collision_mask() const { return collision_mask; } void PhysicsShapeQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) { - exclude.clear(); - for (int i = 0; i < p_exclude.size(); i++) + for (int i = 0; i < p_exclude.size(); i++) { exclude.insert(p_exclude[i]); + } } Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const { - Vector<RID> ret; ret.resize(exclude.size()); int idx = 0; @@ -217,7 +207,6 @@ bool PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled() const { } void PhysicsShapeQueryParameters3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape); ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid); ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid); @@ -251,7 +240,6 @@ void PhysicsShapeQueryParameters3D::_bind_methods() { } PhysicsShapeQueryParameters3D::PhysicsShapeQueryParameters3D() { - margin = 0; collision_mask = 0x7FFFFFFF; collide_with_bodies = true; @@ -261,16 +249,17 @@ PhysicsShapeQueryParameters3D::PhysicsShapeQueryParameters3D() { ///////////////////////////////////// Dictionary PhysicsDirectSpaceState3D::_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++) + 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, p_collide_with_bodies, p_collide_with_areas); - if (!res) + if (!res) { return Dictionary(); + } Dictionary d; d["position"] = inters.position; @@ -284,7 +273,6 @@ Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Vector3 &p_from, cons } Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) { - ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array()); Vector<ShapeResult> sr; @@ -293,7 +281,6 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar Array ret; ret.resize(rc); for (int i = 0; i < rc; i++) { - Dictionary d; d["rid"] = sr[i].rid; d["collider_id"] = sr[i].collider_id; @@ -306,45 +293,48 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar } Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); - if (!res) + if (!res) { return Array(); + } Array ret; ret.resize(2); ret[0] = closest_safe; ret[1] = closest_unsafe; return ret; } -Array PhysicsDirectSpaceState3D::_collide_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) { +Array PhysicsDirectSpaceState3D::_collide_shape(const Ref<PhysicsShapeQueryParameters3D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); - if (!res) + if (!res) { return Array(); + } Array r; r.resize(rc * 2); - for (int i = 0; i < rc * 2; i++) + for (int i = 0; i < rc * 2; i++) { r[i] = ret[i]; + } return r; } -Dictionary PhysicsDirectSpaceState3D::_get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query) { +Dictionary PhysicsDirectSpaceState3D::_get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &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, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas); Dictionary r; - if (!res) + if (!res) { return r; + } r["point"] = sri.point; r["normal"] = sri.normal; @@ -360,7 +350,6 @@ PhysicsDirectSpaceState3D::PhysicsDirectSpaceState3D() { } void PhysicsDirectSpaceState3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState3D::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState3D::_intersect_shape, DEFVAL(32)); ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion"), &PhysicsDirectSpaceState3D::_cast_motion); @@ -369,23 +358,22 @@ void PhysicsDirectSpaceState3D::_bind_methods() { } int PhysicsShapeQueryResult3D::get_result_count() const { - return result.size(); } -RID PhysicsShapeQueryResult3D::get_result_rid(int p_idx) const { +RID PhysicsShapeQueryResult3D::get_result_rid(int p_idx) const { return result[p_idx].rid; } -ObjectID PhysicsShapeQueryResult3D::get_result_object_id(int p_idx) const { +ObjectID PhysicsShapeQueryResult3D::get_result_object_id(int p_idx) const { return result[p_idx].collider_id; } -Object *PhysicsShapeQueryResult3D::get_result_object(int p_idx) const { +Object *PhysicsShapeQueryResult3D::get_result_object(int p_idx) const { return result[p_idx].collider; } -int PhysicsShapeQueryResult3D::get_result_object_shape(int p_idx) const { +int PhysicsShapeQueryResult3D::get_result_object_shape(int p_idx) const { return result[p_idx].shape; } @@ -393,7 +381,6 @@ PhysicsShapeQueryResult3D::PhysicsShapeQueryResult3D() { } void PhysicsShapeQueryResult3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult3D::get_result_count); ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult3D::get_result_rid); ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult3D::get_result_object_id); @@ -404,7 +391,6 @@ void PhysicsShapeQueryResult3D::_bind_methods() { /////////////////////////////////////// void PhysicsServer3D::_bind_methods() { - #ifndef _3D_DISABLED ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer3D::shape_create); @@ -724,13 +710,11 @@ void PhysicsServer3D::_bind_methods() { } PhysicsServer3D::PhysicsServer3D() { - ERR_FAIL_COND(singleton != nullptr); singleton = this; } PhysicsServer3D::~PhysicsServer3D() { - singleton = nullptr; } @@ -740,7 +724,6 @@ int PhysicsServer3DManager::default_server_priority = -1; const String PhysicsServer3DManager::setting_property_name("physics/3d/physics_engine"); void PhysicsServer3DManager::on_servers_changed() { - String physics_servers2("DEFAULT"); for (int i = get_servers_count() - 1; 0 <= i; --i) { physics_servers2 += "," + get_server_name(i); @@ -749,7 +732,6 @@ void PhysicsServer3DManager::on_servers_changed() { } void PhysicsServer3DManager::register_server(const String &p_name, CreatePhysicsServer3DCallback p_creat_callback) { - ERR_FAIL_COND(!p_creat_callback); ERR_FAIL_COND(find_server_id(p_name) != -1); physics_servers.push_back(ClassInfo(p_name, p_creat_callback)); @@ -757,7 +739,6 @@ void PhysicsServer3DManager::register_server(const String &p_name, CreatePhysics } void PhysicsServer3DManager::set_default_server(const String &p_name, int p_priority) { - const int id = find_server_id(p_name); ERR_FAIL_COND(id == -1); // Not found if (default_server_priority < p_priority) { @@ -767,7 +748,6 @@ void PhysicsServer3DManager::set_default_server(const String &p_name, int p_prio } int PhysicsServer3DManager::find_server_id(const String &p_name) { - for (int i = physics_servers.size() - 1; 0 <= i; --i) { if (p_name == physics_servers[i].name) { return i; diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 8ea8b22455..2465b40d3e 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -37,7 +37,6 @@ class PhysicsDirectSpaceState3D; class PhysicsDirectBodyState3D : public Object { - GDCLASS(PhysicsDirectBodyState3D, Object); protected: @@ -98,7 +97,6 @@ public: class PhysicsShapeQueryResult3D; class PhysicsShapeQueryParameters3D : public Reference { - GDCLASS(PhysicsShapeQueryParameters3D, Reference); friend class PhysicsDirectSpaceState3D; @@ -141,7 +139,6 @@ public: }; class PhysicsDirectSpaceState3D : public Object { - GDCLASS(PhysicsDirectSpaceState3D, Object); private: @@ -156,7 +153,6 @@ protected: public: struct ShapeResult { - RID rid; ObjectID collider_id; Object *collider; @@ -166,7 +162,6 @@ public: 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 { - Vector3 position; Vector3 normal; RID rid; @@ -180,7 +175,6 @@ public: 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 { - Vector3 point; Vector3 normal; RID rid; @@ -201,7 +195,6 @@ public: }; class PhysicsShapeQueryResult3D : public Reference { - GDCLASS(PhysicsShapeQueryResult3D, Reference); Vector<PhysicsDirectSpaceState3D::ShapeResult> result; @@ -222,7 +215,6 @@ public: }; class PhysicsServer3D : public Object { - GDCLASS(PhysicsServer3D, Object); static PhysicsServer3D *singleton; @@ -481,7 +473,6 @@ public: virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0; struct MotionResult { - Vector3 motion; Vector3 remainder; @@ -503,7 +494,6 @@ public: virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0; struct SeparationResult { - float collision_depth; Vector3 collision_point; Vector3 collision_normal; @@ -781,11 +771,9 @@ typedef PhysicsServer3D *(*CreatePhysicsServer3DCallback)(); class PhysicsServer3DManager { struct ClassInfo { String name; - CreatePhysicsServer3DCallback create_callback; + CreatePhysicsServer3DCallback create_callback = nullptr; - ClassInfo() : - name(""), - create_callback(nullptr) {} + ClassInfo() {} ClassInfo(String p_name, CreatePhysicsServer3DCallback p_create_callback) : name(p_name), diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 556f9cd8e3..adca7b8055 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -62,6 +62,10 @@ #include "physics_3d/physics_server_3d_sw.h" #include "physics_server_2d.h" #include "physics_server_3d.h" +#include "rendering/rasterizer.h" +#include "rendering/rendering_device.h" +#include "rendering/rendering_device_binds.h" + #include "rendering_server.h" #include "servers/rendering/shader_types.h" #include "xr/xr_interface.h" @@ -79,7 +83,6 @@ PhysicsServer2D *_createGodotPhysics2DCallback() { } static bool has_server_feature_callback(const String &p_feature) { - if (RenderingServer::get_singleton()) { if (RenderingServer::get_singleton()->has_os_feature(p_feature)) { return true; @@ -94,24 +97,23 @@ void preregister_server_types() { } void register_server_types() { - OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback); ClassDB::register_virtual_class<DisplayServer>(); ClassDB::register_virtual_class<RenderingServer>(); ClassDB::register_class<AudioServer>(); - ClassDB::register_virtual_class<PhysicsServer3D>(); ClassDB::register_virtual_class<PhysicsServer2D>(); + ClassDB::register_virtual_class<PhysicsServer3D>(); + ClassDB::register_virtual_class<NavigationServer2D>(); + ClassDB::register_virtual_class<NavigationServer3D>(); ClassDB::register_class<XRServer>(); ClassDB::register_class<CameraServer>(); + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_virtual_class<XRInterface>(); ClassDB::register_class<XRPositionalTracker>(); - ClassDB::add_compatibility_class("ARVRServer", "XRServer"); - ClassDB::add_compatibility_class("ARVRInterface", "XRInterface"); - ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker"); - ClassDB::register_virtual_class<AudioStream>(); ClassDB::register_virtual_class<AudioStreamPlayback>(); ClassDB::register_virtual_class<AudioStreamPlaybackResampled>(); @@ -161,6 +163,22 @@ void register_server_types() { ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>(); } + ClassDB::register_virtual_class<RenderingDevice>(); + ClassDB::register_class<RDTextureFormat>(); + ClassDB::register_class<RDTextureView>(); + ClassDB::register_class<RDAttachmentFormat>(); + ClassDB::register_class<RDSamplerState>(); + ClassDB::register_class<RDVertexAttribute>(); + ClassDB::register_class<RDUniform>(); + ClassDB::register_class<RDPipelineRasterizationState>(); + ClassDB::register_class<RDPipelineMultisampleState>(); + ClassDB::register_class<RDPipelineDepthStencilState>(); + ClassDB::register_class<RDPipelineColorBlendStateAttachment>(); + ClassDB::register_class<RDPipelineColorBlendState>(); + ClassDB::register_class<RDShaderSource>(); + ClassDB::register_class<RDShaderBytecode>(); + ClassDB::register_class<RDShaderFile>(); + ClassDB::register_class<CameraFeed>(); ClassDB::register_virtual_class<PhysicsDirectBodyState2D>(); @@ -190,12 +208,11 @@ void register_server_types() { } void unregister_server_types() { - memdelete(shader_types); } void register_server_singletons() { - + Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton())); diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/rasterizer.cpp index f62e0a43a6..566a14b655 100644 --- a/servers/rendering/rasterizer.cpp +++ b/servers/rendering/rasterizer.cpp @@ -40,6 +40,7 @@ void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, b E->key()->dependency_changed(p_aabb, p_dependencies); } } + void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted) { for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) { E->key()->dependency_deleted(p_deleted); @@ -63,7 +64,6 @@ RasterizerScene::InstanceDependency::~InstanceDependency() { } Rasterizer *Rasterizer::create() { - return _create_func(); } @@ -72,6 +72,5 @@ RasterizerCanvas *RasterizerCanvas::singleton = nullptr; RasterizerStorage *RasterizerStorage::base_singleton = nullptr; RasterizerStorage::RasterizerStorage() { - base_singleton = this; } diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h index 955241e79c..026725bf01 100644 --- a/servers/rendering/rasterizer.h +++ b/servers/rendering/rasterizer.h @@ -38,7 +38,6 @@ #include "core/self_list.h" class RasterizerScene { - public: /* SHADOW ATLAS API */ @@ -57,6 +56,7 @@ public: virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; + virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; /* ENVIRONMENT API */ @@ -94,6 +94,8 @@ public: 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 Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; + virtual bool is_environment(RID p_env) const = 0; virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0; virtual int environment_get_canvas_max_layer(RID p_env) const = 0; @@ -160,9 +162,11 @@ public: SelfList<InstanceBase> dependency_item; - InstanceBase *lightmap_capture; - RID lightmap; - 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 + InstanceBase *lightmap; + Rect2 lightmap_uv_scale; + int lightmap_slice_index; + uint32_t lightmap_cull_index; + Vector<Color> lightmap_sh; //spherical harmonic AABB aabb; AABB transformed_aabb; @@ -178,8 +182,8 @@ public: bool instance_allocated_shader_parameters = false; int32_t instance_allocated_shader_parameters_offset = -1; - virtual void dependency_deleted(RID p_dependency) = 0; - virtual void dependency_changed(bool p_aabb, bool p_dependencies) = 0; + virtual void dependency_deleted(RID p_dependency) {} + virtual void dependency_changed(bool p_aabb, bool p_dependencies) {} Set<InstanceDependency *> dependencies; @@ -222,7 +226,6 @@ public: InstanceBase() : dependency_item(this) { - base_type = RS::INSTANCE_NONE; cast_shadows = RS::SHADOW_CASTING_SETTING_ON; receive_shadows = true; @@ -233,7 +236,9 @@ public: baked_light = false; dynamic_gi = false; redraw_if_visible = false; - lightmap_capture = nullptr; + lightmap_slice_index = 0; + lightmap = nullptr; + lightmap_cull_index = 0; } virtual ~InstanceBase() { @@ -268,7 +273,7 @@ public: virtual bool gi_probe_needs_update(RID p_probe) const = 0; virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0; - virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; + virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0; virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0; virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; @@ -286,6 +291,8 @@ public: virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0; virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + virtual bool free(RID p_rid) = 0; virtual void update() = 0; @@ -293,7 +300,6 @@ public: }; class RasterizerStorage { - Color default_clear_color; public: @@ -311,7 +317,7 @@ public: //these two APIs can be used together or in combination with the others. virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create() = 0; + virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0; virtual RID texture_3d_placeholder_create() = 0; virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; @@ -593,29 +599,21 @@ public: /* LIGHTMAP CAPTURE */ - struct LightmapCaptureOctree { - - enum { - CHILD_EMPTY = 0xFFFFFFFF - }; - - uint16_t light[6][3]; //anisotropic light - float alpha; - uint32_t children[8]; - }; - - virtual RID lightmap_capture_create() = 0; - virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) = 0; - virtual AABB lightmap_capture_get_bounds(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) = 0; - virtual Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) = 0; - virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) = 0; - virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const = 0; - virtual void lightmap_capture_set_energy(RID p_capture, float p_energy) = 0; - virtual float lightmap_capture_get_energy(RID p_capture) const = 0; - virtual const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const = 0; + virtual RID lightmap_create() = 0; + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0; + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0; + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0; + virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0; + virtual bool lightmap_is_interior(RID p_lightmap) const = 0; + virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0; + virtual float lightmap_get_probe_capture_update_speed() const = 0; /* PARTICLES */ @@ -721,14 +719,16 @@ public: Color get_default_clear_color() const { return default_clear_color; } -#define TIMESTAMP_BEGIN() \ - { \ - if (RSG::storage->capturing_timestamps) RSG::storage->capture_timestamps_begin(); \ +#define TIMESTAMP_BEGIN() \ + { \ + if (RSG::storage->capturing_timestamps) \ + RSG::storage->capture_timestamps_begin(); \ } -#define RENDER_TIMESTAMP(m_text) \ - { \ - if (RSG::storage->capturing_timestamps) RSG::storage->capture_timestamp(m_text); \ +#define RENDER_TIMESTAMP(m_text) \ + { \ + if (RSG::storage->capturing_timestamps) \ + RSG::storage->capture_timestamp(m_text); \ } bool capturing_timestamps = false; @@ -760,7 +760,6 @@ public: }; struct Light { - bool enabled; Color color; Transform2D xform; @@ -815,7 +814,7 @@ public: item_mask = 1; scale = 1.0; energy = 1.0; - item_shadow_mask = -1; + item_shadow_mask = 1; mode = RS::CANVAS_LIGHT_MODE_ADD; // texture_cache = nullptr; next_ptr = nullptr; @@ -839,7 +838,6 @@ public: struct Item; struct TextureBinding { - TextureBindingID binding_id; _FORCE_INLINE_ void create(RS::CanvasItemTextureFilter p_item_filter, RS::CanvasItemTextureRepeat p_item_repeat, RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { @@ -857,7 +855,9 @@ public: _FORCE_INLINE_ TextureBinding() { binding_id = 0; } _FORCE_INLINE_ ~TextureBinding() { - if (binding_id) singleton->free_texture_binding(binding_id); + if (binding_id) { + singleton->free_texture_binding(binding_id); + } } }; @@ -867,7 +867,6 @@ public: //also easier to wrap to avoid mistakes struct Polygon { - PolygonID polygon_id; Rect2 rect_cache; @@ -886,14 +885,15 @@ public: _FORCE_INLINE_ Polygon() { polygon_id = 0; } _FORCE_INLINE_ ~Polygon() { - if (polygon_id) singleton->free_polygon(polygon_id); + if (polygon_id) { + singleton->free_polygon(polygon_id); + } } }; //item struct Item { - //commands are allocated in blocks of 4k to improve performance //and cache coherence. //blocks always grow but never shrink. @@ -907,7 +907,6 @@ public: }; struct Command { - enum Type { TYPE_RECT, @@ -927,7 +926,6 @@ public: }; struct CommandRect : public Command { - Rect2 rect; Color modulate; Rect2 source; @@ -943,7 +941,6 @@ public: }; struct CommandNinePatch : public Command { - Rect2 rect; Rect2 source; float margin[4]; @@ -960,7 +957,6 @@ public: }; struct CommandPolygon : public Command { - RS::PrimitiveType primitive; Polygon polygon; Color specular_shininess; @@ -971,7 +967,6 @@ public: }; struct CommandPrimitive : public Command { - uint32_t point_count; Vector2 points[4]; Vector2 uvs[4]; @@ -984,7 +979,6 @@ public: }; struct CommandMesh : public Command { - RID mesh; Transform2D transform; Color modulate; @@ -994,7 +988,6 @@ public: }; struct CommandMultiMesh : public Command { - RID multimesh; Color specular_shininess; TextureBinding texture_binding; @@ -1002,7 +995,6 @@ public: }; struct CommandParticles : public Command { - RID particles; Color specular_shininess; TextureBinding texture_binding; @@ -1010,13 +1002,11 @@ public: }; struct CommandTransform : public Command { - Transform2D xform; CommandTransform() { type = TYPE_TRANSFORM; } }; struct CommandClipIgnore : public Command { - bool ignore; CommandClipIgnore() { type = TYPE_CLIP_IGNORE; @@ -1066,13 +1056,13 @@ public: Rect2 global_rect_cache; const Rect2 &get_rect() const { - if (custom_rect || (!rect_dirty && !update_when_visible)) + if (custom_rect || (!rect_dirty && !update_when_visible)) { return rect; + } //must update rect if (commands == nullptr) { - rect = Rect2(); rect_dirty = false; return rect; @@ -1085,29 +1075,24 @@ public: const Item::Command *c = commands; while (c) { - Rect2 r; switch (c->type) { case Item::Command::TYPE_RECT: { - const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c); r = crect->rect; } break; case Item::Command::TYPE_NINEPATCH: { - const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c); r = style->rect; } break; case Item::Command::TYPE_POLYGON: { - const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); r = polygon->polygon.rect_cache; } break; case Item::Command::TYPE_PRIMITIVE: { - const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); for (uint32_t j = 0; j < primitive->point_count; j++) { if (j == 0) { @@ -1118,7 +1103,6 @@ public: } } break; case Item::Command::TYPE_MESH: { - const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID()); @@ -1126,7 +1110,6 @@ public: } break; case Item::Command::TYPE_MULTIMESH: { - const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); @@ -1134,7 +1117,6 @@ public: } break; case Item::Command::TYPE_PARTICLES: { - const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); if (particles_cmd->particles.is_valid()) { AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); @@ -1143,7 +1125,6 @@ public: } break; case Item::Command::TYPE_TRANSFORM: { - const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); xf = transform->xform; found_xform = true; @@ -1226,7 +1207,6 @@ public: } struct CustomData { - virtual ~CustomData() {} }; @@ -1288,7 +1268,9 @@ public: for (int i = 0; i < blocks.size(); i++) { memfree(blocks[i].memory); } - if (copy_back_buffer) memdelete(copy_back_buffer); + if (copy_back_buffer) { + memdelete(copy_back_buffer); + } if (custom_data) { memdelete(custom_data); } @@ -1299,7 +1281,6 @@ public: virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0; struct LightOccluderInstance { - bool enabled; RID canvas; RID polygon; @@ -1365,6 +1346,8 @@ public: virtual void end_frame(bool p_swap_buffers) = 0; virtual void finalize() = 0; + virtual uint64_t get_frame_number() const = 0; + virtual float get_frame_delta_time() const = 0; virtual bool is_low_end() const = 0; diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp index f75308a975..efb48e6df7 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp @@ -45,7 +45,6 @@ void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraM } void LightClusterBuilder::bake_cluster() { - float slice_depth = (z_near - z_far) / depth; uint8_t *cluster_dataw = cluster_data.ptrw(); @@ -56,7 +55,6 @@ void LightClusterBuilder::bake_cluster() { /* Step 1, create cell positions and count them */ for (uint32_t i = 0; i < item_count; i++) { - const Item &item = items[i]; int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth); @@ -70,7 +68,6 @@ void LightClusterBuilder::bake_cluster() { to_slice = MIN((int)depth - 1, to_slice); for (int j = from_slice; j <= to_slice; j++) { - Vector3 min = item.aabb.position; Vector3 max = item.aabb.position + item.aabb.size; @@ -126,7 +123,6 @@ void LightClusterBuilder::bake_cluster() { sort_id_max = nearest_power_of_2_templated(sort_id_max + 1); sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max); if (ids.size()) { - ids.resize(sort_id_max); RD::get_singleton()->free(items_buffer); items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max); @@ -178,7 +174,6 @@ void LightClusterBuilder::bake_cluster() { } void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) { - if (width == p_width && height == p_height && depth == p_depth) { return; } @@ -208,6 +203,7 @@ void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_ RID LightClusterBuilder::get_cluster_texture() const { return cluster_texture; } + RID LightClusterBuilder::get_cluster_indices_buffer() const { return items_buffer; } @@ -231,8 +227,8 @@ LightClusterBuilder::LightClusterBuilder() { items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024); item_max = 1024; } -LightClusterBuilder::~LightClusterBuilder() { +LightClusterBuilder::~LightClusterBuilder() { if (cluster_data.size()) { RD::get_singleton()->free(cluster_texture); } diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h index 78288dc620..b1da083dad 100644 --- a/servers/rendering/rasterizer_rd/light_cluster_builder.h +++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h @@ -170,7 +170,6 @@ public: _add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count); } break; case LIGHT_TYPE_SPOT: { - float r = ld.radius; real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r; @@ -187,7 +186,6 @@ public: } _FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(refprobe_count == refprobe_max)) { refprobe_max = nearest_power_of_2_templated(refprobe_max + 1); refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max); @@ -233,7 +231,6 @@ public: } _FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) { - if (unlikely(decal_count == decal_max)) { decal_max = nearest_power_of_2_templated(decal_max + 1); decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max); diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp index 1a21fdb4d7..4c477ca5f4 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp @@ -34,7 +34,6 @@ #include "rasterizer_rd.h" void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) { - p_mat4[0] = p_transform.elements[0][0]; p_mat4[1] = p_transform.elements[0][1]; p_mat4[2] = 0; @@ -54,7 +53,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_trans } void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) { - p_mat2x4[0] = p_transform.elements[0][0]; p_mat2x4[1] = p_transform.elements[1][0]; p_mat2x4[2] = 0; @@ -67,7 +65,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra } void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) { - p_mat2x3[0] = p_transform.elements[0][0]; p_mat2x3[1] = p_transform.elements[0][1]; p_mat2x3[2] = p_transform.elements[1][0]; @@ -77,7 +74,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_tra } void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) { - p_mat4[0] = p_transform.basis.elements[0][0]; p_mat4[1] = p_transform.basis.elements[1][0]; p_mat4[2] = p_transform.basis.elements[2][0]; @@ -97,7 +93,6 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, } void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, uint32_t *r_ss) { - *r_ss = uint32_t(CLAMP(p_transform.a * 255.0, 0, 255)) << 24; *r_ss |= uint32_t(CLAMP(p_transform.b * 255.0, 0, 255)) << 16; *r_ss |= uint32_t(CLAMP(p_transform.g * 255.0, 0, 255)) << 8; @@ -105,7 +100,6 @@ void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, ui } RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { - Vector<RD::Uniform> uniform_set; { // COLOR TEXTURE @@ -169,7 +163,6 @@ RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, } RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) { - if (p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) { p_filter = default_samplers.default_filter; } @@ -221,7 +214,6 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R } void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) { - TextureBinding **binding_ptr = bindings.texture_bindings.getptr(p_binding); ERR_FAIL_COND(!binding_ptr); TextureBinding *binding = *binding_ptr; @@ -233,7 +225,6 @@ void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) { } void RasterizerCanvasRD::_dispose_bindings() { - while (bindings.to_dispose_list.first()) { TextureBinding *binding = bindings.to_dispose_list.first()->self(); if (binding->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) { @@ -248,7 +239,6 @@ void RasterizerCanvasRD::_dispose_bindings() { } RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) { - // Care must be taken to generate array formats // in ways where they could be reused, so we will // put single-occuring elements first, and repeated @@ -273,7 +263,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int Vector<uint8_t> polygon_buffer; polygon_buffer.resize(buffer_size * sizeof(float)); - Vector<RD::VertexDescription> descriptions; + Vector<RD::VertexAttribute> descriptions; descriptions.resize(4); Vector<RID> buffers; buffers.resize(4); @@ -284,7 +274,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int uint32_t *uptr = (uint32_t *)r; uint32_t base_offset = 0; { //vertices - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_VERTEX; @@ -304,7 +294,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //colors if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_COLOR; @@ -332,7 +322,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_COLOR; @@ -344,7 +334,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //uvs if ((uint32_t)p_uvs.size() == vertex_count) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_TEX_UV; @@ -360,7 +350,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } base_offset += 2; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; vd.offset = 0; vd.location = RS::ARRAY_TEX_UV; @@ -372,7 +362,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int //bones if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = base_offset * sizeof(float); vd.location = RS::ARRAY_BONES; @@ -384,7 +374,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int const float *weight_ptr = p_weights.ptr(); for (uint32_t i = 0; i < vertex_count; i++) { - uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride]; uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2]; @@ -401,7 +390,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int base_offset += 4; } else { - RD::VertexDescription vd; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; vd.offset = 0; vd.location = RS::ARRAY_BONES; @@ -450,7 +439,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int } void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { - PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon); ERR_FAIL_COND(!pb_ptr); @@ -470,7 +458,6 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) { } Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD::DrawListID p_draw_list, uint32_t &flags) { - TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(p_binding); ERR_FAIL_COND_V(!texture_binding_ptr, Size2i()); TextureBinding *texture_binding = *texture_binding_ptr; @@ -498,7 +485,6 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD: //////////////////// void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) { - //create an empty push constant PushConstant push_constant; @@ -541,13 +527,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ PipelineLightMode light_mode; { - Light *light = p_lights; while (light) { - if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { - uint32_t light_index = light->render_index_cache; push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8); @@ -575,7 +558,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } { - RID &canvas_item_state = light_count ? state_data->state_uniform_set_with_light : state_data->state_uniform_set; bool invalid_uniform = canvas_item_state.is_valid() && !RD::get_singleton()->uniform_set_is_valid(canvas_item_state); @@ -640,7 +622,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } { - RD::Uniform u_lights; u_lights.type = RD::UNIFORM_TYPE_TEXTURE; u_lights.binding = 4; @@ -652,7 +633,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ //lights for (uint32_t i = 0; i < state.max_lights_per_item; i++) { if (i < light_count) { - CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal); ERR_CONTINUE(!cl); @@ -711,7 +691,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ switch (c->type) { case Item::Command::TYPE_RECT: { - const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c); //bind pipeline @@ -811,7 +790,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_NINEPATCH: { - const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c); //bind pipeline @@ -839,12 +817,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y); if (texpixel_size == Size2()) { - texpixel_size = Size2(1, 1); src_rect = Rect2(0, 0, 1, 1); } else { - if (np->source != Rect2()) { src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height); texpixel_size = Size2(1.0 / np->source.size.width, 1.0 / np->source.size.height); @@ -889,7 +865,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_POLYGON: { - const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c); PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id); @@ -945,7 +920,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; case Item::Command::TYPE_PRIMITIVE: { - const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c); //bind pipeline @@ -1291,23 +1265,18 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } break; #endif case Item::Command::TYPE_TRANSFORM: { - const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c); _update_transform_2d_to_mat2x3(base_transform * transform->xform, push_constant.world); } break; case Item::Command::TYPE_CLIP_IGNORE: { - const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c); if (current_clip) { - if (ci->ignore != reclip) { - if (ci->ignore) { RD::get_singleton()->draw_list_disable_scissor(p_draw_list); reclip = true; } else { - RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect); reclip = false; } @@ -1327,7 +1296,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_ } void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set) { - Item *current_clip = nullptr; Transform2D canvas_transform_inverse = p_canvas_transform_inverse; @@ -1357,33 +1325,27 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, PipelineVariants *pipeline_variants = &shader.pipeline_variants; for (int i = 0; i < p_item_count; i++) { - Item *ci = items[i]; if (current_clip != ci->final_clip_owner) { - current_clip = ci->final_clip_owner; //setup clip if (current_clip) { - RD::get_singleton()->draw_list_enable_scissor(draw_list, current_clip->final_clip_rect); } else { - RD::get_singleton()->draw_list_disable_scissor(draw_list); } } if (ci->material != prev_material) { - MaterialData *material_data = nullptr; if (ci->material.is_valid()) { material_data = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); } if (material_data) { - if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) { pipeline_variants = &material_data->shader_data->pipeline_variants; if (material_data->uniform_set.is_valid()) { @@ -1406,7 +1368,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, } void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) { - int item_count = 0; //setup canvas state uniforms if needed @@ -1447,12 +1408,10 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite //setup lights if exist { - Light *l = p_light_list; uint32_t index = 0; while (l) { - if (index == state.max_lights_per_render) { l->render_index_cache = -1; l = l->next_ptr; @@ -1513,7 +1472,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite RID screen_uniform_set; while (ci) { - if (ci->copy_back_buffer) { backbuffer_copy = true; @@ -1527,7 +1485,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite if (ci->material.is_valid()) { MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D); if (md && md->shader_data->valid) { - if (md->shader_data->uses_screen_texture) { if (!material_screen_texture_found) { backbuffer_copy = true; @@ -1539,8 +1496,8 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } } - if (md->last_frame != RasterizerRD::get_frame_number()) { - md->last_frame = RasterizerRD::get_frame_number(); + if (md->last_frame != RasterizerRD::singleton->get_frame_number()) { + md->last_frame = RasterizerRD::singleton->get_frame_number(); if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) { // uniform set may be gone because a dependency was erased. In this case, it will happen // if a texture is deleted, so just re-create it. @@ -1574,7 +1531,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite } RID RasterizerCanvasRD::light_create() { - CanvasLight canvas_light; canvas_light.shadow.size = 0; return canvas_light_owner.make_rid(canvas_light); @@ -1589,6 +1545,7 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) { cl->texture = p_texture; } + void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(!cl); @@ -1598,7 +1555,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } if (cl->shadow.texture.is_valid()) { - RD::get_singleton()->free(cl->shadow.fb); RD::get_singleton()->free(cl->shadow.depth); RD::get_singleton()->free(cl->shadow.texture); @@ -1608,7 +1564,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } if (p_enable) { - Vector<RID> fb_textures; { //texture @@ -1641,12 +1596,10 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re } void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) { - CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND(cl->shadow.texture.is_null()); for (int i = 0; i < 4; i++) { - //make sure it remains orthogonal, makes easy to read angle later //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); @@ -1691,11 +1644,9 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig LightOccluderInstance *instance = p_occluders; while (instance) { - OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder); if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) { - instance = instance->next; continue; } @@ -1717,7 +1668,6 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig } RID RasterizerCanvasRD::occluder_polygon_create() { - OccluderPolygon occluder; occluder.point_count = 0; occluder.cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; @@ -1725,12 +1675,10 @@ RID RasterizerCanvasRD::occluder_polygon_create() { } void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) { - OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); if (oc->point_count != p_lines.size() && oc->vertex_array.is_valid()) { - RD::get_singleton()->free(oc->vertex_array); RD::get_singleton()->free(oc->vertex_buffer); RD::get_singleton()->free(oc->index_array); @@ -1743,7 +1691,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con } if (p_lines.size()) { - Vector<uint8_t> geometry; Vector<uint8_t> indices; int lc = p_lines.size(); @@ -1762,7 +1709,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con const int POLY_HEIGHT = 16384; for (int i = 0; i < lc / 2; i++) { - vwptr[i * 12 + 0] = lr[i * 2 + 0].x; vwptr[i * 12 + 1] = lr[i * 2 + 0].y; vwptr[i * 12 + 2] = POLY_HEIGHT; @@ -1813,6 +1759,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con } } } + void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) { OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder); ERR_FAIL_COND(!oc); @@ -1895,12 +1842,10 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { switch (blend_mode) { case BLEND_MODE_DISABLED: { - // nothing to do here, disabled by default } break; case BLEND_MODE_MIX: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_ADD; attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -1911,7 +1856,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_ADD: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_ADD; attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -1922,7 +1866,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_SUB: { - attachment.enable_blend = true; attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT; attachment.color_blend_op = RD::BLEND_OP_SUBTRACT; @@ -2014,12 +1957,11 @@ void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName default_texture_params[p_name] = p_texture; } } -void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } @@ -2031,7 +1973,6 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -2039,9 +1980,7 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_ } void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -2066,9 +2005,11 @@ bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param) bool RasterizerCanvasRD::ShaderData::is_animated() const { return false; } + bool RasterizerCanvasRD::ShaderData::casts_shadows() const { return false; } + Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; @@ -2097,8 +2038,8 @@ RasterizerStorageRD::ShaderData *RasterizerCanvasRD::_create_shader_func() { ShaderData *shader_data = memnew(ShaderData); return shader_data; } -void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { @@ -2123,7 +2064,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -2142,7 +2082,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false); } @@ -2201,6 +2140,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), 1); } + RasterizerCanvasRD::MaterialData::~MaterialData() { if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) { RD::get_singleton()->free(uniform_set); @@ -2423,8 +2363,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } //pipelines - Vector<RD::VertexDescription> vf; - RD::VertexDescription vd; + Vector<RD::VertexAttribute> vf; + RD::VertexAttribute vd; vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; vd.location = 0; vd.offset = 0; @@ -2514,7 +2454,6 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) { } bool RasterizerCanvasRD::free(RID p_rid) { - if (canvas_light_owner.owns(p_rid)) { CanvasLight *cl = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!cl, false); @@ -2531,7 +2470,6 @@ bool RasterizerCanvasRD::free(RID p_rid) { } RasterizerCanvasRD::~RasterizerCanvasRD() { - //canvas state { @@ -2547,14 +2485,12 @@ RasterizerCanvasRD::~RasterizerCanvasRD() { //shadow rendering { - shadow_render.shader.version_free(shadow_render.shader_version); //this will also automatically clear all pipelines RD::get_singleton()->free(state.shadow_sampler); } //bindings { - free_texture_binding(bindings.default_empty); //dispose pending diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h index 4d47b3e13b..bfe4e61f47 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h @@ -40,7 +40,6 @@ #include "servers/rendering/rendering_device.h" class RasterizerCanvasRD : public RasterizerCanvas { - RasterizerStorageRD *storage; enum ShaderVariant { @@ -149,7 +148,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { } shader; struct ShaderData : public RasterizerStorageRD::ShaderData { - enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -313,7 +311,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { /******************/ struct CanvasLight { - RID texture; struct { int size; @@ -333,7 +330,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { }; struct OccluderPolygon { - RS::CanvasOccluderPolygonCullMode cull_mode; int point_count; RID vertex_buffer; @@ -371,7 +367,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { //state that does not vary across rendering all items struct ItemStateData : public Item::CustomData { - struct LightCache { uint64_t light_version; Light *light; @@ -382,7 +377,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { RID state_uniform_set_with_light; RID state_uniform_set; ItemStateData() { - for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) { light_cache[i].light_version = 0; light_cache[i].light = nullptr; @@ -401,7 +395,6 @@ class RasterizerCanvasRD : public RasterizerCanvas { }; struct State { - //state buffer struct Buffer { float canvas_transform[16]; @@ -489,7 +482,7 @@ public: void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform); - void canvas_debug_viewport_shadows(Light *p_lights_with_shadow){}; + void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {} void draw_window_margins(int *p_margins, RID *p_margin_textures) {} diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp index d469dd97ca..303cb7ad42 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp @@ -51,17 +51,14 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar } static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; } } } RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { - if (image_to_uniform_set_cache.has(p_image)) { RID uniform_set = image_to_uniform_set_cache[p_image]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -83,7 +80,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) { } RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { - if (texture_to_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -107,7 +103,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use } RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) { - if (texture_to_compute_uniform_set_cache.has(p_texture)) { RID uniform_set = texture_to_compute_uniform_set_cache[p_texture]; if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { @@ -131,7 +126,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo } RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { - TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -169,7 +163,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur } RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { - TexturePair tp; tp.texture1 = p_texture1; tp.texture2 = p_texture2; @@ -205,7 +198,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1 } void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { - zeromem(©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); copy_to_fb.push_constant.use_section = true; @@ -249,7 +241,6 @@ void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_fr } void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -282,8 +273,30 @@ void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_textu RD::get_singleton()->compute_list_end(); } -void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { +void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { + zeromem(©.push_constant, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_panorama_size.width; + copy.push_constant.section[3] = p_panorama_size.height; + copy.push_constant.target[0] = 0; + copy.push_constant.target[1] = 0; + copy.push_constant.camera_z_far = p_lod; + + int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1; + int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1; + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -311,7 +324,6 @@ void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_textu } void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); if (p_flip_y) { copy.push_constant.flags |= COPY_FLAG_FLIP_Y; @@ -337,7 +349,6 @@ void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest } void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); uint32_t base_flags = 0; @@ -373,7 +384,6 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, } void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; @@ -425,7 +435,6 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, } void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -454,7 +463,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } { - ssr.push_constant.camera_z_far = p_camera.get_z_far(); ssr.push_constant.camera_z_near = p_camera.get_z_near(); ssr.push_constant.orthogonal = p_camera.is_orthogonal(); @@ -494,7 +502,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { - //blurr RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -551,7 +558,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R } void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); int32_t x_groups = (p_screen_size.width - 1) / 8 + 1; @@ -598,11 +604,9 @@ void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, } void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>()); if (p_reflection.is_valid()) { - if (p_base.is_valid()) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); @@ -614,7 +618,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1); } else { - if (p_base.is_valid()) { RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); @@ -631,7 +634,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, } void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { - zeromem(©.push_constant, sizeof(CopyPushConstant)); copy.push_constant.section[0] = 0; @@ -652,7 +654,6 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_textur } void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { - CopyToDPPushConstant push_constant; push_constant.screen_size[0] = p_rect.size.x; push_constant.screen_size[1] = p_rect.size.y; @@ -676,7 +677,6 @@ void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest } void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { - zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant)); tonemap.push_constant.use_bcs = p_settings.use_bcs; @@ -719,7 +719,6 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, } void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { - luminance_reduce.push_constant.source_size[0] = p_source_size.x; luminance_reduce.push_constant.source_size[1] = p_source_size.y; luminance_reduce.push_constant.max_luminance = p_max_luminance; @@ -729,12 +728,10 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); for (int i = 0; i < p_reduce.size(); i++) { - if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_texture), 0); } else { - RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done if (i == p_reduce.size() - 1 && !p_set) { @@ -764,7 +761,6 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i } void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { - bokeh.push_constant.blur_far_active = p_dof_far; bokeh.push_constant.blur_far_begin = p_dof_far_begin; bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; @@ -807,7 +803,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con RD::get_singleton()->compute_list_add_barrier(compute_list); if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { - //second pass RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL]); @@ -843,7 +838,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con bokeh.push_constant.second_pass = true; if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture2), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1); } else { @@ -927,7 +921,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con } void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) { - //minify first ssao.minify_push_constant.orthogonal = p_projection.is_orthogonal(); ssao.minify_push_constant.z_near = p_projection.get_z_near(); @@ -943,7 +936,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, // Minify the depth buffer. for (int i = 0; i < depth_mipmaps.size(); i++) { - if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_MINIFY_FIRST]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0); @@ -1027,7 +1019,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, ssao.blur_push_constant.axis[1] = 0; if (p_blur != RS::ENV_SSAO_BLUR_DISABLED) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[p_half_size ? SSAO_BLUR_PASS_HALF : SSAO_BLUR_PASS]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao1), 0); if (p_half_size) { @@ -1083,7 +1074,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, } void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) { - roughness_limiter.push_constant.screen_size[0] = p_size.x; roughness_limiter.push_constant.screen_size[1] = p_size.y; roughness_limiter.push_constant.curve = p_curve; @@ -1104,7 +1094,6 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, } void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) { - zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; @@ -1130,7 +1119,6 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_ } void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) { - cubemap_downsampler.push_constant.face_size = p_size.x; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -1149,7 +1137,6 @@ void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cu } void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { - Vector<RD::Uniform> uniforms; for (int i = 0; i < p_dest_cubemap.size(); i++) { RD::Uniform u; @@ -1179,7 +1166,6 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des } void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) { - SkyPushConstant sky_push_constant; zeromem(&sky_push_constant, sizeof(SkyPushConstant)); @@ -1202,7 +1188,9 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format)); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_samplers, 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1); + if (p_uniform_set.is_valid()) { //material may not have uniform set + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1); + } RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_lights, 3); @@ -1214,7 +1202,6 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_ } RasterizerEffectsRD::RasterizerEffectsRD() { - { // Initialize copy Vector<String> copy_modes; copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); @@ -1226,6 +1213,8 @@ RasterizerEffectsRD::RasterizerEffectsRD() { copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); copy_modes.push_back("\n#define MODE_MIPMAP\n"); copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_TO_PANORAMA\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n"); copy.shader.initialize(copy_modes); zeromem(©.push_constant, sizeof(CopyPushConstant)); @@ -1464,7 +1453,6 @@ RasterizerEffectsRD::RasterizerEffectsRD() { blend_additive.attachments.push_back(ba); for (int i = 0; i < SPECULAR_MERGE_MAX; i++) { - RD::PipelineColorBlendState blend_state; if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) { blend_state = blend_additive; diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h index 531591442b..8a55d2d13c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h @@ -55,7 +55,6 @@ #include "servers/rendering_server.h" class RasterizerEffectsRD { - enum CopyMode { COPY_MODE_GAUSSIAN_COPY, COPY_MODE_GAUSSIAN_COPY_8BIT, @@ -66,6 +65,8 @@ class RasterizerEffectsRD { COPY_MODE_SIMPLY_COPY_DEPTH, COPY_MODE_MIPMAP, COPY_MODE_LINEARIZE_DEPTH, + COPY_MODE_CUBE_TO_PANORAMA, + COPY_MODE_CUBE_ARRAY_TO_PANORAMA, COPY_MODE_MAX, }; @@ -82,7 +83,6 @@ class RasterizerEffectsRD { }; struct CopyPushConstant { - int32_t section[4]; int32_t target[2]; uint32_t flags; @@ -119,7 +119,6 @@ class RasterizerEffectsRD { }; struct CopyToFbPushConstant { - float section[4]; float pixel_size[2]; uint32_t flip_y; @@ -148,7 +147,6 @@ class RasterizerEffectsRD { }; struct CubemapRoughness { - CubemapRoughnessPushConstant push_constant; CubemapRoughnessShaderRD shader; RID shader_version; @@ -212,7 +210,6 @@ class RasterizerEffectsRD { }; struct LuminanceReduce { - LuminanceReducePushConstant push_constant; LuminanceReduceShaderRD shader; RID shader_version; @@ -229,7 +226,6 @@ class RasterizerEffectsRD { }; struct CoptToDP { - CubeToDpShaderRD shader; RID shader_version; RID pipeline; @@ -270,7 +266,6 @@ class RasterizerEffectsRD { }; struct Bokeh { - BokehPushConstant push_constant; BokehDofShaderRD shader; RID shader_version; @@ -331,7 +326,6 @@ class RasterizerEffectsRD { }; struct SSAO { - SSAOMinifyPushConstant minify_push_constant; SsaoMinifyShaderRD minify_shader; RID minify_shader_version; @@ -354,7 +348,6 @@ class RasterizerEffectsRD { }; struct RoughnessLimiter { - RoughnessLimiterPushConstant push_constant; RoughnessLimiterShaderRD shader; RID shader_version; @@ -368,7 +361,6 @@ class RasterizerEffectsRD { }; struct CubemapDownsampler { - CubemapDownsamplerPushConstant push_constant; CubemapDownsamplerShaderRD shader; RID shader_version; @@ -385,7 +377,6 @@ class RasterizerEffectsRD { }; struct CubemapFilter { - CubemapFilterShaderRD shader; RID shader_version; RID pipelines[FILTER_MODE_MAX]; @@ -418,7 +409,6 @@ class RasterizerEffectsRD { */ struct SpecularMerge { - SpecularMergeShaderRD shader; RID shader_version; RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX]; @@ -432,7 +422,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionPushConstant { - float proj_info[4]; int32_t screen_size[2]; @@ -453,7 +442,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflection { - ScreenSpaceReflectionPushConstant push_constant; ScreenSpaceReflectionShaderRD shader; RID shader_version; @@ -462,7 +450,6 @@ class RasterizerEffectsRD { } ssr; struct ScreenSpaceReflectionFilterPushConstant { - float proj_info[4]; uint32_t orthogonal; @@ -481,7 +468,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionFilter { - ScreenSpaceReflectionFilterPushConstant push_constant; ScreenSpaceReflectionFilterShaderRD shader; RID shader_version; @@ -489,7 +475,6 @@ class RasterizerEffectsRD { } ssr_filter; struct ScreenSpaceReflectionScalePushConstant { - int32_t screen_size[2]; float camera_z_near; float camera_z_far; @@ -500,7 +485,6 @@ class RasterizerEffectsRD { }; struct ScreenSpaceReflectionScale { - ScreenSpaceReflectionScalePushConstant push_constant; ScreenSpaceReflectionScaleShaderRD shader; RID shader_version; @@ -508,7 +492,6 @@ class RasterizerEffectsRD { } ssr_scale; struct SubSurfaceScatteringPushConstant { - int32_t screen_size[2]; float camera_z_far; float camera_z_near; @@ -523,7 +506,6 @@ class RasterizerEffectsRD { }; struct SubSurfaceScattering { - SubSurfaceScatteringPushConstant push_constant; SubsurfaceScatteringShaderRD shader; RID shader_version; @@ -564,6 +546,7 @@ class RasterizerEffectsRD { public: void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false); void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false); + void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); @@ -577,7 +560,6 @@ public: void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); struct TonemapSettings { - bool use_glow = false; enum GlowMode { GLOW_MODE_ADD, diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp index 9c54f0caae..18cf4fa340 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp @@ -30,12 +30,13 @@ #include "rasterizer_rd.h" +#include "core/project_settings.h" + void RasterizerRD::prepare_for_blitting_render_targets() { RD::get_singleton()->prepare_screen_for_drawing(); } void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); for (int i = 0; i < p_amount; i++) { @@ -77,13 +78,17 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree void RasterizerRD::begin_frame(double frame_step) { frame++; + delta = frame_step; time += frame_step; + + double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); + time = Math::fmod(time, time_roll_over); + canvas->set_time(time); scene->set_time(time, frame_step); } void RasterizerRD::end_frame(bool p_swap_buffers) { - #ifndef _MSC_VER #warning TODO: likely passa bool to swap buffers to avoid display? #endif @@ -91,7 +96,6 @@ void RasterizerRD::end_frame(bool p_swap_buffers) { } void RasterizerRD::initialize() { - { //create framebuffer copy shader RenderingDevice::ShaderStageData vert; vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX; @@ -151,10 +155,9 @@ void RasterizerRD::initialize() { } ThreadWorkPool RasterizerRD::thread_work_pool; -uint32_t RasterizerRD::frame = 1; +uint64_t RasterizerRD::frame = 1; void RasterizerRD::finalize() { - thread_work_pool.finish(); memdelete(scene); @@ -167,7 +170,10 @@ void RasterizerRD::finalize() { RD::get_singleton()->free(copy_viewports_sampler); } +RasterizerRD *RasterizerRD::singleton = nullptr; + RasterizerRD::RasterizerRD() { + singleton = this; thread_work_pool.init(); time = 0; diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/rasterizer_rd/rasterizer_rd.h index 756b9499ca..cb53a531ac 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_rd.h @@ -53,8 +53,9 @@ protected: Map<RID, RID> render_target_descriptors; double time; + float delta; - static uint32_t frame; + static uint64_t frame; public: RasterizerStorage *get_storage() { return storage; } @@ -71,7 +72,8 @@ public: void end_frame(bool p_swap_buffers); void finalize(); - static _ALWAYS_INLINE_ uint64_t get_frame_number() { return frame; } + _ALWAYS_INLINE_ uint64_t get_frame_number() const { return frame; } + _ALWAYS_INLINE_ float get_frame_delta_time() const { return delta; } static Error is_viable() { return OK; @@ -89,6 +91,7 @@ public: static ThreadWorkPool thread_work_pool; + static RasterizerRD *singleton; RasterizerRD(); ~RasterizerRD() {} }; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index b3cf40f166..7d351f249a 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -67,33 +67,30 @@ static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) { p_array[11] = 0; } -static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_array) { - p_array[0] = p_mtx.basis.elements[0][0]; - p_array[1] = p_mtx.basis.elements[1][0]; - p_array[2] = p_mtx.basis.elements[2][0]; +static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) { + p_array[0] = p_mtx.elements[0][0]; + p_array[1] = p_mtx.elements[1][0]; + p_array[2] = p_mtx.elements[2][0]; p_array[3] = 0; - p_array[4] = p_mtx.basis.elements[0][1]; - p_array[5] = p_mtx.basis.elements[1][1]; - p_array[6] = p_mtx.basis.elements[2][1]; + p_array[4] = p_mtx.elements[0][1]; + p_array[5] = p_mtx.elements[1][1]; + p_array[6] = p_mtx.elements[2][1]; p_array[7] = 0; - p_array[8] = p_mtx.basis.elements[0][2]; - p_array[9] = p_mtx.basis.elements[1][2]; - p_array[10] = p_mtx.basis.elements[2][2]; + p_array[8] = p_mtx.elements[0][2]; + p_array[9] = p_mtx.elements[1][2]; + p_array[10] = p_mtx.elements[2][2]; p_array[11] = 0; } static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; } } } static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) { - for (int i = 0; i < 128; i++) { p_array[i] = p_kernel[i]; } @@ -224,7 +221,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { switch (blend_mode) { case BLEND_MODE_MIX: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD; blend_attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -235,7 +231,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_ADD: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD; blend_attachment.color_blend_op = RD::BLEND_OP_ADD; @@ -247,7 +242,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } break; case BLEND_MODE_SUB: { - blend_attachment.enable_blend = true; blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT; blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT; @@ -288,7 +282,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { } for (int i = 0; i < CULL_VARIANT_MAX; i++) { - RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = { { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK }, { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT }, @@ -298,7 +291,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull]; for (int j = 0; j < RS::PRIMITIVE_MAX; j++) { - RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = { RD::RENDER_PRIMITIVE_POINTS, RD::RENDER_PRIMITIVE_LINES, @@ -310,7 +302,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j]; for (int k = 0; k < SHADER_VERSION_MAX; k++) { - RD::PipelineRasterizationState raster_state; raster_state.cull_mode = cull_mode_rd; raster_state.wireframe = wireframe; @@ -337,7 +328,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) { continue; // do not use this version (will error if using it is attempted) } } else { - if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_VCT_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) { blend_state = blend_state_opaque; } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) { @@ -373,11 +363,9 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin } void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { continue; } @@ -390,7 +378,6 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -398,9 +385,7 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_ } void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -429,6 +414,7 @@ bool RasterizerSceneHighEndRD::ShaderData::is_animated() const { bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const { return false; } + Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; @@ -466,7 +452,6 @@ void RasterizerSceneHighEndRD::MaterialData::set_next_pass(RID p_pass) { } void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton; if ((uint32_t)ubo_data.size() != shader_data->ubo_size) { @@ -491,7 +476,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -510,7 +494,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true); } @@ -527,7 +510,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN Vector<RD::Uniform> uniforms; { - if (shader_data->ubo_size) { RD::Uniform u; u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; @@ -572,7 +554,6 @@ RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() { } void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { - if (!specular.is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; @@ -588,7 +569,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { specular = RD::get_singleton()->texture_create(tf, RD::TextureView()); if (msaa == RS::VIEWPORT_MSAA_DISABLED) { - { Vector<RID> fb; fb.push_back(color); @@ -605,7 +585,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { } } else { - tf.samples = texture_samples; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); @@ -629,7 +608,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() { } void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() { - if (color_msaa.is_valid()) { RD::get_singleton()->free(color_msaa); color_msaa = RID(); @@ -689,7 +667,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu depth = p_depth_buffer; if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) { - { Vector<RID> fb; fb.push_back(p_color_buffer); @@ -704,7 +681,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu depth_fb = RD::get_singleton()->framebuffer_create(fb); } } else { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = p_width; @@ -785,7 +761,6 @@ void RasterizerSceneHighEndRD::_allocate_normal_texture(RenderBufferDataHighEnd } void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighEnd *rb) { - if (rb->roughness_buffer.is_valid()) { return; } @@ -807,7 +782,6 @@ void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighE rb->roughness_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView()); if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) { - Vector<RID> fb; fb.push_back(rb->depth); fb.push_back(rb->normal_buffer); @@ -840,9 +814,9 @@ bool RasterizerSceneHighEndRD::free(RID p_rid) { } void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth) { + uint32_t lightmap_captures_used = 0; for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; InstanceData &id = scene_state.instances[i]; store_transform(e->instance->transform, id.transform); @@ -898,6 +872,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, if (written == 0) { id.gi_offset = index; + id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE; written = 1; } else { id.gi_offset = index << 16; @@ -910,18 +885,51 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, } else if (written == 1) { id.gi_offset |= 0xFFFF0000; } + } else if (e->instance->lightmap) { + int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base); + if (lightmap_index >= 0) { + id.gi_offset = lightmap_index; + id.gi_offset |= e->instance->lightmap_slice_index << 12; + id.gi_offset |= e->instance->lightmap_cull_index << 20; + id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x; + id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y; + id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width; + id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height; + id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP; + if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) { + id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP; + } + } else { + id.gi_offset = 0xFFFFFFFF; + } + } else if (!e->instance->lightmap_sh.empty()) { + if (lightmap_captures_used < scene_state.max_lightmap_captures) { + const Color *src_capture = e->instance->lightmap_sh.ptr(); + LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used]; + for (int j = 0; j < 9; j++) { + lcd.sh[j * 4 + 0] = src_capture[j].r; + lcd.sh[j * 4 + 1] = src_capture[j].g; + lcd.sh[j * 4 + 2] = src_capture[j].b; + lcd.sh[j * 4 + 3] = src_capture[j].a; + } + id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE; + id.gi_offset = lightmap_captures_used; + lightmap_captures_used++; + } } else { id.gi_offset = 0xFFFFFFFF; } } RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true); + if (lightmap_captures_used) { + RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true); + } } /// RENDERING /// -void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set) { - +void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) { RD::DrawListID draw_list = p_draw_list; RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format; @@ -949,9 +957,10 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l PushConstant push_constant; zeromem(&push_constant, sizeof(PushConstant)); + push_constant.bake_uv2_offset[0] = p_uv_offset.x; + push_constant.bake_uv2_offset[1] = p_uv_offset.y; for (int i = 0; i < p_element_count; i++) { - const RenderList::Element *e = p_elements[i]; MaterialData *material = e->material; @@ -961,7 +970,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l //find cull variant ShaderData::CullVariant cull_variant; - if ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) { + if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) { cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED; } else { bool mirror = e->instance->mirror; @@ -1080,7 +1089,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l prev_index_array_rd = index_array_rd; } - RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format); + RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe); if (pipeline_rd != prev_pipeline_rd) { // checking with prev shader does not make so much sense, as @@ -1115,10 +1124,8 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances); } break; case RS::INSTANCE_IMMEDIATE: { - } break; case RS::INSTANCE_PARTICLES: { - } break; default: { ERR_CONTINUE(true); //should be a bug @@ -1128,7 +1135,6 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l } void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) { - //CameraMatrix projection = p_cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down CameraMatrix correction; @@ -1173,7 +1179,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.time = time; if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - scene_state.ubo.use_ambient_light = true; scene_state.ubo.ambient_light_color_energy[0] = 1; scene_state.ubo.ambient_light_color_energy[1] = 1; @@ -1184,7 +1189,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.ssao_enabled = false; } else if (is_environment(p_environment)) { - RS::EnvironmentBG env_bg = environment_get_background(p_environment); RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment); @@ -1195,7 +1199,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment); color = color.to_linear(); @@ -1205,7 +1208,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = environment_get_ambient_light_energy(p_environment); Color color = environment_get_ambient_light_color(p_environment); color = color.to_linear(); @@ -1240,7 +1242,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.ao_color[3] = ao_color.a; } else { - if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) { scene_state.ubo.use_ambient_light = false; } else { @@ -1255,6 +1256,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer scene_state.ubo.use_ambient_cubemap = false; scene_state.ubo.use_reflection_cubemap = false; + scene_state.ubo.ssao_enabled = false; } scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active(); @@ -1263,7 +1265,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer } void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index) { - RID m_src; m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material; @@ -1271,8 +1272,6 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) { if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { m_src = overdraw_material; - } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME) { - m_src = wireframe_material; } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) { m_src = default_material; } @@ -1297,16 +1296,15 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t _add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index); while (material->next_pass.is_valid()) { - material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D); - if (!material || !material->shader_data->valid) + if (!material || !material->shader_data->valid) { break; + } _add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index); } } void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index) { - bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture; bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha); bool has_blend_alpha = p_material->shader_data->uses_blend_alpha; @@ -1329,7 +1327,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta } if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) { - if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { //conditions in which no depth pass should be processed return; @@ -1351,8 +1348,9 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta RenderList::Element *e = (has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) ? render_list.add_alpha_element() : render_list.add_element(); - if (!e) + if (!e) { return; + } e->instance = p_instance; e->material = p_material; @@ -1374,7 +1372,7 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta e->geometry_index = p_geometry_index; e->material_index = e->material->index; e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH; - e->uses_lightmap = e->instance->lightmap.is_valid(); + e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.empty(); e->uses_vct = e->instance->gi_probe_instances.size(); e->shader_index = e->shader_index; e->depth_layer = e->instance->depth_layer; @@ -1386,7 +1384,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta } void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi) { - scene_state.current_shader_index = 0; scene_state.current_material_index = 0; scene_state.used_sss = false; @@ -1399,14 +1396,11 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i //fill list for (int i = 0; i < p_cull_count; i++) { - InstanceBase *inst = p_cull_result[i]; //add geometry for drawing switch (inst->base_type) { - case RS::INSTANCE_MESH: { - const RID *materials = nullptr; uint32_t surface_count; @@ -1418,7 +1412,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i const RID *inst_materials = inst->materials.ptr(); for (uint32_t j = 0; j < surface_count; j++) { - RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j]; uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index); @@ -1430,7 +1423,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } break; case RS::INSTANCE_MULTIMESH: { - if (storage->multimesh_get_instances_to_draw(inst->base) == 0) { //not visible, 0 instances continue; @@ -1450,7 +1442,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } for (uint32_t j = 0; j < surface_count; j++) { - uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index); _add_geometry(inst, j, materials[j], p_pass_mode, surface_index); } @@ -1497,9 +1488,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i } void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) { - for (int i = 0; i < p_reflection_probe_cull_count; i++) { - RID rpi = p_reflection_probe_cull_result[i]; if (i >= (int)scene_state.max_reflections) { @@ -1575,12 +1564,29 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r } } -void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) { +void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) { + uint32_t lightmaps_used = 0; + for (int i = 0; i < p_lightmap_cull_count; i++) { + if (i >= (int)scene_state.max_lightmaps) { + break; + } + InstanceBase *lm = p_lightmap_cull_result[i]; + Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis; + to_lm = to_lm.inverse().transposed(); //will transform normals + store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform); + lm->lightmap_cull_index = i; + lightmaps_used++; + } + if (lightmaps_used > 0) { + RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true); + } +} + +void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) { int index = 0; for (int i = 0; i < p_gi_probe_probe_cull_count; i++) { - RID rpi = p_gi_probe_probe_cull_result[i]; if (index >= (int)scene_state.max_gi_probes) { @@ -1631,13 +1637,11 @@ void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_resul } void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows) { - uint32_t light_count = 0; scene_state.ubo.directional_light_count = 0; sky_scene_state.directional_light_count = 0; for (int i = 0; i < p_light_cull_count; i++) { - RID li = p_light_cull_result[i]; RID base = light_instance_get_base_light(li); @@ -1645,9 +1649,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig RS::LightType type = storage->light_get_type(base); switch (type) { - case RS::LIGHT_DIRECTIONAL: { - if (scene_state.ubo.directional_light_count >= scene_state.max_directional_lights) { continue; } @@ -1699,7 +1701,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.shadow_color4[3] = 1.0; } else { - light_data.shadow_color1[0] = shadow_col.r; light_data.shadow_color1[1] = shadow_col.g; light_data.shadow_color1[2] = shadow_col.b; @@ -1720,8 +1721,17 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); - if (light_data.shadow_enabled) { + float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + if (angular_diameter > 0.0) { + // I know tan(0) is 0, but let's not risk it with numerical precision. + // technically this will keep expanding until reaching the sun, but all we care + // is expand until we reach the radius of the near plane (there can't be more occluders than that) + angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); + } else { + angular_diameter = 0.0; + } + if (light_data.shadow_enabled) { RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base); int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); @@ -1775,22 +1785,15 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.fade_to = -light_data.shadow_split_offsets[3]; light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); + light_data.softshadow_angle = angular_diameter; - float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); - if (softshadow_angle > 0.0) { - // I know tan(0) is 0, but let's not risk it with numerical precision. - // technically this will keep expanding until reaching the sun, but all we care - // is expand until we reach the radius of the near plane (there can't be more occluders than that) - light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle)); - } else { - light_data.softshadow_angle = 0; + if (angular_diameter <= 0.0) { light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF } } // Copy to SkyDirectionalLightData if (sky_scene_state.directional_light_count < sky_scene_state.max_directional_lights) { - SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.directional_light_count]; Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); @@ -1806,7 +1809,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig sky_light_data.color[2] = light_data.color[2]; sky_light_data.enabled = true; - sky_light_data.size = light_data.softshadow_angle; + sky_light_data.size = angular_diameter; sky_scene_state.directional_light_count++; } @@ -1814,7 +1817,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } break; case RS::LIGHT_SPOT: case RS::LIGHT_OMNI: { - if (light_count >= scene_state.max_lights) { continue; } @@ -1870,7 +1872,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig Rect2 rect = storage->decal_atlas_get_texture_rect(projector); if (type == RS::LIGHT_SPOT) { - light_data.projector_rect[0] = rect.position.x; light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped light_data.projector_rect[2] = rect.size.width; @@ -1923,14 +1924,12 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR); if (type == RS::LIGHT_OMNI) { - light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another Transform proj = (p_camera_inverse_transform * light_transform).inverse(); store_transform(proj, light_data.shadow_matrix); if (size > 0.0) { - light_data.soft_shadow_size = size; } else { light_data.soft_shadow_size = 0.0; @@ -1938,7 +1937,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } } else if (type == RS::LIGHT_SPOT) { - Transform modelview = (p_camera_inverse_transform * light_transform).inverse(); CameraMatrix bias; bias.set_light_bias(); @@ -1982,7 +1980,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig } void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) { - Transform uv_xform; uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0)); uv_xform.origin = Vector3(-1.0, 0.0, -1.0); @@ -1990,7 +1987,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p p_decal_count = MIN((uint32_t)p_decal_count, scene_state.max_decals); int idx = 0; for (int i = 0; i < p_decal_count; i++) { - RID di = p_decal_instances[i]; RID decal = decal_instance_get_base(di); @@ -2038,7 +2034,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p dd.albedo_rect[2] = rect.size.x; dd.albedo_rect[3] = rect.size.y; } else { - if (!emission_tex.is_valid()) { continue; //no albedo, no emission, no decal. } @@ -2114,8 +2109,7 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p } } -void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { - +void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) { RenderBufferDataHighEnd *render_buffer = nullptr; if (p_render_buffer.is_valid()) { render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer); @@ -2164,7 +2158,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool using_ssr = false; if (render_buffer) { - screen_pixel_size.width = 1.0 / render_buffer->width; screen_pixel_size.height = 1.0 / render_buffer->height; screen_size.x = render_buffer->width; @@ -2234,6 +2227,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor _setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse()); _setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment); _setup_gi_probes(p_gi_probe_cull_result, p_gi_probe_cull_count, p_cam_transform); + _setup_lightmaps(p_lightmap_cull_result, p_lightmap_cull_count, p_cam_transform); _setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false); cluster_builder.bake_cluster(); //bake to cluster @@ -2285,7 +2279,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor keep_color = true; } break; case RS::ENV_BG_CAMERA_FEED: { - } break; default: { } @@ -2294,7 +2287,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (draw_sky || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RID sky = environment_get_sky(p_environment); if (sky.is_valid()) { - RENDER_TIMESTAMP("Setup Sky"); CameraMatrix projection = p_cam_projection; if (p_reflection_probe.is_valid()) { @@ -2312,7 +2304,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } } } else { - clear_color = p_default_bg_color; } @@ -2334,7 +2325,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool finish_depth = using_ssao; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID()); + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID(), get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME); RD::get_singleton()->draw_list_end(); if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { @@ -2373,7 +2364,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; { - bool will_continue_color = (can_continue_color || draw_sky || debug_giprobes); bool will_continue_depth = (can_continue_depth || draw_sky || debug_giprobes); @@ -2390,7 +2380,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (using_ssao ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME); RD::get_singleton()->draw_list_end(); if (will_continue_color && using_separate_specular) { @@ -2429,7 +2419,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); if (using_separate_specular) { RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true); @@ -2437,12 +2426,10 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor } if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true); } if (using_separate_specular) { - if (using_sss) { RENDER_TIMESTAMP("Sub Surface Scattering"); _process_sss(p_render_buffer, p_cam_projection); @@ -2468,18 +2455,16 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); - _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set); + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME); RD::get_singleton()->draw_list_end(); } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true); } } void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); _update_render_base_uniform_set(); @@ -2513,13 +2498,14 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase ** } void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { - RENDER_TIMESTAMP("Setup Rendering Shadow"); + RENDER_TIMESTAMP("Setup Rendering Material"); _update_render_base_uniform_set(); render_pass++; scene_state.ubo.dual_paraboloid_side = 0; + scene_state.ubo.material_uv2_mode = true; _setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); @@ -2550,8 +2536,68 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform } } -void RasterizerSceneHighEndRD::_base_uniforms_changed() { +void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { + RENDER_TIMESTAMP("Setup Rendering UV2"); + + _update_render_base_uniform_set(); + + render_pass++; + + scene_state.ubo.dual_paraboloid_side = 0; + scene_state.ubo.material_uv2_mode = true; + + _setup_environment(RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0); + + render_list.clear(); + + PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL; + _fill_render_list(p_cull_result, p_cull_count, pass_mode, true); + + _setup_view_dependant_uniform_set(RID(), RID()); + + RENDER_TIMESTAMP("Render Material"); + + render_list.sort_by_key(false); + + _fill_instances(render_list.elements, render_list.element_count, true); + + { + //regular forward for now + Vector<Color> clear; + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + clear.push_back(Color(0, 0, 0, 0)); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region); + + const int uv_offset_count = 9; + static const Vector2 uv_offsets[uv_offset_count] = { + Vector2(-1, 1), + Vector2(1, 1), + Vector2(1, -1), + Vector2(-1, -1), + Vector2(-1, 0), + Vector2(1, 0), + Vector2(0, -1), + Vector2(0, 1), + Vector2(0, 0), + + }; + + for (int i = 0; i < uv_offset_count; i++) { + Vector2 ofs = uv_offsets[i]; + ofs.x /= p_region.size.width; + ofs.y /= p_region.size.height; + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), true, ofs); //first wireframe, for pseudo conservative + } + _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), false); //second regular triangles + RD::get_singleton()->draw_list_end(); + } +} + +void RasterizerSceneHighEndRD::_base_uniforms_changed() { if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); } @@ -2559,13 +2605,13 @@ void RasterizerSceneHighEndRD::_base_uniforms_changed() { } void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { - - if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { - + if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) { if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) { RD::get_singleton()->free(render_base_uniform_set); } + lightmap_texture_array_version = storage->lightmap_array_get_version(); + Vector<RD::Uniform> uniforms; { @@ -2653,7 +2699,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } for (int i = 0; i < slot_count; i++) { - RID probe = gi_probe_get_slots()[i]; if (gi_probe_is_anisotropic()) { @@ -2681,6 +2726,27 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.binding = 10; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.lightmap_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 11; + u.type = RD::UNIFORM_TYPE_TEXTURE; + u.ids = storage->lightmap_array_get_textures(); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 12; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.ids.push_back(scene_state.lightmap_capture_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 13; u.type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2688,7 +2754,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 11; + u.binding = 14; u.type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); @@ -2696,7 +2762,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 12; + u.binding = 15; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.decal_buffer); uniforms.push_back(u); @@ -2704,14 +2770,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 13; + u.binding = 16; u.type = RD::UNIFORM_TYPE_TEXTURE; u.ids.push_back(cluster_builder.get_cluster_texture()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 14; + u.binding = 17; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(cluster_builder.get_cluster_indices_buffer()); uniforms.push_back(u); @@ -2719,7 +2785,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 15; + u.binding = 18; u.type = RD::UNIFORM_TYPE_TEXTURE; if (directional_shadow_get_texture().is_valid()) { u.ids.push_back(directional_shadow_get_texture()); @@ -2732,7 +2798,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { { RD::Uniform u; u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 16; + u.binding = 19; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2742,7 +2808,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() { } void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas) { - if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) { RD::get_singleton()->free(view_dependant_uniform_set); } @@ -2752,7 +2817,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at Vector<RD::Uniform> uniforms; { - RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID(); RD::Uniform u; u.binding = 0; @@ -2784,7 +2848,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at } void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) { - if (!rb->uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) { RD::get_singleton()->free(rb->uniform_set); } @@ -2792,7 +2855,6 @@ void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDat } void RasterizerSceneHighEndRD::_render_buffers_uniform_set_changed(RID p_render_buffers) { - RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); _render_buffers_clear_uniform_set(rb); @@ -2811,11 +2873,9 @@ RID RasterizerSceneHighEndRD::_render_buffers_get_normal_texture(RID p_render_bu } void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_buffers) { - RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers); if (rb->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) { - Vector<RD::Uniform> uniforms; { RD::Uniform u; @@ -2947,7 +3007,21 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag scene_state.gi_probe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * scene_state.max_gi_probes); defines += "\n#define MAX_GI_PROBES " + itos(scene_state.max_gi_probes) + "\n"; } + { + //lightmaps + scene_state.max_lightmaps = storage->lightmap_array_get_size(); + defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n"; + defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n"; + scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps); + scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps); + } + { + //captures + scene_state.max_lightmap_captures = 2048; + scene_state.lightmap_captures = memnew_arr(LightmapCaptureData, scene_state.max_lightmap_captures); + scene_state.lightmap_capture_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapCaptureData) * scene_state.max_lightmap_captures); + } { //decals scene_state.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(DecalData); //1mb of decals uint32_t decal_buffer_size = scene_state.max_decals * sizeof(DecalData); @@ -2955,6 +3029,10 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag scene_state.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size); } + { + defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n"; + } + Vector<String> shader_versions; shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); @@ -3125,7 +3203,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag render_pass = 0; { - scene_state.max_instances = render_list.max_elements; scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances); scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances); @@ -3145,7 +3222,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag } { - overdraw_material_shader = storage->shader_create(); storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }"); overdraw_material = storage->material_create(); @@ -3169,7 +3245,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, TRANSFORMS_UNIFORM_SET); } { - RD::SamplerState sampler; sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; @@ -3235,12 +3310,16 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { RD::get_singleton()->free(scene_state.gi_probe_buffer); RD::get_singleton()->free(scene_state.directional_light_buffer); RD::get_singleton()->free(scene_state.light_buffer); + RD::get_singleton()->free(scene_state.lightmap_buffer); + RD::get_singleton()->free(scene_state.lightmap_capture_buffer); RD::get_singleton()->free(scene_state.reflection_buffer); RD::get_singleton()->free(scene_state.decal_buffer); memdelete_arr(scene_state.instances); memdelete_arr(scene_state.gi_probes); memdelete_arr(scene_state.directional_lights); memdelete_arr(scene_state.lights); + memdelete_arr(scene_state.lightmaps); + memdelete_arr(scene_state.lightmap_captures); memdelete_arr(scene_state.reflections); memdelete_arr(scene_state.decals); } diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h index a48e2e2259..8438a4f730 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h @@ -38,7 +38,6 @@ #include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h" class RasterizerSceneHighEndRD : public RasterizerSceneRD { - enum { SCENE_UNIFORM_SET = 0, RADIANCE_UNIFORM_SET = 1, @@ -75,7 +74,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { /* Material */ struct ShaderData : public RasterizerStorageRD::ShaderData { - enum BlendMode { //used internally BLEND_MODE_MIX, BLEND_MODE_ADD, @@ -193,7 +191,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { struct PushConstant { uint32_t index; - uint32_t pad[3]; + uint32_t pad; + float bake_uv2_offset[2]; }; /* Framebuffer */ @@ -241,6 +240,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID render_base_uniform_set; RID view_dependant_uniform_set; + uint64_t lightmap_texture_array_version = 0xFFFFFFFF; + virtual void _base_uniforms_changed(); void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb); virtual void _render_buffers_uniform_set_changed(RID p_render_buffers); @@ -285,7 +286,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { }; struct DirectionalLightData { - float direction[3]; float energy; float color[3]; @@ -331,6 +331,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t pad[1]; }; + struct LightmapData { + float normal_xform[12]; + }; + struct DecalData { float xform[16]; float inv_extents[3]; @@ -349,7 +353,15 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { float normal_fade; }; + struct LightmapCaptureData { + float sh[9 * 4]; + }; + enum { + INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8, + INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9, + INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10, + INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11, INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12, INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13, INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14, @@ -366,6 +378,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap) uint32_t mask; + float lightmap_uv_scale[4]; }; struct SceneState { @@ -418,6 +431,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t roughness_limiter_enabled; float ao_color[4]; + + uint32_t material_uv2_mode; + uint32_t pad_material[3]; }; UBO ubo; @@ -434,6 +450,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { RID gi_probe_buffer; uint32_t max_gi_probe_probes_per_instance; + LightmapData *lightmaps; + uint32_t max_lightmaps; + RID lightmap_buffer; + DecalData *decals; uint32_t max_decals; RID decal_buffer; @@ -446,6 +466,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { uint32_t max_directional_lights; RID directional_light_buffer; + LightmapCaptureData *lightmap_captures; + uint32_t max_lightmap_captures; + RID lightmap_capture_buffer; + RID instance_buffer; InstanceData *instances; uint32_t max_instances; @@ -456,12 +480,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { bool used_sss = false; uint32_t current_shader_index = 0; uint32_t current_material_index = 0; + } scene_state; /* Render List */ struct RenderList { - int max_elements; struct Element { @@ -492,7 +516,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { int alpha_element_count; void clear() { - element_count = 0; alpha_element_count = 0; } @@ -500,14 +523,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { //should eventually be replaced by radix struct SortByKey { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { return A->sort_key < B->sort_key; } }; void sort_by_key(bool p_alpha) { - SortArray<Element *, SortByKey> sorter; if (p_alpha) { sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count); @@ -517,7 +538,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } struct SortByDepth { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { return A->instance->depth < B->instance->depth; } @@ -534,7 +554,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } struct SortByReverseDepthAndPriority { - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { uint32_t layer_A = uint32_t(A->priority); uint32_t layer_B = uint32_t(B->priority); @@ -557,17 +576,17 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } _FORCE_INLINE_ Element *add_element() { - - if (element_count + alpha_element_count >= max_elements) + if (element_count + alpha_element_count >= max_elements) { return nullptr; + } elements[element_count] = &base_elements[element_count]; return elements[element_count++]; } _FORCE_INLINE_ Element *add_alpha_element() { - - if (element_count + alpha_element_count >= max_elements) + if (element_count + alpha_element_count >= max_elements) { return nullptr; + } int idx = max_elements - alpha_element_count - 1; elements[idx] = &base_elements[idx]; alpha_element_count++; @@ -575,17 +594,16 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { } void init() { - element_count = 0; alpha_element_count = 0; elements = memnew_arr(Element *, max_elements); base_elements = memnew_arr(Element, max_elements); - for (int i = 0; i < max_elements; i++) + for (int i = 0; i < max_elements; i++) { elements[i] = &base_elements[i]; // assign elements + } } RenderList() { - max_elements = 0; } @@ -632,18 +650,20 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD { void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform); void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment); void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform); + void _setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform); void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth); - void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set); + void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2()); _FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index); _FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index); void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi); protected: - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color); virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake); virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); + virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region); public: virtual void set_time(double p_time, double p_step); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 8877de87ac..689552be2f 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -49,7 +49,6 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { - rd.layers.clear(); rd.radiance_base_cubemap = RID(); if (rd.downsampled_radiance_cubemap.is_valid()) { @@ -152,7 +151,6 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, } void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) { - storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { @@ -174,21 +172,16 @@ void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool } void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) { - if (p_use_arrays) { - //render directly to the layers storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x); } else { - storage->get_effects()->cubemap_roughness(rd.layers[0].views[p_base_layer - 1], rd.layers[0].views[p_base_layer], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[p_base_layer].size.x); } } void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) { - if (sky_use_cubemap_array) { - for (int i = 0; i < rd.layers.size(); i++) { for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) { for (int k = 0; k < 6; k++) { @@ -263,13 +256,49 @@ void RasterizerSceneRD::sky_set_material(RID p_sky, RID p_material) { Sky *sky = sky_owner.getornull(p_sky); ERR_FAIL_COND(!sky); sky->material = p_material; + _sky_invalidate(sky); } -void RasterizerSceneRD::_update_dirty_skys() { +Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { + Sky *sky = sky_owner.getornull(p_sky); + ERR_FAIL_COND_V(!sky, Ref<Image>()); + + _update_dirty_skys(); + + if (sky->radiance.is_valid()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; + tf.width = p_size.width; + tf.height = p_size.height; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + storage->get_effects()->copy_cubemap_to_panorama(sky->radiance, rad_tex, p_size, p_bake_irradiance ? roughness_layers : 0, sky->reflection.layers.size() > 1); + Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0); + RD::get_singleton()->free(rad_tex); + + Ref<Image> img; + img.instance(); + img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data); + for (int i = 0; i < p_size.width; i++) { + for (int j = 0; j < p_size.height; j++) { + Color c = img->get_pixel(i, j); + c.r *= p_energy; + c.g *= p_energy; + c.b *= p_energy; + img->set_pixel(i, j, c); + } + } + return img; + } + + return Ref<Image>(); +} + +void RasterizerSceneRD::_update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { - bool texture_set_dirty = false; //update sky configuration if texture is missing @@ -381,7 +410,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, ERR_FAIL_COND_V(!sky, RID()); if (sky->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->uniform_set)) { - sky->uniform_set = RID(); if (sky->radiance.is_valid()) { Vector<RD::Uniform> uniforms; @@ -401,7 +429,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, } RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) { - if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) { return p_sky->texture_uniform_sets[p_version]; } @@ -468,7 +495,6 @@ RID RasterizerSceneRD::sky_get_material(RID p_sky) const { } void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -505,7 +531,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue CameraMatrix camera; if (custom_fov) { - float near_plane = p_projection.get_z_near(); float far_plane = p_projection.get_z_far(); float aspect = p_projection.get_aspect(); @@ -554,7 +579,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue } void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -612,26 +636,22 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } if (shader_data->uses_time && time - sky->prev_time > 0.00001) { - sky->prev_time = time; sky->reflection.dirty = true; RenderingServerRaster::redraw_request(); } if (material != sky->prev_material) { - sky->prev_material = material; sky->reflection.dirty = true; } if (material->uniform_set_updated) { - material->uniform_set_updated = false; sky->reflection.dirty = true; } if (!p_position.is_equal_approx(sky->prev_position) && shader_data->uses_position) { - sky->prev_position = p_position; sky->reflection.dirty = true; } @@ -664,7 +684,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } if (light_data_dirty || sky_scene_state.light_uniform_set.is_null()) { - RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true); if (sky_scene_state.light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.light_uniform_set)) { @@ -692,7 +711,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, } void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) { - ERR_FAIL_COND(!is_environment(p_environment)); Sky *sky = sky_owner.getornull(environment_get_sky(p_environment)); @@ -724,7 +742,6 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro // Update radiance cubemap if (sky->reflection.dirty) { - static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -905,7 +922,6 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) { //update pipelines for (int i = 0; i < SKY_VERSION_MAX; i++) { - RD::PipelineDepthStencilState depth_stencil_state; depth_stencil_state.enable_depth_test = true; depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; @@ -926,11 +942,9 @@ void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringNam } void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -943,7 +957,6 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); pi.name = E->get(); p_param_list->push_back(pi); @@ -951,9 +964,7 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para } void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } @@ -1011,7 +1022,6 @@ RasterizerStorageRD::ShaderData *RasterizerSceneRD::_create_sky_shader_func() { } void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton; uniform_set_updated = true; @@ -1038,7 +1048,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, //check whether buffer changed if (p_uniform_dirty && ubo_data.size()) { - update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false); RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw()); } @@ -1057,7 +1066,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, } if (p_textures_dirty && tex_uniform_count) { - update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true); } @@ -1074,7 +1082,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Vector<RD::Uniform> uniforms; { - if (shader_data->ubo_size) { RD::Uniform u; u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; @@ -1115,7 +1122,6 @@ RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func( } RID RasterizerSceneRD::environment_create() { - return environment_owner.make_rid(Environent()); } @@ -1124,36 +1130,43 @@ void RasterizerSceneRD::environment_set_background(RID p_env, RS::EnvironmentBG ERR_FAIL_COND(!env); env->background = p_bg; } + void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky = p_sky; } + void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_custom_fov = p_scale; } + void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->sky_orientation = p_orientation; } + void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_color = p_color; } + void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->bg_energy = p_energy; } + void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->canvas_max_layer = p_max_layer; } + void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1170,56 +1183,67 @@ RS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); return env->background; } + RID RasterizerSceneRD::environment_get_sky(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RID()); return env->sky; } + float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->sky_custom_fov; } + Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Basis()); return env->sky_orientation; } + Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->bg_color; } + float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->bg_energy; } + int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->canvas_max_layer; } + Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, Color()); return env->ambient_light; } + RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); return env->ambient_source; } + float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_light_energy; } + float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, 0); return env->ambient_sky_contribution; } + RS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); @@ -1249,7 +1273,6 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa } void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->glow_enabled = p_enable; @@ -1269,7 +1292,6 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable) } void RasterizerSceneRD::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) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1289,7 +1311,6 @@ RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughn } void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); @@ -1308,7 +1329,6 @@ void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality } bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssao_enabled; @@ -1319,6 +1339,7 @@ float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const { ERR_FAIL_COND_V(!env, false); return env->ssao_ao_channel_affect; } + float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const { Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); @@ -1326,7 +1347,6 @@ float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const { } bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const { - Environent *env = environment_owner.getornull(p_env); ERR_FAIL_COND_V(!env, false); return env->ssr_enabled; @@ -1336,10 +1356,46 @@ bool RasterizerSceneRD::is_environment(RID p_env) const { return environment_owner.owns(p_env); } +Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { + Environent *env = environment_owner.getornull(p_env); + ERR_FAIL_COND_V(!env, Ref<Image>()); + + if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) { + return Ref<Image>(); //nothing to bake + } + + if (env->background == RS::ENV_BG_CLEAR_COLOR || env->background == RS::ENV_BG_COLOR) { + Color color; + if (env->background == RS::ENV_BG_CLEAR_COLOR) { + color = storage->get_default_clear_color(); + } else { + color = env->bg_color; + } + color.r *= env->bg_energy; + color.g *= env->bg_energy; + color.b *= env->bg_energy; + + Ref<Image> ret; + ret.instance(); + ret->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF); + for (int i = 0; i < p_size.width; i++) { + for (int j = 0; j < p_size.height; j++) { + ret->set_pixel(i, j, color); + } + } + return ret; + } + + if (env->background == RS::ENV_BG_SKY && env->sky.is_valid()) { + return sky_bake_panorama(env->sky, env->bg_energy, p_bake_irradiance, p_size); + } + + return Ref<Image>(); +} + //////////////////////////////////////////////////////////// RID RasterizerSceneRD::reflection_atlas_create() { - ReflectionAtlas ra; ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count"); ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size"); @@ -1348,7 +1404,6 @@ RID RasterizerSceneRD::reflection_atlas_create() { } void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { - ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas); ERR_FAIL_COND(!ra); @@ -1395,7 +1450,6 @@ void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance, } void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND(!rpi); @@ -1411,7 +1465,6 @@ void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) { } bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); @@ -1431,7 +1484,6 @@ bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) { } bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); @@ -1439,7 +1491,6 @@ bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) } bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { - ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas); ERR_FAIL_COND_V(!atlas, false); @@ -1484,7 +1535,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView()); } { - RD::TextureFormat tf; tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; tf.width = atlas->size; @@ -1540,7 +1590,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R } bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instance) { - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!rpi, false); ERR_FAIL_COND_V(!rpi->rendering, false); @@ -1618,19 +1667,18 @@ RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_ins /////////////////////////////////////////////////////////// RID RasterizerSceneRD::shadow_atlas_create() { - return shadow_atlas_owner.make_rid(ShadowAtlas()); } void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); - if (p_size == shadow_atlas->size) + if (p_size == shadow_atlas->size) { return; + } // erasing atlas if (shadow_atlas->depth.is_valid()) { @@ -1656,7 +1704,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { shadow_atlas->size = p_size; if (shadow_atlas->size) { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = shadow_atlas->size; @@ -1668,7 +1715,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { } void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_INDEX(p_quadrant, 4); @@ -1683,12 +1729,12 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p //obtain the number that will be x*x - if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) + if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) { return; + } //erase all data from quadrant for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) { - if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) { shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); LightInstance *li = light_instance_owner.getornull(shadow_atlas->quadrants[p_quadrant].shadows[i].owner); @@ -1731,9 +1777,7 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p } bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) { - for (int i = p_quadrant_count - 1; i >= 0; i--) { - int qidx = p_in_quadrants[i]; if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) { @@ -1758,10 +1802,10 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int ERR_CONTINUE(!sli); if (sli->last_scene_pass != scene_pass) { - //was just allocated, don't kill it so soon, wait a bit.. - if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) + if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) { continue; + } if (found_used_idx == -1 || sli->last_scene_pass < min_pass) { found_used_idx = j; @@ -1770,8 +1814,9 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int } } - if (found_free_idx == -1 && found_used_idx == -1) + if (found_free_idx == -1 && found_used_idx == -1) { continue; //nothing found + } if (found_free_idx == -1 && found_used_idx != -1) { found_free_idx = found_used_idx; @@ -1787,7 +1832,6 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int } bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND_V(!shadow_atlas, false); @@ -1810,13 +1854,15 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan for (int i = 0; i < 4; i++) { int q = shadow_atlas->size_order[i]; int sd = shadow_atlas->quadrants[q].subdivision; - if (sd == 0) + if (sd == 0) { continue; //unused + } int max_fit = quad_size / sd; - if (best_size != -1 && max_fit > best_size) + if (best_size != -1 && max_fit > best_size) { break; //too large + } valid_quadrants[valid_quadrant_count++] = q; best_subdiv = sd; @@ -1921,7 +1967,6 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan } void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { - p_size = nearest_power_of_2_templated(p_size); if (directional_shadow.size == p_size) { @@ -1936,7 +1981,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { } if (p_size > 0) { - RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32_SFLOAT; tf.width = p_size; @@ -1950,13 +1994,11 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) { } void RasterizerSceneRD::set_directional_shadow_count(int p_count) { - directional_shadow.light_count = p_count; directional_shadow.current_light = 0; } static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) { - int split_h = 1; int split_v = 1; @@ -1979,7 +2021,6 @@ static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p } int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { - ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0); Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0); @@ -1990,8 +2031,12 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { switch (storage->light_directional_get_shadow_mode(light_instance->light)) { case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: break; //none - case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: r.size.height /= 2; break; - case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: r.size /= 2; break; + case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: + r.size.height /= 2; + break; + case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: + r.size /= 2; + break; } return MAX(r.size.width, r.size.height); @@ -2000,18 +2045,15 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) { ////////////////////////////////////////////////// RID RasterizerSceneRD::camera_effects_create() { - return camera_effects_owner.make_rid(CameraEffects()); } void RasterizerSceneRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) { - dof_blur_quality = p_quality; dof_blur_use_jitter = p_use_jitter; } void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) { - dof_blur_bokeh_shape = p_shape; } @@ -2031,7 +2073,6 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p } void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) { - CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects); ERR_FAIL_COND(!camfx); @@ -2040,7 +2081,6 @@ void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, } RID RasterizerSceneRD::light_instance_create(RID p_light) { - RID li = light_instance_owner.make_rid(LightInstance()); LightInstance *light_instance = light_instance_owner.getornull(li); @@ -2053,7 +2093,6 @@ RID RasterizerSceneRD::light_instance_create(RID p_light) { } void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2061,7 +2100,6 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const } void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2082,7 +2120,6 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance } void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { - LightInstance *light_instance = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -2090,9 +2127,7 @@ void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) { } RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_size) { - if (!shadow_cubemaps.has(p_size)) { - ShadowCubemap sc; { RD::TextureFormat tf; @@ -2119,9 +2154,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s } RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p_size) { - if (!shadow_maps.has(p_size)) { - ShadowMap sm; { RD::TextureFormat tf; @@ -2181,7 +2214,6 @@ RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) { } void RasterizerSceneRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) { - GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -2197,7 +2229,6 @@ bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const { } void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) { - GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gi_probe); @@ -2449,7 +2480,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView()); if (gi_probe->dynamic_maps.size() == 0) { - dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView()); @@ -2557,7 +2587,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc } if (write) { - { RD::Uniform u; u.type = RD::UNIFORM_TYPE_IMAGE; @@ -2590,7 +2619,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc } if (plot) { - { RD::Uniform u; u.type = RD::UNIFORM_TYPE_IMAGE; @@ -2644,7 +2672,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc uint32_t light_count = 0; if (p_update_light_instances || p_dynamic_object_count > 0) { - light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size()); { @@ -2724,9 +2751,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); for (int pass = 0; pass < passes; pass++) { - if (p_update_light_instances) { - for (int i = 0; i < gi_probe->mipmaps.size(); i++) { if (i == 0) { RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]); @@ -2762,7 +2787,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]); for (int i = 0; i < gi_probe->mipmaps.size(); i++) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].write_uniform_set, 0); push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset; @@ -2786,7 +2810,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again if (p_dynamic_object_count && gi_probe->dynamic_maps.size()) { - Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe); int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z); @@ -2801,7 +2824,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //this could probably be better parallelized in compute.. for (int i = 0; i < p_dynamic_object_count; i++) { - InstanceBase *instance = p_dynamic_objects[i]; //not used, so clear instance->depth_layer = 0; @@ -2830,7 +2852,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //print_line("aabb: " + aabb); for (int j = 0; j < 6; j++) { - //if (j != 0 && j != 3) { // continue; //} @@ -2919,7 +2940,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc //print_line("rect: " + itos(i) + ": " + rect); for (int k = 1; k < gi_probe->dynamic_maps.size(); k++) { - // enlarge the rect if needed so all pixels fit when downscaled, // this ensures downsampling is smooth and optimal because no pixels are left behind @@ -3017,7 +3037,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - push_constant.projection[i * 4 + j] = transform.matrix[i][j]; } } @@ -3080,7 +3099,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis } const Vector<RID> &RasterizerSceneRD::gi_probe_get_slots() const { - return gi_probe_slots; } @@ -3119,7 +3137,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { int base_height = rb->height; for (uint32_t i = 0; i < mipmaps_required; i++) { - RenderBuffers::Blur::Mipmap mm; mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i); @@ -3129,7 +3146,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) { rb->blur[0].mipmaps.push_back(mm); if (i > 0) { - mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1); rb->blur[1].mipmaps.push_back(mm); @@ -3174,7 +3190,6 @@ void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) { } void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { - if (rb->texture.is_valid()) { RD::get_singleton()->free(rb->texture); rb->texture = RID(); @@ -3240,7 +3255,6 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { } void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3260,7 +3274,6 @@ void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p } void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3314,7 +3327,6 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe } void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3382,7 +3394,6 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R } void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND(!rb); @@ -3393,7 +3404,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu bool can_use_effects = rb->width >= 8 && rb->height >= 8; if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) { - if (rb->blur[0].texture.is_null()) { _allocate_blur_textures(rb); _render_buffers_uniform_set_changed(p_render_buffers); @@ -3404,7 +3414,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu } if (can_use_effects && env && env->auto_exposure) { - if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); _render_buffers_uniform_set_changed(p_render_buffers); @@ -3425,7 +3434,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu int glow_mask = 0; if (can_use_effects && env && env->glow_enabled) { - /* see that blur textures are allocated */ if (rb->blur[0].texture.is_null()) { @@ -3435,7 +3443,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { if (env->glow_levels & (1 << i)) { - if (i >= rb->blur[1].mipmaps.size()) { max_glow_level = rb->blur[1].mipmaps.size() - 1; glow_mask |= 1 << max_glow_level; @@ -3448,7 +3455,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu } for (int i = 0; i < (max_glow_level + 1); i++) { - int vp_w = rb->blur[1].mipmaps[i].width; int vp_h = rb->blur[1].mipmaps[i].height; @@ -3475,7 +3481,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu tonemap.exposure_texture = rb->luminance.current; tonemap.auto_exposure_grey = env->auto_exp_scale; } else { - tonemap.exposure_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE); } @@ -3570,7 +3575,6 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s } RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); if (!rb->blur[0].texture.is_valid()) { @@ -3587,7 +3591,6 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) { } void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) { - RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); rb->width = p_width; rb->height = p_height; @@ -3642,7 +3645,6 @@ void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_ } void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { - ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (shadows_quality != p_quality) { @@ -3683,7 +3685,6 @@ void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) { } void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) { - ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum"); if (directional_shadow_quality != p_quality) { @@ -3737,8 +3738,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data( return rb->data; } -void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { - +void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { Color clear_color; if (p_render_buffers.is_valid()) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); @@ -3748,7 +3748,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca clear_color = storage->get_default_clear_color(); } - _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); + _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_lightmap_cull_result, p_lightmap_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color); if (p_render_buffers.is_valid()) { RENDER_TIMESTAMP("Tonemap"); @@ -3759,7 +3759,6 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca } void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) { - LightInstance *light_instance = light_instance_owner.getornull(p_light); ERR_FAIL_COND(!light_instance); @@ -3801,7 +3800,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas atlas_rect.size.height = light_instance->directional_rect.size.y; if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { - atlas_rect.size.width /= 2; atlas_rect.size.height /= 2; @@ -3815,11 +3813,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { - atlas_rect.size.height /= 2; if (p_pass == 0) { - } else { atlas_rect.position.y += atlas_rect.size.height; } @@ -3872,9 +3868,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { - if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { - ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2); render_fb = cubemap->side_fb[p_pass]; @@ -3886,7 +3880,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas finalize_cubemap = p_pass == 5; } else { - light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; @@ -3902,7 +3895,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } } else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) { - light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; @@ -3943,12 +3935,10 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas } void RasterizerSceneRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) { - _render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region); } bool RasterizerSceneRD::free(RID p_rid) { - if (render_buffers_owner.owns(p_rid)) { RenderBuffers *rb = render_buffers_owner.getornull(p_rid); _free_render_buffer_data(rb); @@ -4020,7 +4010,6 @@ bool RasterizerSceneRD::free(RID p_rid) { sky_owner.free(p_rid); } else if (light_instance_owner.owns(p_rid)) { - LightInstance *light_instance = light_instance_owner.getornull(p_rid); //remove from shadow atlases.. @@ -4038,7 +4027,6 @@ bool RasterizerSceneRD::free(RID p_rid) { light_instance_owner.free(p_rid); } else if (shadow_atlas_owner.owns(p_rid)) { - shadow_atlas_set_size(p_rid, 0); shadow_atlas_owner.free(p_rid); @@ -4075,6 +4063,97 @@ float RasterizerSceneRD::screen_space_roughness_limiter_get_curve() const { return screen_space_roughness_limiter_curve; } +TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tf.width = p_image_size.width; // Always 64x64 + tf.height = p_image_size.height; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + RID albedo_alpha_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RID normal_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RID orm_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + RID emission_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + RID depth_write_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; + RID depth_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> fb_tex; + fb_tex.push_back(albedo_alpha_tex); + fb_tex.push_back(normal_tex); + fb_tex.push_back(orm_tex); + fb_tex.push_back(emission_tex); + fb_tex.push_back(depth_write_tex); + fb_tex.push_back(depth_tex); + + RID fb = RD::get_singleton()->framebuffer_create(fb_tex); + + //RID sampled_light; + + InstanceBase ins; + + ins.base_type = RSG::storage->get_base_type(p_base); + ins.base = p_base; + ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base)); + for (int i = 0; i < ins.materials.size(); i++) { + if (i < p_material_overrides.size()) { + ins.materials.write[i] = p_material_overrides[i]; + } + } + + InstanceBase *cull = &ins; + _render_uv2(&cull, 1, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height)); + + TypedArray<Image> ret; + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(albedo_alpha_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(normal_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data); + RD::get_singleton()->free(orm_tex); + ret.push_back(img); + } + + { + PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0); + Ref<Image> img; + img.instance(); + img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data); + RD::get_singleton()->free(emission_tex); + ret.push_back(img); + } + + RD::get_singleton()->free(depth_write_tex); + RD::get_singleton()->free(depth_tex); + + return ret; +} + RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr; RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { @@ -4089,7 +4168,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); { - //kinda complicated to compute the amount of slots, we try to use as many as we can gi_probe_max_lights = 32; @@ -4144,7 +4222,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { } { - String defines; if (gi_probe_use_anisotropy) { defines += "\n#define USE_ANISOTROPY\n"; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index a511838e16..781dbd50cc 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h @@ -52,7 +52,6 @@ protected: // Skys need less info from Directional Lights than the normal shaders struct SkyDirectionalLightData { - float direction[3]; float energy; float color[3]; @@ -62,7 +61,6 @@ protected: }; struct SkySceneState { - SkyDirectionalLightData *directional_lights; SkyDirectionalLightData *last_frame_directional_lights; uint32_t max_directional_lights; @@ -74,15 +72,15 @@ protected: } sky_scene_state; struct RenderBufferData { - virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0; virtual ~RenderBufferData() {} }; virtual RenderBufferData *_create_render_buffer_data() = 0; - virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0; + virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0; virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0; virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); @@ -111,7 +109,6 @@ private: RasterizerStorageRD *storage; struct ReflectionData { - struct Layer { struct Mipmap { RID framebuffers[6]; @@ -286,7 +283,6 @@ private: /* REFLECTION ATLAS */ struct ReflectionAtlas { - int count = 0; int size = 0; @@ -308,7 +304,6 @@ private: /* REFLECTION PROBE INSTANCE */ struct ReflectionProbeInstance { - RID probe; int atlas_index = -1; RID atlas; @@ -330,7 +325,6 @@ private: /* REFLECTION PROBE INSTANCE */ struct DecalInstance { - RID decal; Transform transform; }; @@ -340,7 +334,6 @@ private: /* GIPROBE INSTANCE */ struct GIProbeLight { - uint32_t type; float energy; float radius; @@ -357,7 +350,6 @@ private: }; struct GIProbePushConstant { - int32_t limits[3]; uint32_t stack_size; @@ -373,7 +365,6 @@ private: }; struct GIProbeDynamicPushConstant { - int32_t limits[3]; uint32_t light_count; int32_t x_dir[3]; @@ -395,7 +386,6 @@ private: }; struct GIProbeInstance { - RID probe; RID texture; RID anisotropy[2]; //only if anisotropy is used @@ -495,7 +485,6 @@ private: /* SHADOW ATLAS */ struct ShadowAtlas { - enum { QUADRANT_SHIFT = 27, SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1, @@ -503,7 +492,6 @@ private: }; struct Quadrant { - uint32_t subdivision; struct Shadow { @@ -567,7 +555,6 @@ private: /* SHADOW CUBEMAPS */ struct ShadowCubemap { - RID cubemap; RID side_fb[6]; }; @@ -588,9 +575,7 @@ private: /* LIGHT INSTANCE */ struct LightInstance { - struct ShadowTransform { - CameraMatrix camera; Transform transform; float farplane; @@ -637,7 +622,6 @@ private: /* ENVIRONMENT */ struct Environent { - // BG RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; RID sky; @@ -710,7 +694,6 @@ private: /* CAMERA EFFECTS */ struct CameraEffects { - bool dof_blur_far_enabled = false; float dof_blur_far_distance = 10; float dof_blur_far_transition = 5; @@ -737,7 +720,6 @@ private: /* RENDER BUFFERS */ struct RenderBuffers { - RenderBufferData *data = nullptr; int width = 0, height = 0; RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; @@ -766,7 +748,6 @@ private: Blur blur[2]; //the second one starts from the first mipmap struct Luminance { - Vector<RID> reduce; RID current; } luminance; @@ -843,6 +824,7 @@ public: void sky_set_radiance_size(RID p_sky, int p_radiance_size); void sky_set_mode(RID p_sky, RS::SkyMode p_mode); void sky_set_material(RID p_sky, RID p_material); + Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size); RID sky_get_radiance_texture_rd(RID p_sky) const; RID sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const; @@ -900,6 +882,8 @@ public: 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) {} void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {} + virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size); + virtual RID camera_effects_create(); virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter); @@ -924,7 +908,6 @@ public: } _FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas); LightInstance *li = light_instance_owner.getornull(p_light_instance); uint32_t key = shadow_atlas->shadow_owners[li->self]; @@ -951,13 +934,11 @@ public: } _FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].camera; } _FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) { - #ifdef DEBUG_ENABLED LightInstance *li = light_instance_owner.getornull(p_light_instance); ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0); @@ -980,46 +961,38 @@ public: _FORCE_INLINE_ Transform light_instance_get_shadow_transform(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].transform; } _FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].bias_scale; } _FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].farplane; } _FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].range_begin; } _FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].uv_scale; } _FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].atlas_rect; } _FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].split; } _FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) { - LightInstance *li = light_instance_owner.getornull(p_light_instance); return li->shadow_transform[p_index].shadow_texel_size; } @@ -1194,7 +1167,7 @@ public: RID render_buffers_get_ao_texture(RID p_render_buffers); RID render_buffers_get_back_buffer_texture(RID p_render_buffers); - void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); + void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass); void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count); @@ -1235,6 +1208,8 @@ public: int get_roughness_layers() const; bool is_using_radiance_cubemap_array() const; + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + virtual bool free(RID p_rid); virtual void update(); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index 97ef604dd2..a5151d1ff8 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -36,7 +36,6 @@ #include "servers/rendering/shader_language.h" Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) { - Ref<Image> image = p_image->duplicate(); switch (p_image->get_format()) { @@ -131,7 +130,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima image->convert(Image::FORMAT_RGBAF); } - r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; @@ -171,7 +169,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima image->convert(Image::FORMAT_RGBAH); } - r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R; r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G; r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B; @@ -405,7 +402,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima } break; //etc2 case Image::FORMAT_ETC2_R11S: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK; } else { @@ -483,7 +479,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; } break; case Image::FORMAT_ETC2_RGB8A1: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK; r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK; @@ -500,7 +495,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A; } break; case Image::FORMAT_ETC2_RA_AS_RG: { - if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) { r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK; @@ -611,11 +605,116 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) { } RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) { + ERR_FAIL_COND_V(p_layers.size() == 0, RID()); - return RID(); + ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID()); + ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID()); + + TextureToRDFormat ret_format; + Vector<Ref<Image>> images; + { + int valid_width = 0; + int valid_height = 0; + bool valid_mipmaps = false; + Image::Format valid_format = Image::FORMAT_MAX; + + for (int i = 0; i < p_layers.size(); i++) { + ERR_FAIL_COND_V(p_layers[i]->empty(), RID()); + + if (i == 0) { + valid_width = p_layers[i]->get_width(); + valid_height = p_layers[i]->get_height(); + valid_format = p_layers[i]->get_format(); + valid_mipmaps = p_layers[i]->has_mipmaps(); + } else { + ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID()); + ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID()); + ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID()); + ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID()); + } + + images.push_back(_validate_texture_format(p_layers[i], ret_format)); + } + } + + Texture texture; + + texture.type = Texture::TYPE_LAYERED; + texture.layered_type = p_layered_type; + + texture.width = p_layers[0]->get_width(); + texture.height = p_layers[0]->get_height(); + texture.layers = p_layers.size(); + texture.mipmaps = p_layers[0]->get_mipmap_count() + 1; + texture.depth = 1; + texture.format = p_layers[0]->get_format(); + texture.validated_format = images[0]->get_format(); + + switch (p_layered_type) { + case RS::TEXTURE_LAYERED_2D_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE; + } break; + case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: { + texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY; + } break; + } + + texture.rd_format = ret_format.format; + texture.rd_format_srgb = ret_format.format_srgb; + + RD::TextureFormat rd_format; + RD::TextureView rd_view; + { //attempt register + rd_format.format = texture.rd_format; + rd_format.width = texture.width; + rd_format.height = texture.height; + rd_format.depth = 1; + rd_format.array_layers = texture.layers; + rd_format.mipmaps = texture.mipmaps; + rd_format.type = texture.rd_type; + rd_format.samples = RD::TEXTURE_SAMPLES_1; + rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_format.shareable_formats.push_back(texture.rd_format); + rd_format.shareable_formats.push_back(texture.rd_format_srgb); + } + } + { + rd_view.swizzle_r = ret_format.swizzle_r; + rd_view.swizzle_g = ret_format.swizzle_g; + rd_view.swizzle_b = ret_format.swizzle_b; + rd_view.swizzle_a = ret_format.swizzle_a; + } + Vector<Vector<uint8_t>> data_slices; + for (int i = 0; i < images.size(); i++) { + Vector<uint8_t> data = images[i]->get_data(); //use image data + data_slices.push_back(data); + } + texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices); + ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID()); + if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) { + rd_view.format_override = texture.rd_format_srgb; + texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture); + if (texture.rd_texture_srgb.is_null()) { + RD::get_singleton()->free(texture.rd_texture); + ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID()); + } + } + + //used for 2D, overridable + texture.width_2d = texture.width; + texture.height_2d = texture.height; + texture.is_render_target = false; + texture.rd_view = rd_view; + texture.is_proxy = false; + + return texture_owner.make_rid(texture); } -RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { +RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) { return RID(); } @@ -643,7 +742,6 @@ RID RasterizerStorageRD::texture_proxy_create(RID p_base) { } void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) { - ERR_FAIL_COND(p_image.is_null() || p_image->empty()); Texture *tex = texture_owner.getornull(p_texture); @@ -668,14 +766,15 @@ void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_ void RasterizerStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, true); } + void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) { _texture_2d_update(p_texture, p_image, p_layer, false); } + void RasterizerStorageRD::texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) { } void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(!tex->is_proxy); @@ -716,7 +815,6 @@ void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) { //these two APIs can be used together or in combination with the others. RID RasterizerStorageRD::texture_2d_placeholder_create() { - //this could be better optimized to reuse an existing image , done this way //for now to get it working Ref<Image> image; @@ -731,17 +829,38 @@ RID RasterizerStorageRD::texture_2d_placeholder_create() { return texture_2d_create(image); } -RID RasterizerStorageRD::texture_2d_layered_placeholder_create() { - return RID(); +RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) { + //this could be better optimized to reuse an existing image , done this way + //for now to get it working + Ref<Image> image; + image.instance(); + image->create(4, 4, false, Image::FORMAT_RGBA8); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + image->set_pixel(i, j, Color(1, 0, 1, 1)); + } + } + + Vector<Ref<Image>> images; + if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) { + images.push_back(image); + } else { + //cube + for (int i = 0; i < 6; i++) { + images.push_back(image); + } + } + + return texture_2d_layered_create(images, p_layered_type); } -RID RasterizerStorageRD::texture_3d_placeholder_create() { +RID RasterizerStorageRD::texture_3d_placeholder_create() { return RID(); } Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND_V(!tex, Ref<Image>()); @@ -768,17 +887,16 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const { return image; } -Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { +Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const { return Ref<Image>(); } -Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { +Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const { return Ref<Image>(); } void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { - Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); ERR_FAIL_COND(tex->proxy_to.is_valid()); //cant replace proxy @@ -817,6 +935,7 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) { decal_atlas.dirty = true; //mark it dirty since it was most likely modified } } + void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); @@ -830,6 +949,7 @@ void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path) ERR_FAIL_COND(!tex); tex->path = p_path; } + String RasterizerStorageRD::texture_get_path(RID p_texture) const { return String(); } @@ -840,23 +960,27 @@ void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::Text tex->detect_3d_callback_ud = p_userdata; tex->detect_3d_callback = p_callback; } + void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_normal_callback_ud = p_userdata; tex->detect_normal_callback = p_callback; } + void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) { Texture *tex = texture_owner.getornull(p_texture); ERR_FAIL_COND(!tex); tex->detect_roughness_callback_ud = p_userdata; tex->detect_roughness_callback = p_callback; } + void RasterizerStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) { } void RasterizerStorageRD::texture_set_proxy(RID p_proxy, RID p_base) { } + void RasterizerStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) { } @@ -867,7 +991,6 @@ Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) { /* SHADER API */ RID RasterizerStorageRD::shader_create() { - Shader shader; shader.data = nullptr; shader.type = SHADER_TYPE_MAX; @@ -883,16 +1006,17 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { String mode_string = ShaderLanguage::get_shader_type(p_code); ShaderType new_type; - if (mode_string == "canvas_item") + if (mode_string == "canvas_item") { new_type = SHADER_TYPE_2D; - else if (mode_string == "particles") + } else if (mode_string == "particles") { new_type = SHADER_TYPE_PARTICLES; - else if (mode_string == "spatial") + } else if (mode_string == "spatial") { new_type = SHADER_TYPE_3D; - else if (mode_string == "sky") + } else if (mode_string == "sky") { new_type = SHADER_TYPE_SKY; - else + } else { new_type = SHADER_TYPE_MAX; + } if (new_type != shader->type) { if (shader->data) { @@ -901,7 +1025,6 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) { } for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); material->shader_type = new_type; if (material->data) { @@ -946,8 +1069,8 @@ String RasterizerStorageRD::shader_get_code(RID p_shader) const { ERR_FAIL_COND_V(!shader, String()); return shader->code; } -void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { +void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); if (shader->data) { @@ -956,7 +1079,6 @@ void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> } void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) { - Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND(!shader); @@ -981,6 +1103,7 @@ RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const St return RID(); } + Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const { Shader *shader = shader_owner.getornull(p_shader); ERR_FAIL_COND_V(!shader, Variant()); @@ -989,6 +1112,7 @@ Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const String } return Variant(); } + void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) { ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX); shader_data_request_func[p_shader_type] = p_function; @@ -997,7 +1121,6 @@ void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_t /* COMMON MATERIAL API */ RID RasterizerStorageRD::material_create() { - Material material; material.data = nullptr; material.shader = nullptr; @@ -1028,7 +1151,6 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif } void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1070,7 +1192,6 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) { } void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1113,6 +1234,7 @@ void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_mate material->instance_dependency.instance_notify_changed(false, true); } + void RasterizerStorageRD::material_set_render_priority(RID p_material, int priority) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); @@ -1134,6 +1256,7 @@ bool RasterizerStorageRD::material_is_animated(RID p_material) { } return false; //by default nothing is animated } + bool RasterizerStorageRD::material_casts_shadows(RID p_material) { Material *material = material_owner.getornull(p_material); ERR_FAIL_COND_V(!material, true); @@ -1148,7 +1271,6 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) { } void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) { - Material *material = material_owner.getornull(p_material); ERR_FAIL_COND(!material); if (material->shader && material->shader->data) { @@ -1177,14 +1299,12 @@ void RasterizerStorageRD::material_set_data_request_function(ShaderType p_shader _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant &value, uint8_t *data, bool p_linear_color) { switch (type) { case ShaderLanguage::TYPE_BOOL: { - bool v = value; uint32_t *gui = (uint32_t *)data; *gui = v ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC2: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = v & 1 ? 1 : 0; @@ -1192,7 +1312,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_BVEC3: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = (v & 1) ? 1 : 0; @@ -1201,7 +1320,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_BVEC4: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = (v & 1) ? 1 : 0; @@ -1211,14 +1329,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_INT: { - int v = value; int32_t *gui = (int32_t *)data; gui[0] = v; } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1226,15 +1342,15 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 2; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1242,14 +1358,14 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 3; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; int s = iv.size(); int32_t *gui = (int32_t *)data; @@ -1257,21 +1373,20 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 4; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_UINT: { - int v = value; uint32_t *gui = (uint32_t *)data; gui[0] = v; } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; int s = iv.size(); uint32_t *gui = (uint32_t *)data; @@ -1279,10 +1394,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 2; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_UVEC3: { @@ -1293,10 +1409,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 3; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; @@ -1308,10 +1425,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy const int *r = iv.ptr(); for (int i = 0; i < 4; i++) { - if (i < s) + if (i < s) { gui[i] = r[i]; - else + } else { gui[i] = 0; + } } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -1336,7 +1454,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } break; case ShaderLanguage::TYPE_VEC4: { - float *gui = (float *)data; if (value.get_type() == Variant::COLOR) { @@ -1388,7 +1505,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[7] = 0; } break; case ShaderLanguage::TYPE_MAT3: { - Basis v = value; float *gui = (float *)data; @@ -1406,7 +1522,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[11] = 0; } break; case ShaderLanguage::TYPE_MAT4: { - Transform v = value; float *gui = (float *)data; @@ -1433,22 +1548,18 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::ConstantNode::Value> &value, uint8_t *data) { - switch (type) { case ShaderLanguage::TYPE_BOOL: { - uint32_t *gui = (uint32_t *)data; *gui = value[0].boolean ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC2: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; } break; case ShaderLanguage::TYPE_BVEC3: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; @@ -1456,7 +1567,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_BVEC4: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].boolean ? 1 : 0; gui[1] = value[1].boolean ? 1 : 0; @@ -1465,13 +1575,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_INT: { - int32_t *gui = (int32_t *)data; gui[0] = value[0].sint; } break; case ShaderLanguage::TYPE_IVEC2: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 2; i++) { @@ -1480,7 +1588,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_IVEC3: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 3; i++) { @@ -1489,7 +1596,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_IVEC4: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 4; i++) { @@ -1498,13 +1604,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_UINT: { - uint32_t *gui = (uint32_t *)data; gui[0] = value[0].uint; } break; case ShaderLanguage::TYPE_UVEC2: { - int32_t *gui = (int32_t *)data; for (int i = 0; i < 2; i++) { @@ -1527,13 +1631,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } } break; case ShaderLanguage::TYPE_FLOAT: { - float *gui = (float *)data; gui[0] = value[0].real; } break; case ShaderLanguage::TYPE_VEC2: { - float *gui = (float *)data; for (int i = 0; i < 2; i++) { @@ -1542,7 +1644,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_VEC3: { - float *gui = (float *)data; for (int i = 0; i < 3; i++) { @@ -1551,7 +1652,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_VEC4: { - float *gui = (float *)data; for (int i = 0; i < 4; i++) { @@ -1572,7 +1672,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, gui[7] = 0; } break; case ShaderLanguage::TYPE_MAT3: { - float *gui = (float *)data; gui[0] = value[0].real; @@ -1589,7 +1688,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, gui[11] = 0; } break; case ShaderLanguage::TYPE_MAT4: { - float *gui = (float *)data; for (int i = 0; i < 16; i++) { @@ -1602,9 +1700,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, uint8_t *data) { - switch (type) { - case ShaderLanguage::TYPE_BOOL: case ShaderLanguage::TYPE_INT: case ShaderLanguage::TYPE_UINT: @@ -1625,15 +1721,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, case ShaderLanguage::TYPE_IVEC4: case ShaderLanguage::TYPE_UVEC4: case ShaderLanguage::TYPE_VEC4: { - zeromem(data, 16); } break; case ShaderLanguage::TYPE_MAT2: { - zeromem(data, 32); } break; case ShaderLanguage::TYPE_MAT3: { - zeromem(data, 48); } break; case ShaderLanguage::TYPE_MAT4: { @@ -1646,13 +1739,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, } void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { - bool uses_global_buffer = false; for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) { - - if (E->get().order < 0) + if (E->get().order < 0) { continue; // texture, does not go here + } if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; //instance uniforms don't appear in the bufferr @@ -1740,7 +1832,6 @@ RasterizerStorageRD::MaterialData::~MaterialData() { } void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { - RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton; #ifdef TOOLS_ENABLED Texture *roughness_detect_texture = nullptr; @@ -1752,13 +1843,11 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va global_textures_pass++; for (int i = 0; i < p_texture_uniforms.size(); i++) { - const StringName &uniform_name = p_texture_uniforms[i].name; RID texture; if (p_texture_uniforms[i].global) { - RasterizerStorageRD *rs = base_singleton; uses_global_textures = true; @@ -1769,7 +1858,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { - Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name); if (!E) { E = used_global_textures.insert(uniform_name, global_textures_pass); @@ -1786,7 +1874,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va } } else { if (!texture.is_valid()) { - const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name); if (V) { texture = V->get(); @@ -1796,7 +1883,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va if (!texture.is_valid()) { const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name); if (W) { - texture = W->get(); } } @@ -1827,7 +1913,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va Texture *tex = singleton->texture_owner.getornull(texture); if (tex) { - rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture; #ifdef TOOLS_ENABLED if (tex->detect_3d_callback && p_use_linear_color) { @@ -1919,16 +2004,15 @@ void RasterizerStorageRD::_update_queued_materials() { } material_update_list = nullptr; } + /* MESH API */ RID RasterizerStorageRD::mesh_create() { - return mesh_owner.make_rid(Mesh()); } /// Returns stride void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); @@ -1939,17 +2023,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ #ifdef DEBUG_ENABLED //do a validation, to catch errors first { - uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - if ((p_surface.format & (1 << i))) { - switch (i) { - case RS::ARRAY_VERTEX: { - if (p_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) { stride += sizeof(float) * 2; } else { @@ -1958,7 +2037,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_NORMAL: { - if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) { stride += sizeof(int8_t) * 4; } else { @@ -1967,7 +2045,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TANGENT: { - if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) { stride += sizeof(int8_t) * 4; } else { @@ -1976,7 +2053,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_COLOR: { - if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) { stride += sizeof(int8_t) * 4; } else { @@ -1985,7 +2061,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TEX_UV: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) { stride += sizeof(int16_t) * 2; } else { @@ -1994,7 +2069,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ } break; case RS::ARRAY_TEX_UV2: { - if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) { stride += sizeof(int16_t) * 2; } else { @@ -2039,7 +2113,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->lod_count = p_surface.lods.size(); for (int i = 0; i < p_surface.lods.size(); i++) { - uint32_t indices = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4); s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data); s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices); @@ -2052,7 +2125,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_ s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. for (int i = 0; i < p_surface.blend_shapes.size(); i++) { - if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) { memdelete(s); ERR_FAIL_COND(p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()); @@ -2097,6 +2169,7 @@ void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMo mesh->blend_shape_mode = p_mode; } + RS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED); @@ -2123,6 +2196,7 @@ void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, R mesh->instance_dependency.instance_notify_changed(false, true); mesh->material_cache.clear(); } + RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RID()); @@ -2132,7 +2206,6 @@ RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) co } RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, RS::SurfaceData()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData()); @@ -2178,6 +2251,7 @@ void RasterizerStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; } + AABB RasterizerStorageRD::mesh_get_custom_aabb(RID p_mesh) const { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND_V(!mesh, AABB()); @@ -2201,10 +2275,8 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { AABB aabb; for (uint32_t i = 0; i < mesh->surface_count; i++) { - AABB laabb; if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) { - int bs = mesh->surfaces[i]->bone_aabbs.size(); const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr(); @@ -2216,9 +2288,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { if (skeleton->use_2d) { for (int j = 0; j < bs; j++) { - - if (skbones[0].size == Vector3()) + if (skbones[0].size == Vector3()) { continue; //bone is unused + } const float *dataptr = baseptr + j * 8; @@ -2243,9 +2315,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } } else { for (int j = 0; j < bs; j++) { - - if (skbones[0].size == Vector3()) + if (skbones[0].size == Vector3()) { continue; //bone is unused + } const float *dataptr = baseptr + j * 12; @@ -2278,7 +2350,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { laabb = mesh->surfaces[i]->aabb; } } else { - laabb = mesh->surfaces[i]->aabb; } @@ -2293,7 +2364,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) { } void RasterizerStorageRD::mesh_clear(RID p_mesh) { - Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); for (uint32_t i = 0; i < mesh->surface_count; i++) { @@ -2341,14 +2411,13 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su Mesh::Surface::Version &v = s->versions[version]; - Vector<RD::VertexDescription> attributes; + Vector<RD::VertexAttribute> attributes; Vector<RID> buffers; uint32_t stride = 0; for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) { - - RD::VertexDescription vd; + RD::VertexAttribute vd; RID buffer; vd.location = i; @@ -2356,9 +2425,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su // Not supplied by surface, use default value buffer = mesh_default_rd_buffers[i]; switch (i) { - case RS::ARRAY_VERTEX: { - vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; } break; @@ -2366,25 +2433,20 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT; } break; case RS::ARRAY_TANGENT: { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; } break; case RS::ARRAY_COLOR: { - vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; } break; case RS::ARRAY_TEX_UV: { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; } break; case RS::ARRAY_TEX_UV2: { - vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; } break; case RS::ARRAY_BONES: { - //assumed weights too vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT; } break; @@ -2397,9 +2459,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su buffer = s->vertex_buffer; switch (i) { - case RS::ARRAY_VERTEX: { - if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) { vd.format = RD::DATA_FORMAT_R32G32_SFLOAT; stride += sizeof(float) * 2; @@ -2410,7 +2470,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_NORMAL: { - if (s->format & RS::ARRAY_COMPRESS_NORMAL) { vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; stride += sizeof(int8_t) * 4; @@ -2421,7 +2480,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TANGENT: { - if (s->format & RS::ARRAY_COMPRESS_TANGENT) { vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM; stride += sizeof(int8_t) * 4; @@ -2432,7 +2490,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_COLOR: { - if (s->format & RS::ARRAY_COMPRESS_COLOR) { vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; stride += sizeof(int8_t) * 4; @@ -2443,7 +2500,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TEX_UV: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV) { vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; stride += sizeof(int16_t) * 2; @@ -2454,7 +2510,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su } break; case RS::ARRAY_TEX_UV2: { - if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) { vd.format = RD::DATA_FORMAT_R16G16_SFLOAT; stride += sizeof(int16_t) * 2; @@ -2499,12 +2554,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su ////////////////// MULTIMESH RID RasterizerStorageRD::multimesh_create() { - return multimesh_owner.make_rid(MultiMesh()); } void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -2540,7 +2593,6 @@ void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, R multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances); if (multimesh->instances) { - multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4); } } @@ -2595,7 +2647,6 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { if (multimesh->buffer_set) { Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer); { - const uint8_t *r = buffer.ptr(); copymem(w, r, buffer.size()); } @@ -2606,13 +2657,12 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const { uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count); for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) { - multimesh->data_cache_dirty_regions[i] = 0; + multimesh->data_cache_dirty_regions[i] = false; } multimesh->data_cache_used_dirty_regions = 0; } void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) { - uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE; #ifdef DEBUG_ENABLED uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -2658,7 +2708,6 @@ void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p } void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) { - ERR_FAIL_COND(multimesh->mesh.is_null()); AABB aabb; AABB mesh_aabb = mesh_get_aabb(multimesh->mesh); @@ -2667,7 +2716,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const Transform t; if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) { - t.basis.elements[0][0] = data[0]; t.basis.elements[0][1] = data[1]; t.basis.elements[0][2] = data[2]; @@ -2682,7 +2730,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const t.origin.z = data[11]; } else { - t.basis.elements[0].x = data[0]; t.basis.elements[1].x = data[1]; t.origin.x = data[3]; @@ -2703,7 +2750,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const } void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2734,7 +2780,6 @@ void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int } void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2759,8 +2804,8 @@ void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, i _multimesh_mark_dirty(multimesh, p_index, true); } -void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { +void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_INDEX(p_index, multimesh->instances); @@ -2781,6 +2826,7 @@ void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_in _multimesh_mark_dirty(multimesh, p_index, false); } + void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); @@ -2804,7 +2850,6 @@ void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, in } RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, RID()); @@ -2812,7 +2857,6 @@ RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const { } Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform()); @@ -2842,8 +2886,8 @@ Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, return t; } -Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { +Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Transform2D()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D()); @@ -2867,8 +2911,8 @@ Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multi return t; } -Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { +Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -2890,8 +2934,8 @@ Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_i return c; } -Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { +Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, Color()); ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color()); @@ -2971,7 +3015,6 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const { } void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) { - MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances); @@ -2986,6 +3029,7 @@ void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p multimesh->visible_instances = p_visible; } + int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND_V(!multimesh, 0); @@ -3002,9 +3046,7 @@ AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const { } void RasterizerStorageRD::_update_dirty_multimeshes() { - while (multimesh_dirty_list) { - MultiMesh *multimesh = multimesh_dirty_list; if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists @@ -3013,7 +3055,6 @@ void RasterizerStorageRD::_update_dirty_multimeshes() { uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; if (multimesh->data_cache_used_dirty_regions) { - uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; uint32_t visible_region_count = (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1; @@ -3062,12 +3103,10 @@ void RasterizerStorageRD::_update_dirty_multimeshes() { /* SKELETON API */ RID RasterizerStorageRD::skeleton_create() { - return skeleton_owner.make_rid(Skeleton()); } void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { - if (!skeleton->dirty) { skeleton->dirty = true; skeleton->dirty_list = skeleton_dirty_list; @@ -3076,13 +3115,13 @@ void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) { } void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); ERR_FAIL_COND(p_bones < 0); - if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) + if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) { return; + } skeleton->size = p_bones; skeleton->use_2d = p_2d_skeleton; @@ -3095,7 +3134,6 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_ } if (skeleton->size) { - skeleton->data.resize(skeleton->size * (skeleton->use_2d ? 8 : 12)); skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float)); zeromem(skeleton->data.ptrw(), skeleton->data.size() * sizeof(float)); @@ -3103,8 +3141,8 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_ _skeleton_make_dirty(skeleton); } } -int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { +int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, 0); @@ -3112,7 +3150,6 @@ int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const { } void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -3138,7 +3175,6 @@ void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone } Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform()); @@ -3164,8 +3200,8 @@ Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p return t; } -void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { +void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -3185,8 +3221,8 @@ void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_b _skeleton_make_dirty(skeleton); } -Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { +Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const { Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND_V(!skeleton, Transform2D()); @@ -3207,7 +3243,6 @@ Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, } void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton->use_2d); @@ -3216,13 +3251,10 @@ void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const T } void RasterizerStorageRD::_update_dirty_skeletons() { - while (skeleton_dirty_list) { - Skeleton *skeleton = skeleton_dirty_list; if (skeleton->size) { - RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr(), false); } @@ -3240,7 +3272,6 @@ void RasterizerStorageRD::_update_dirty_skeletons() { /* LIGHT */ RID RasterizerStorageRD::light_create(RS::LightType p_type) { - Light light; light.type = p_type; @@ -3264,14 +3295,13 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) { } void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->color = p_color; } -void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { +void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX); @@ -3286,7 +3316,6 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS: case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE: case RS::LIGHT_PARAM_SHADOW_BIAS: { - light->version++; light->instance_dependency.instance_notify_changed(true, false); } break; @@ -3296,8 +3325,8 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f light->param[p_param] = p_value; } -void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { +void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow = p_enabled; @@ -3307,14 +3336,12 @@ void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) { } void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->shadow_color = p_color; } void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3334,14 +3361,13 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { } void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); light->negative = p_enable; } -void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { +void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3352,7 +3378,6 @@ void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { } void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3371,8 +3396,8 @@ void RasterizerStorageRD::light_set_use_gi(RID p_light, bool p_enabled) { light->version++; light->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { +void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3383,7 +3408,6 @@ void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniS } RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE); @@ -3391,7 +3415,6 @@ RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_li } void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3401,7 +3424,6 @@ void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Lig } void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3411,7 +3433,6 @@ void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p } bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, false); @@ -3419,7 +3440,6 @@ bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const } RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL); @@ -3427,7 +3447,6 @@ RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow } void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) { - Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); @@ -3435,7 +3454,6 @@ void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_li } RS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE); @@ -3450,7 +3468,6 @@ bool RasterizerStorageRD::light_get_use_gi(RID p_light) { } uint64_t RasterizerStorageRD::light_get_version(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -3458,25 +3475,20 @@ uint64_t RasterizerStorageRD::light_get_version(RID p_light) const { } AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, AABB()); switch (light->type) { - case RS::LIGHT_SPOT: { - float len = light->param[RS::LIGHT_PARAM_RANGE]; float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); }; case RS::LIGHT_OMNI: { - float r = light->param[RS::LIGHT_PARAM_RANGE]; return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2); }; case RS::LIGHT_DIRECTIONAL: { - return AABB(); }; } @@ -3487,12 +3499,10 @@ AABB RasterizerStorageRD::light_get_aabb(RID p_light) const { /* REFLECTION PROBE */ RID RasterizerStorageRD::reflection_probe_create() { - return reflection_probe_owner.make_rid(ReflectionProbe()); } void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3501,7 +3511,6 @@ void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Refl } void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3509,7 +3518,6 @@ void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_in } void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3517,7 +3525,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, con } void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3525,7 +3532,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_pro } void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3533,7 +3539,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contributi } void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3541,16 +3546,16 @@ void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { +void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->extents = p_extents; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { +void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3559,15 +3564,14 @@ void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const } void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->interior = p_enable; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { +void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3575,15 +3579,14 @@ void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe } void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); reflection_probe->enable_shadows = p_enable; reflection_probe->instance_dependency.instance_notify_changed(true, false); } -void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { +void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) { ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); @@ -3592,7 +3595,6 @@ void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p } void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) { - ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND(!reflection_probe); ERR_FAIL_COND(p_resolution < 32); @@ -3610,8 +3612,8 @@ AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const { return aabb; } -RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const { +RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS); @@ -3619,7 +3621,6 @@ RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_m } uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3627,14 +3628,13 @@ uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const } Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); return reflection_probe->extents; } -Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { +Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Vector3()); @@ -3642,7 +3642,6 @@ Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) con } bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); @@ -3650,7 +3649,6 @@ bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const { } float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3658,7 +3656,6 @@ float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) } int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3666,21 +3663,20 @@ int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const { } float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->intensity; } -bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const { +bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); return reflection_probe->interior; } -bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const { +bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, false); @@ -3688,21 +3684,20 @@ bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const } Color RasterizerStorageRD::reflection_probe_get_interior_ambient(RID p_probe) const { - const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, Color()); return reflection_probe->interior_ambient; } -float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const { +float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); return reflection_probe->interior_ambient_energy; } -float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const { +float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!reflection_probe, 0); @@ -3719,6 +3714,7 @@ void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extent decal->extents = p_extents; decal->instance_dependency.instance_notify_changed(true, false); } + void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3742,6 +3738,7 @@ void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type decal->instance_dependency.instance_notify_changed(false, true); } + void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3759,6 +3756,7 @@ void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulat ERR_FAIL_COND(!decal); decal->modulate = p_modulate; } + void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); @@ -3767,7 +3765,6 @@ void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { } void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->distance_fade = p_enabled; @@ -3776,7 +3773,6 @@ void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, f } void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->upper_fade = p_above; @@ -3784,7 +3780,6 @@ void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_bel } void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) { - Decal *decal = decal_owner.getornull(p_decal); ERR_FAIL_COND(!decal); decal->normal_fade = p_fade; @@ -3798,7 +3793,6 @@ AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const { } RID RasterizerStorageRD::gi_probe_create() { - return gi_probe_owner.make_rid(GIProbe()); } @@ -3940,6 +3934,7 @@ Vector3i RasterizerStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const { ERR_FAIL_COND_V(!gi_probe, Vector3i()); return gi_probe->octree_size; } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3949,6 +3944,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) c } return Vector<uint8_t>(); } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3958,6 +3954,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) con } return Vector<uint8_t>(); } + Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>()); @@ -3967,12 +3964,14 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) } return Vector<uint8_t>(); } + Vector<int> RasterizerStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Vector<int>()); return gi_probe->level_counts; } + Transform RasterizerStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, Transform()); @@ -3987,6 +3986,7 @@ void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_ran gi_probe->dynamic_range = p_range; gi_probe->version++; } + float RasterizerStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4001,6 +4001,7 @@ void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range gi_probe->propagation = p_range; gi_probe->version++; } + float RasterizerStorageRD::gi_probe_get_propagation(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4013,6 +4014,7 @@ void RasterizerStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) { gi_probe->energy = p_energy; } + float RasterizerStorageRD::gi_probe_get_energy(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4025,6 +4027,7 @@ void RasterizerStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) { gi_probe->ao = p_ao; } + float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4032,7 +4035,6 @@ float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const { } void RasterizerStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -4051,6 +4053,7 @@ void RasterizerStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) { gi_probe->bias = p_bias; } + float RasterizerStorageRD::gi_probe_get_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4063,6 +4066,7 @@ void RasterizerStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_norma gi_probe->normal_bias = p_normal_bias; } + float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, 0); @@ -4070,7 +4074,6 @@ float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const { } void RasterizerStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND(!gi_probe); @@ -4123,13 +4126,12 @@ uint32_t RasterizerStorageRD::gi_probe_get_data_version(RID p_gi_probe) { } RID RasterizerStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const { - GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->octree_buffer; } -RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { +RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const { GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe); ERR_FAIL_COND_V(!gi_probe, RID()); return gi_probe->data_buffer; @@ -4142,10 +4144,182 @@ RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) { return gi_probe->sdf_texture; } +/* LIGHTMAP API */ + +RID RasterizerStorageRD::lightmap_create() { + return lightmap_owner.make_rid(Lightmap()); +} + +void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + lightmap_array_version++; + + //erase lightmap users + if (lm->light_texture.is_valid()) { + Texture *t = texture_owner.getornull(lm->light_texture); + if (t) { + t->lightmap_users.erase(p_lightmap); + } + } + + Texture *t = texture_owner.getornull(p_light); + lm->light_texture = p_light; + lm->uses_spherical_harmonics = p_uses_spherical_haromics; + + RID default_2d_array = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + if (!t) { + if (using_lightmap_array) { + if (lm->array_index >= 0) { + lightmap_textures.write[lm->array_index] = default_2d_array; + lm->array_index = -1; + } + } + + return; + } + + t->lightmap_users.insert(p_lightmap); + + if (using_lightmap_array) { + if (lm->array_index < 0) { + //not in array, try to put in array + for (int i = 0; i < lightmap_textures.size(); i++) { + if (lightmap_textures[i] == default_2d_array) { + lm->array_index = i; + break; + } + } + } + ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly."); + + lightmap_textures.write[lm->array_index] = t->rd_texture; + } +} + +void RasterizerStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + lm->bounds = p_bounds; +} + +void RasterizerStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + lm->interior = p_interior; +} + +void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + if (p_points.size()) { + ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size()); + ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0); + ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0); + } + + lm->points = p_points; + lm->bsp_tree = p_bsp_tree; + lm->point_sh = p_point_sh; + lm->tetrahedra = p_tetrahedra; +} + +PackedVector3Array RasterizerStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedVector3Array()); + + return lm->points; +} + +PackedColorArray RasterizerStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedColorArray()); + return lm->point_sh; +} + +PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedInt32Array()); + return lm->tetrahedra; +} + +PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, PackedInt32Array()); + return lm->bsp_tree; +} + +void RasterizerStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) { + lightmap_probe_capture_update_speed = p_speed; +} + +void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) { + Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND(!lm); + + for (int i = 0; i < 9; i++) { + r_sh[i] = Color(0, 0, 0, 0); + } + + if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) { + return; + } + + static_assert(sizeof(Lightmap::BSP) == 24); + + const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr(); + int32_t node = 0; + while (node >= 0) { + if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node); +#endif + + node = bsp[node].over; + } else { +#ifdef DEBUG_ENABLED + ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node); +#endif + node = bsp[node].under; + } + } + + if (node == Lightmap::BSP::EMPTY_LEAF) { + return; //nothing could be done + } + + node = ABS(node) - 1; + + uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4]; + Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] }; + const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] }; + Color barycentric = Geometry3D::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point); + + for (int i = 0; i < 4; i++) { + float c = CLAMP(barycentric[i], 0.0, 1.0); + for (int j = 0; j < 9; j++) { + r_sh[j] += sh_colors[i][j] * c; + } + } +} + +bool RasterizerStorageRD::lightmap_is_interior(RID p_lightmap) const { + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, false); + return lm->interior; +} + +AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const { + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + ERR_FAIL_COND_V(!lm, AABB()); + return lm->bounds; +} + /* RENDER TARGET API */ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { - //free in reverse dependency order if (rt->framebuffer.is_valid()) { RD::get_singleton()->free(rt->framebuffer); @@ -4174,7 +4348,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) { } void RasterizerStorageRD::_update_render_target(RenderTarget *rt) { - if (rt->texture.is_null()) { //create a placeholder until updated rt->texture = texture_2d_placeholder_create(); @@ -4279,7 +4452,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) { //create mipmaps for (uint32_t i = 1; i < mipmaps_required; i++) { - RenderTarget::BackbufferMipmap mm; { mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i); @@ -4343,14 +4515,12 @@ void RasterizerStorageRD::render_target_set_flag(RID p_render_target, RenderTarg } bool RasterizerStorageRD::render_target_was_used(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, false); return rt->was_used; } void RasterizerStorageRD::render_target_set_as_unused(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->was_used = false; @@ -4369,12 +4539,14 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) { return rt->framebuffer; } + RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, RID()); return rt->color; } + void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); @@ -4389,21 +4561,18 @@ bool RasterizerStorageRD::render_target_is_clear_requested(RID p_render_target) } Color RasterizerStorageRD::render_target_get_clear_request_color(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND_V(!rt, Color()); return rt->clear_color; } void RasterizerStorageRD::render_target_disable_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); rt->clear_requested = false; } void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) { - RenderTarget *rt = render_target_owner.getornull(p_render_target); ERR_FAIL_COND(!rt); if (!rt->clear_requested) { @@ -4478,7 +4647,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In Mesh *mesh = mesh_owner.getornull(p_base); p_instance->update_dependency(&mesh->instance_dependency); } else if (multimesh_owner.owns(p_base)) { - MultiMesh *multimesh = multimesh_owner.getornull(p_base); p_instance->update_dependency(&multimesh->instance_dependency); if (multimesh->mesh.is_valid()) { @@ -4493,6 +4661,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } else if (gi_probe_owner.owns(p_base)) { GIProbe *gip = gi_probe_owner.getornull(p_base); p_instance->update_dependency(&gip->instance_dependency); + } else if (lightmap_owner.owns(p_base)) { + Lightmap *lm = lightmap_owner.getornull(p_base); + p_instance->update_dependency(&lm->instance_dependency); } else if (light_owner.owns(p_base)) { Light *l = light_owner.getornull(p_base); p_instance->update_dependency(&l->instance_dependency); @@ -4500,7 +4671,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In } void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) { - Skeleton *skeleton = skeleton_owner.getornull(p_skeleton); ERR_FAIL_COND(!skeleton); @@ -4508,7 +4678,6 @@ void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerS } RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { - if (mesh_owner.owns(p_rid)) { return RS::INSTANCE_MESH; } @@ -4527,6 +4696,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { if (light_owner.owns(p_rid)) { return RS::INSTANCE_LIGHT; } + if (lightmap_owner.owns(p_rid)) { + return RS::INSTANCE_LIGHTMAP; + } return RS::INSTANCE_NONE; } @@ -4590,7 +4762,7 @@ void RasterizerStorageRD::_update_decal_atlas() { Vector<DecalAtlas::SortItem> itemsv; itemsv.resize(decal_atlas.textures.size()); int base_size = 8; - const RID *K = NULL; + const RID *K = nullptr; int idx = 0; while ((K = decal_atlas.textures.next(K))) { @@ -4620,7 +4792,6 @@ void RasterizerStorageRD::_update_decal_atlas() { int atlas_height = 0; while (true) { - Vector<int> v_offsetsv; v_offsetsv.resize(base_size); @@ -4680,12 +4851,11 @@ void RasterizerStorageRD::_update_decal_atlas() { DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture); t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2); t->uv_rect.size = items[i].pixel_size; - //print_line("blitrect: " + t->uv_rect); + t->uv_rect.position /= Size2(decal_atlas.size); t->uv_rect.size /= Size2(decal_atlas.size); } } else { - //use border as size, so it at least has enough mipmaps decal_atlas.size.width = border; decal_atlas.size.height = border; @@ -4737,14 +4907,13 @@ void RasterizerStorageRD::_update_decal_atlas() { Color clear_color(0, 0, 0, 0); if (decal_atlas.textures.size()) { - if (i == 0) { Vector<Color> cc; cc.push_back(clear_color); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc); - const RID *K = NULL; + const RID *K = nullptr; while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); Texture *src_tex = texture_owner.getornull(*K); @@ -4755,7 +4924,6 @@ void RasterizerStorageRD::_update_decal_atlas() { prev_texture = mm.texture; } else { - effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); prev_texture = mm.texture; } @@ -4766,7 +4934,6 @@ void RasterizerStorageRD::_update_decal_atlas() { } int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { - int32_t idx = 0; while (idx + p_elements <= global_variables.buffer_size) { if (global_variables.buffer_usage[idx].elements == 0) { @@ -4793,10 +4960,8 @@ int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) { } void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { - switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; @@ -4975,7 +5140,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.elements[0][0]; @@ -4995,7 +5159,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Vector<float> m2 = p_value; @@ -5025,7 +5188,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.elements[0][0]; @@ -5045,7 +5207,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; Transform v = p_value; bv[0].x = v.basis.elements[0][0]; @@ -5063,10 +5224,10 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: bv[2].z = v.basis.elements[2][2]; bv[2].w = 0; - bv[2].x = v.origin.x; - bv[2].y = v.origin.y; - bv[2].z = v.origin.z; - bv[2].w = 1; + bv[3].x = v.origin.x; + bv[3].y = v.origin.y; + bv[3].z = v.origin.z; + bv[3].w = 1; } break; default: { @@ -5076,7 +5237,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS:: } void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { - int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { @@ -5093,7 +5253,6 @@ void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, in } void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); GlobalVariables::Variable gv; gv.type = p_type; @@ -5104,7 +5263,6 @@ void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::Glob //is texture global_variables.must_update_texture_materials = true; //normally ther are no } else { - gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { //color needs to elements to store srgb and linear @@ -5147,13 +5305,13 @@ void RasterizerStorageRD::global_variable_remove(const StringName &p_name) { global_variables.variables.erase(p_name); } -Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { +Vector<StringName> RasterizerStorageRD::global_variable_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } - const StringName *K = NULL; + const StringName *K = nullptr; Vector<StringName> names; while ((K = global_variables.variables.next(K))) { names.push_back(*K); @@ -5181,6 +5339,7 @@ void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Va } } } + void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) { if (!global_variables.variables.has(p_name)) { return; //variable may not exist @@ -5210,7 +5369,6 @@ void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, } Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const { - if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } @@ -5223,7 +5381,6 @@ Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const } RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } @@ -5240,7 +5397,6 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const Strin } void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) { - List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -5346,8 +5502,8 @@ void RasterizerStorageRD::global_variables_instance_free(RID p_instance) { } global_variables.instance_buffer_pos.erase(p_instance); } -void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { +void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { if (!global_variables.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } @@ -5391,7 +5547,6 @@ void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p } void RasterizerStorageRD::_update_global_variables() { - if (global_variables.buffer_dirty_region_count > 0) { uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; if (total_regions / global_variables.buffer_dirty_region_count <= 4) { @@ -5403,7 +5558,6 @@ void RasterizerStorageRD::_update_global_variables() { for (uint32_t i = 0; i < total_regions; i++) { if (global_variables.buffer_dirty_regions[i]) { - RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values); global_variables.buffer_dirty_regions[i] = false; @@ -5451,7 +5605,6 @@ void RasterizerStorageRD::update_dirty_resources() { } bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { - if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) { return true; } @@ -5474,8 +5627,8 @@ bool RasterizerStorageRD::has_os_feature(const String &p_feature) const { return false; } -bool RasterizerStorageRD::free(RID p_rid) { +bool RasterizerStorageRD::free(RID p_rid) { if (texture_owner.owns(p_rid)) { Texture *t = texture_owner.getornull(p_rid); @@ -5565,9 +5718,13 @@ bool RasterizerStorageRD::free(RID p_rid) { GIProbe *gi_probe = gi_probe_owner.getornull(p_rid); gi_probe->instance_dependency.instance_notify_deleted(p_rid); gi_probe_owner.free(p_rid); + } else if (lightmap_owner.owns(p_rid)) { + lightmap_set_textures(p_rid, RID(), false); + Lightmap *lightmap = lightmap_owner.getornull(p_rid); + lightmap->instance_dependency.instance_notify_deleted(p_rid); + lightmap_owner.free(p_rid); } else if (light_owner.owns(p_rid)) { - light_set_projector(p_rid, RID()); //clear projector // delete the texture Light *light = light_owner.getornull(p_rid); @@ -5608,6 +5765,7 @@ void RasterizerStorageRD::capture_timestamp(const String &p_name) { uint32_t RasterizerStorageRD::get_captured_timestamps_count() const { return RD::get_singleton()->get_captured_timestamps_count(); } + uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const { return RD::get_singleton()->get_captured_timestamps_frame(); } @@ -5615,9 +5773,11 @@ uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const { uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index); } + uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index); } + String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const { return RD::get_singleton()->get_captured_timestamp_name(p_index); } @@ -5625,7 +5785,6 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr; RasterizerStorageRD::RasterizerStorageRD() { - base_singleton = this; for (int i = 0; i < SHADER_TYPE_MAX; i++) { @@ -5803,6 +5962,32 @@ RasterizerStorageRD::RasterizerStorageRD() { } } + { //create default array + + RD::TextureFormat tformat; + tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + tformat.width = 4; + tformat.height = 4; + tformat.array_layers = 1; + tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; + tformat.type = RD::TEXTURE_TYPE_2D_ARRAY; + + Vector<uint8_t> pv; + pv.resize(16 * 4); + for (int i = 0; i < 16; i++) { + pv.set(i * 4 + 0, 255); + pv.set(i * 4 + 1, 255); + pv.set(i * 4 + 2, 255); + pv.set(i * 4 + 3, 255); + } + + { + Vector<Vector<uint8_t>> vpv; + vpv.push_back(pv); + default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv); + } + } + //default samplers for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { @@ -5814,7 +5999,6 @@ RasterizerStorageRD::RasterizerStorageRD() { sampler_state.max_lod = 0; } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR: { - sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.max_lod = 0; @@ -5835,14 +6019,14 @@ RasterizerStorageRD::RasterizerStorageRD() { sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy"); + sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level")); } break; case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: { sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR; sampler_state.use_anisotropy = true; - sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy"); + sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level")); } break; default: { @@ -5850,7 +6034,6 @@ RasterizerStorageRD::RasterizerStorageRD() { } switch (j) { case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: { - sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE; @@ -5873,129 +6056,134 @@ RasterizerStorageRD::RasterizerStorageRD() { //default rd buffers { - - //vertex + Vector<uint8_t> buffer; { + buffer.resize(sizeof(float) * 3); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } - Vector<uint8_t> buffer; + { //normal + buffer.resize(sizeof(float) * 3); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } - buffer.resize(sizeof(float) * 3); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //tangent + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //normal - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 3); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //color + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 1.0; + fptr[1] = 1.0; + fptr[2] = 1.0; + fptr[3] = 1.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //tangent - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - fptr[3] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //tex uv 1 + buffer.resize(sizeof(float) * 2); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } + { //tex uv 2 + buffer.resize(sizeof(float) * 2); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //color - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 1.0; - fptr[1] = 1.0; - fptr[2] = 1.0; - fptr[3] = 1.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} + { //bones + buffer.resize(sizeof(uint32_t) * 4); + { + uint8_t *w = buffer.ptrw(); + uint32_t *fptr = (uint32_t *)w; + fptr[0] = 0; + fptr[1] = 0; + fptr[2] = 0; + fptr[3] = 0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } -{ //tex uv 1 - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 2); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //tex uv 2 - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 2); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; + { //weights + buffer.resize(sizeof(float) * 4); + { + uint8_t *w = buffer.ptrw(); + float *fptr = (float *)w; + fptr[0] = 0.0; + fptr[1] = 0.0; + fptr[2] = 0.0; + fptr[3] = 0.0; + } + mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); + } } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //bones - Vector<uint8_t> buffer; - buffer.resize(sizeof(uint32_t) * 4); { - uint8_t *w = buffer.ptrw(); - uint32_t *fptr = (uint32_t *)w; - fptr[0] = 0; - fptr[1] = 0; - fptr[2] = 0; - fptr[3] = 0; + Vector<String> sdf_versions; + sdf_versions.push_back(""); //one only + giprobe_sdf_shader.initialize(sdf_versions); + giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); + giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>()); + giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); + giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -{ //weights - Vector<uint8_t> buffer; - buffer.resize(sizeof(float) * 4); - { - uint8_t *w = buffer.ptrw(); - float *fptr = (float *)w; - fptr[0] = 0.0; - fptr[1] = 0.0; - fptr[2] = 0.0; - fptr[3] = 0.0; + using_lightmap_array = true; // high end + if (using_lightmap_array) { + uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + + if (textures_per_stage <= 256) { + lightmap_textures.resize(32); + } else { + lightmap_textures.resize(1024); + } + + for (int i = 0; i < lightmap_textures.size(); i++) { + lightmap_textures.write[i] = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE]; + } } - mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer); -} -} -{ - Vector<String> sdf_versions; - sdf_versions.push_back(""); //one only - giprobe_sdf_shader.initialize(sdf_versions); - giprobe_sdf_shader_version = giprobe_sdf_shader.version_create(); - giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>()); - giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0); - giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader); -} + lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed"); } RasterizerStorageRD::~RasterizerStorageRD() { - memdelete_arr(global_variables.buffer_values); memdelete_arr(global_variables.buffer_usage); memdelete_arr(global_variables.buffer_dirty_regions); diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h index f874c3baf8..fe9377192e 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h @@ -64,7 +64,6 @@ public: typedef ShaderData *(*ShaderDataRequestFunction)(); struct MaterialData { - void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); @@ -92,6 +91,7 @@ public: DEFAULT_RD_TEXTURE_CUBEMAP_BLACK, DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK, DEFAULT_RD_TEXTURE_3D_WHITE, + DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE, DEFAULT_RD_TEXTURE_MAX }; @@ -110,7 +110,6 @@ public: private: /* TEXTURE API */ struct Texture { - enum Type { TYPE_2D, TYPE_LAYERED, @@ -118,6 +117,7 @@ private: }; Type type; + RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY; RenderingDevice::TextureType rd_type; RID rd_texture; @@ -147,6 +147,7 @@ private: RID proxy_to; Vector<RID> proxies; + Set<RID> lightmap_users; RS::TextureDetectCallback detect_3d_callback = nullptr; void *detect_3d_callback_ud = nullptr; @@ -187,7 +188,6 @@ private: struct DecalAtlas { struct Texture { - int panorama_to_dp_users; int users; Rect2 uv_rect; @@ -271,7 +271,6 @@ private: /* Mesh */ struct Mesh { - struct Surface { RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS; uint32_t format = 0; @@ -413,7 +412,6 @@ private: /* LIGHT */ struct Light { - RS::LightType type; float param[RS::LIGHT_PARAM_MAX]; Color color = Color(1, 1, 1, 1); @@ -438,7 +436,6 @@ private: /* REFLECTION PROBE */ struct ReflectionProbe { - RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE; int resolution = 256; float intensity = 1.0; @@ -461,7 +458,6 @@ private: /* DECAL */ struct Decal { - Vector3 extents = Vector3(1, 1, 1); RID textures[RS::DECAL_TEXTURE_MAX]; float emission_energy = 1.0; @@ -483,7 +479,6 @@ private: /* GI PROBE */ struct GIProbe { - RID octree_buffer; RID data_buffer; RID sdf_texture; @@ -524,10 +519,42 @@ private: mutable RID_Owner<GIProbe> gi_probe_owner; + /* REFLECTION PROBE */ + + struct Lightmap { + RID light_texture; + bool uses_spherical_harmonics = false; + bool interior = false; + AABB bounds = AABB(Vector3(), Vector3(1, 1, 1)); + int32_t array_index = -1; //unassigned + PackedVector3Array points; + PackedColorArray point_sh; + PackedInt32Array tetrahedra; + PackedInt32Array bsp_tree; + + struct BSP { + static const int32_t EMPTY_LEAF = INT32_MIN; + float plane[4]; + int32_t over = EMPTY_LEAF, under = EMPTY_LEAF; + }; + + RasterizerScene::InstanceDependency instance_dependency; + }; + + bool using_lightmap_array; //high end uses this + /* for high end */ + + Vector<RID> lightmap_textures; + + uint64_t lightmap_array_version = 0; + + mutable RID_Owner<Lightmap> lightmap_owner; + + float lightmap_probe_capture_update_speed = 4; + /* RENDER TARGET */ struct RenderTarget { - Size2i size; RID framebuffer; RID color; @@ -568,7 +595,6 @@ private: /* GLOBAL SHADER VARIABLES */ struct GlobalVariables { - enum { BUFFER_DIRTY_REGION_SIZE = 1024 }; @@ -653,7 +679,7 @@ public: //these two APIs can be used together or in combination with the others. virtual RID texture_2d_placeholder_create(); - virtual RID texture_2d_layered_placeholder_create(); + virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type); virtual RID texture_3d_placeholder_create(); virtual Ref<Image> texture_2d_get(RID p_texture) const; @@ -1037,7 +1063,6 @@ public: AABB light_get_aabb(RID p_light) const; _FORCE_INLINE_ float light_get_param(RID p_light, RS::LightParam p_param) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -1045,7 +1070,6 @@ public: } _FORCE_INLINE_ RID light_get_projector(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RID()); @@ -1053,7 +1077,6 @@ public: } _FORCE_INLINE_ Color light_get_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, Color()); @@ -1061,7 +1084,6 @@ public: } _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, Color()); @@ -1069,7 +1091,6 @@ public: } _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0); @@ -1077,7 +1098,6 @@ public: } _FORCE_INLINE_ bool light_has_shadow(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); @@ -1085,7 +1105,6 @@ public: } _FORCE_INLINE_ bool light_is_negative(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL); @@ -1093,7 +1112,6 @@ public: } _FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const { - const Light *light = light_owner.getornull(p_light); ERR_FAIL_COND_V(!light, 0.0); @@ -1270,23 +1288,47 @@ public: /* LIGHTMAP CAPTURE */ - void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {} - AABB lightmap_capture_get_bounds(RID p_capture) const { return AABB(); } - void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {} - RID lightmap_capture_create() { - return RID(); + virtual RID lightmap_create(); + + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics); + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds); + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior); + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree); + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const; + virtual AABB lightmap_get_aabb(RID p_lightmap) const; + virtual bool lightmap_is_interior(RID p_lightmap) const; + virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh); + virtual void lightmap_set_probe_capture_update_speed(float p_speed); + _FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const { + return lightmap_probe_capture_update_speed; + } + + _FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const { + ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + return lm->array_index; } - Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const { - return Vector<uint8_t>(); + _FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const { + ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays + const Lightmap *lm = lightmap_owner.getornull(p_lightmap); + return lm->uses_spherical_harmonics; } - void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) {} - Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const { return Transform(); } - void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) {} - int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const { return 0; } - void lightmap_capture_set_energy(RID p_capture, float p_energy) {} - float lightmap_capture_get_energy(RID p_capture) const { return 0.0; } - const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const { - return nullptr; + _FORCE_INLINE_ uint64_t lightmap_array_get_version() const { + ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays + return lightmap_array_version; + } + + _FORCE_INLINE_ int lightmap_array_get_size() const { + ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays + return lightmap_textures.size(); + } + + _FORCE_INLINE_ const Vector<RID> &lightmap_array_get_textures() const { + ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays + return lightmap_textures; } /* PARTICLES */ diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp index 2bfdb7fffe..5cc3da8d4e 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp @@ -31,23 +31,25 @@ #include "render_pipeline_vertex_format_cache_rd.h" #include "core/os/memory.h" -RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { - +RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) { RD::PipelineMultisampleState multisample_state_version = multisample_state; multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id); - RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags); + RD::PipelineRasterizationState raster_state_version = rasterization_state; + raster_state_version.wireframe = p_wireframe; + + RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags); ERR_FAIL_COND_V(pipeline.is_null(), RID()); versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1)); versions[version_count].framebuffer_id = p_framebuffer_format_id; versions[version_count].vertex_id = p_vertex_format_id; + versions[version_count].wireframe = p_wireframe; versions[version_count].pipeline = pipeline; version_count++; return pipeline; } void RenderPipelineVertexFormatCacheRD::_clear() { - if (versions) { for (uint32_t i = 0; i < version_count; i++) { //shader may be gone, so this may not be valid diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h index ecb1b42b06..cf15e79586 100644 --- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h +++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h @@ -35,7 +35,6 @@ #include "servers/rendering/rendering_device.h" class RenderPipelineVertexFormatCacheRD { - SpinLock spin_lock; RID shader; @@ -51,13 +50,14 @@ class RenderPipelineVertexFormatCacheRD { struct Version { RD::VertexFormatID vertex_id; RD::FramebufferFormatID framebuffer_id; + bool wireframe; RID pipeline; }; Version *versions; uint32_t version_count; - RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id); + RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe); void _clear(); @@ -65,7 +65,7 @@ public: void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0); void update_shader(RID p_shader); - _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) { + _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false) { #ifdef DEBUG_ENABLED ERR_FAIL_COND_V_MSG(shader.is_null(), RID(), "Attempted to use an unused shader variant (shader is null),"); @@ -74,13 +74,13 @@ public: spin_lock.lock(); RID result; for (uint32_t i = 0; i < version_count; i++) { - if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) { + if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe) { result = versions[i].pipeline; spin_lock.unlock(); return result; } } - result = _generate_version(p_vertex_format_id, p_framebuffer_format_id); + result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe); spin_lock.unlock(); return result; } diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp index 9cbff2571a..32321164a1 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp @@ -38,7 +38,6 @@ #define SL ShaderLanguage static String _mktab(int p_level) { - String tb; for (int i = 0; i < p_level; i++) { tb += "\t"; @@ -48,7 +47,6 @@ static String _mktab(int p_level) { } static String _typestr(SL::DataType p_type) { - String type = ShaderLanguage::get_datatype_name(p_type); if (ShaderLanguage::is_sampler_type(p_type)) { type = type.replace("sampler", "texture"); //we use textures instead of samplers @@ -57,42 +55,72 @@ static String _typestr(SL::DataType p_type) { } static int _get_datatype_size(SL::DataType p_type) { - switch (p_type) { - - case SL::TYPE_VOID: return 0; - case SL::TYPE_BOOL: return 4; - case SL::TYPE_BVEC2: return 8; - case SL::TYPE_BVEC3: return 12; - case SL::TYPE_BVEC4: return 16; - case SL::TYPE_INT: return 4; - case SL::TYPE_IVEC2: return 8; - case SL::TYPE_IVEC3: return 12; - case SL::TYPE_IVEC4: return 16; - case SL::TYPE_UINT: return 4; - case SL::TYPE_UVEC2: return 8; - case SL::TYPE_UVEC3: return 12; - case SL::TYPE_UVEC4: return 16; - case SL::TYPE_FLOAT: return 4; - case SL::TYPE_VEC2: return 8; - case SL::TYPE_VEC3: return 12; - case SL::TYPE_VEC4: return 16; + case SL::TYPE_VOID: + return 0; + case SL::TYPE_BOOL: + return 4; + case SL::TYPE_BVEC2: + return 8; + case SL::TYPE_BVEC3: + return 12; + case SL::TYPE_BVEC4: + return 16; + case SL::TYPE_INT: + return 4; + case SL::TYPE_IVEC2: + return 8; + case SL::TYPE_IVEC3: + return 12; + case SL::TYPE_IVEC4: + return 16; + case SL::TYPE_UINT: + return 4; + case SL::TYPE_UVEC2: + return 8; + case SL::TYPE_UVEC3: + return 12; + case SL::TYPE_UVEC4: + return 16; + case SL::TYPE_FLOAT: + return 4; + case SL::TYPE_VEC2: + return 8; + case SL::TYPE_VEC3: + return 12; + case SL::TYPE_VEC4: + return 16; case SL::TYPE_MAT2: return 32; //4 * 4 + 4 * 4 case SL::TYPE_MAT3: return 48; // 4 * 4 + 4 * 4 + 4 * 4 - case SL::TYPE_MAT4: return 64; - case SL::TYPE_SAMPLER2D: return 16; - case SL::TYPE_ISAMPLER2D: return 16; - case SL::TYPE_USAMPLER2D: return 16; - case SL::TYPE_SAMPLER2DARRAY: return 16; - case SL::TYPE_ISAMPLER2DARRAY: return 16; - case SL::TYPE_USAMPLER2DARRAY: return 16; - case SL::TYPE_SAMPLER3D: return 16; - case SL::TYPE_ISAMPLER3D: return 16; - case SL::TYPE_USAMPLER3D: return 16; - case SL::TYPE_SAMPLERCUBE: return 16; - case SL::TYPE_STRUCT: return 0; + case SL::TYPE_MAT4: + return 64; + case SL::TYPE_SAMPLER2D: + return 16; + case SL::TYPE_ISAMPLER2D: + return 16; + case SL::TYPE_USAMPLER2D: + return 16; + case SL::TYPE_SAMPLER2DARRAY: + return 16; + case SL::TYPE_ISAMPLER2DARRAY: + return 16; + case SL::TYPE_USAMPLER2DARRAY: + return 16; + case SL::TYPE_SAMPLER3D: + return 16; + case SL::TYPE_ISAMPLER3D: + return 16; + case SL::TYPE_USAMPLER3D: + return 16; + case SL::TYPE_SAMPLERCUBE: + return 16; + case SL::TYPE_SAMPLERCUBEARRAY: + return 16; + case SL::TYPE_STRUCT: + return 0; + case SL::TYPE_MAX: { ERR_FAIL_V(0); }; @@ -102,40 +130,71 @@ static int _get_datatype_size(SL::DataType p_type) { } static int _get_datatype_alignment(SL::DataType p_type) { - switch (p_type) { - - case SL::TYPE_VOID: return 0; - case SL::TYPE_BOOL: return 4; - case SL::TYPE_BVEC2: return 8; - case SL::TYPE_BVEC3: return 16; - case SL::TYPE_BVEC4: return 16; - case SL::TYPE_INT: return 4; - case SL::TYPE_IVEC2: return 8; - case SL::TYPE_IVEC3: return 16; - case SL::TYPE_IVEC4: return 16; - case SL::TYPE_UINT: return 4; - case SL::TYPE_UVEC2: return 8; - case SL::TYPE_UVEC3: return 16; - case SL::TYPE_UVEC4: return 16; - case SL::TYPE_FLOAT: return 4; - case SL::TYPE_VEC2: return 8; - case SL::TYPE_VEC3: return 16; - case SL::TYPE_VEC4: return 16; - case SL::TYPE_MAT2: return 16; - case SL::TYPE_MAT3: return 16; - case SL::TYPE_MAT4: return 16; - case SL::TYPE_SAMPLER2D: return 16; - case SL::TYPE_ISAMPLER2D: return 16; - case SL::TYPE_USAMPLER2D: return 16; - case SL::TYPE_SAMPLER2DARRAY: return 16; - case SL::TYPE_ISAMPLER2DARRAY: return 16; - case SL::TYPE_USAMPLER2DARRAY: return 16; - case SL::TYPE_SAMPLER3D: return 16; - case SL::TYPE_ISAMPLER3D: return 16; - case SL::TYPE_USAMPLER3D: return 16; - case SL::TYPE_SAMPLERCUBE: return 16; - case SL::TYPE_STRUCT: return 0; + case SL::TYPE_VOID: + return 0; + case SL::TYPE_BOOL: + return 4; + case SL::TYPE_BVEC2: + return 8; + case SL::TYPE_BVEC3: + return 16; + case SL::TYPE_BVEC4: + return 16; + case SL::TYPE_INT: + return 4; + case SL::TYPE_IVEC2: + return 8; + case SL::TYPE_IVEC3: + return 16; + case SL::TYPE_IVEC4: + return 16; + case SL::TYPE_UINT: + return 4; + case SL::TYPE_UVEC2: + return 8; + case SL::TYPE_UVEC3: + return 16; + case SL::TYPE_UVEC4: + return 16; + case SL::TYPE_FLOAT: + return 4; + case SL::TYPE_VEC2: + return 8; + case SL::TYPE_VEC3: + return 16; + case SL::TYPE_VEC4: + return 16; + case SL::TYPE_MAT2: + return 16; + case SL::TYPE_MAT3: + return 16; + case SL::TYPE_MAT4: + return 16; + case SL::TYPE_SAMPLER2D: + return 16; + case SL::TYPE_ISAMPLER2D: + return 16; + case SL::TYPE_USAMPLER2D: + return 16; + case SL::TYPE_SAMPLER2DARRAY: + return 16; + case SL::TYPE_ISAMPLER2DARRAY: + return 16; + case SL::TYPE_USAMPLER2DARRAY: + return 16; + case SL::TYPE_SAMPLER3D: + return 16; + case SL::TYPE_ISAMPLER3D: + return 16; + case SL::TYPE_USAMPLER3D: + return 16; + case SL::TYPE_SAMPLERCUBE: + return 16; + case SL::TYPE_SAMPLERCUBEARRAY: + return 16; + case SL::TYPE_STRUCT: + return 0; case SL::TYPE_MAX: { ERR_FAIL_V(0); } @@ -143,49 +202,53 @@ static int _get_datatype_alignment(SL::DataType p_type) { ERR_FAIL_V(0); } -static String _interpstr(SL::DataInterpolation p_interp) { +static String _interpstr(SL::DataInterpolation p_interp) { switch (p_interp) { - case SL::INTERPOLATION_FLAT: return "flat "; - case SL::INTERPOLATION_SMOOTH: return ""; + case SL::INTERPOLATION_FLAT: + return "flat "; + case SL::INTERPOLATION_SMOOTH: + return ""; } return ""; } static String _prestr(SL::DataPrecision p_pres) { - switch (p_pres) { - case SL::PRECISION_LOWP: return "lowp "; - case SL::PRECISION_MEDIUMP: return "mediump "; - case SL::PRECISION_HIGHP: return "highp "; - case SL::PRECISION_DEFAULT: return ""; + case SL::PRECISION_LOWP: + return "lowp "; + case SL::PRECISION_MEDIUMP: + return "mediump "; + case SL::PRECISION_HIGHP: + return "highp "; + case SL::PRECISION_DEFAULT: + return ""; } return ""; } static String _qualstr(SL::ArgumentQualifier p_qual) { - switch (p_qual) { - case SL::ARGUMENT_QUALIFIER_IN: return ""; - case SL::ARGUMENT_QUALIFIER_OUT: return "out "; - case SL::ARGUMENT_QUALIFIER_INOUT: return "inout "; + case SL::ARGUMENT_QUALIFIER_IN: + return ""; + case SL::ARGUMENT_QUALIFIER_OUT: + return "out "; + case SL::ARGUMENT_QUALIFIER_INOUT: + return "inout "; } return ""; } static String _opstr(SL::Operator p_op) { - return SL::get_operator_text(p_op); } static String _mkid(const String &p_id) { - String id = "m_" + p_id.replace("__", "_dus_"); return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl } static String f2sp0(float p_float) { - String num = rtoss(p_float); if (num.find(".") == -1 && num.find("e") == -1) { num += ".0"; @@ -194,17 +257,17 @@ static String f2sp0(float p_float) { } static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) { - switch (p_type) { - case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false"; + case SL::TYPE_BOOL: + return p_values[0].boolean ? "true" : "false"; case SL::TYPE_BVEC2: case SL::TYPE_BVEC3: case SL::TYPE_BVEC4: { - String text = "bvec" + itos(p_type - SL::TYPE_BOOL + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += p_values[i].boolean ? "true" : "false"; } @@ -212,15 +275,16 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo return text; } - case SL::TYPE_INT: return itos(p_values[0].sint); + case SL::TYPE_INT: + return itos(p_values[0].sint); case SL::TYPE_IVEC2: case SL::TYPE_IVEC3: case SL::TYPE_IVEC4: { - String text = "ivec" + itos(p_type - SL::TYPE_INT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += itos(p_values[i].sint); } @@ -228,30 +292,32 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo return text; } break; - case SL::TYPE_UINT: return itos(p_values[0].uint) + "u"; + case SL::TYPE_UINT: + return itos(p_values[0].uint) + "u"; case SL::TYPE_UVEC2: case SL::TYPE_UVEC3: case SL::TYPE_UVEC4: { - String text = "uvec" + itos(p_type - SL::TYPE_UINT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += itos(p_values[i].uint) + "u"; } text += ")"; return text; } break; - case SL::TYPE_FLOAT: return f2sp0(p_values[0].real); + case SL::TYPE_FLOAT: + return f2sp0(p_values[0].real); case SL::TYPE_VEC2: case SL::TYPE_VEC3: case SL::TYPE_VEC4: { - String text = "vec" + itos(p_type - SL::TYPE_FLOAT + 1) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += f2sp0(p_values[i].real); } @@ -262,11 +328,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo case SL::TYPE_MAT2: case SL::TYPE_MAT3: case SL::TYPE_MAT4: { - String text = "mat" + itos(p_type - SL::TYPE_MAT2 + 2) + "("; for (int i = 0; i < p_values.size(); i++) { - if (i > 0) + if (i > 0) { text += ","; + } text += f2sp0(p_values[i].real); } @@ -274,7 +340,8 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo return text; } break; - default: ERR_FAIL_V(String()); + default: + ERR_FAIL_V(String()); } } @@ -291,7 +358,6 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte } void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) { - int fidx = -1; for (int i = 0; i < p_node->functions.size(); i++) { @@ -304,7 +370,6 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S ERR_FAIL_COND(fidx == -1); for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - if (added.has(E->get())) { continue; //was added already } @@ -331,9 +396,9 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "("; } for (int i = 0; i < fnode->arguments.size(); i++) { - - if (i > 0) + if (i > 0) { header += ", "; + } if (fnode->arguments[i].type == SL::TYPE_STRUCT) { header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name); } else { @@ -414,20 +479,15 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c } } -String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) { - +String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) { String code; switch (p_node->type) { - case SL::Node::TYPE_SHADER: { - SL::ShaderNode *pnode = (SL::ShaderNode *)p_node; for (int i = 0; i < pnode->render_modes.size(); i++) { - if (p_default_actions.render_mode_defines.has(pnode->render_modes[i]) && !used_rmode_defines.has(pnode->render_modes[i])) { - r_gen_code.defines.push_back(p_default_actions.render_mode_defines[pnode->render_modes[i]]); used_rmode_defines.insert(pnode->render_modes[i]); } @@ -445,7 +505,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge // structs for (int i = 0; i < pnode->vstructs.size(); i++) { - SL::StructNode *st = pnode->vstructs[i].shader_struct; String struct_code; @@ -481,11 +540,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge int max_uniforms = 0; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - if (SL::is_sampler_type(E->get().type)) { max_texture_uniforms++; } else { - if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; //instances are indexed directly, dont need index uniforms } @@ -505,7 +562,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge bool uses_uniforms = false; for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { - String ucode; if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) { @@ -547,7 +603,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge r_gen_code.texture_uniforms.write[E->get().texture_order] = texture; } else { if (!uses_uniforms) { - r_gen_code.defines.push_back(String("#define USE_MATERIAL_UNIFORMS\n")); uses_uniforms = true; } @@ -573,7 +628,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge // add up int offset = 0; for (int i = 0; i < uniform_sizes.size(); i++) { - int align = offset % uniform_alignments[i]; if (align != 0) { @@ -593,9 +647,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge #else // add up for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) { - int align = uniform_sizes[i - 1] % uniform_alignments[i]; if (align != 0) { uniform_sizes[i - 1] += uniform_alignments[i] - align; @@ -607,7 +659,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //offset r_gen_code.uniform_offsets.resize(uniform_sizes.size()); for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) r_gen_code.uniform_offsets[i] = uniform_sizes[i - 1]; else @@ -633,7 +684,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge uint32_t index = p_default_actions.base_varying_index; for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { - String vcode; String interp_mode = _interpstr(E->get().interpolation); vcode += _prestr(E->get().precision); @@ -650,18 +700,19 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge index++; } - for (Map<StringName, SL::ShaderNode::Constant>::Element *E = pnode->constants.front(); E; E = E->next()) { + for (int i = 0; i < pnode->vconstants.size(); i++) { + const SL::ShaderNode::Constant &cnode = pnode->vconstants[i]; String gcode; gcode += "const "; - gcode += _prestr(E->get().precision); - if (E->get().type == SL::TYPE_STRUCT) { - gcode += _mkid(E->get().type_str); + gcode += _prestr(cnode.precision); + if (cnode.type == SL::TYPE_STRUCT) { + gcode += _mkid(cnode.type_str); } else { - gcode += _typestr(E->get().type); + gcode += _typestr(cnode.type); } - gcode += " " + _mkid(E->key()); + gcode += " " + _mkid(String(cnode.name)); gcode += "="; - gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + gcode += _dump_node_code(cnode.initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); gcode += ";\n"; r_gen_code.vertex_global += gcode; r_gen_code.fragment_global += gcode; @@ -684,7 +735,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge Set<StringName> added_fragment; //share for light for (int i = 0; i < pnode->functions.size(); i++) { - SL::FunctionNode *fnode = pnode->functions[i].function; function = fnode; @@ -692,19 +742,16 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge current_func_name = fnode->name; if (fnode->name == vertex_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.vertex_global, added_vtx); r_gen_code.vertex = function_code[vertex_name]; } if (fnode->name == fragment_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); r_gen_code.fragment = function_code[fragment_name]; } if (fnode->name == light_name) { - _dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment); r_gen_code.light = function_code[light_name]; } @@ -714,10 +761,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge //code+=dump_node_code(pnode->body,p_level); } break; case SL::Node::TYPE_STRUCT: { - } break; case SL::Node::TYPE_FUNCTION: { - } break; case SL::Node::TYPE_BLOCK: { SL::BlockNode *bnode = (SL::BlockNode *)p_node; @@ -728,7 +773,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } for (int i = 0; i < bnode->statements.size(); i++) { - String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) { @@ -790,9 +834,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge used_flag_pointers.insert(vnode->name); } - if (p_default_actions.renames.has(vnode->name)) + if (p_default_actions.renames.has(vnode->name)) { code = p_default_actions.renames[vnode->name]; - else { + } else { if (shader->uniforms.has(vnode->name)) { //its a uniform! const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name]; @@ -850,7 +894,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += ")"; } break; case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node; String declaration; if (adnode->is_const) { @@ -916,14 +959,15 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge used_flag_pointers.insert(anode->name); } - if (p_default_actions.renames.has(anode->name)) + if (p_default_actions.renames.has(anode->name)) { code = p_default_actions.renames[anode->name]; - else + } else { code = _mkid(anode->name); + } if (anode->call_expression != nullptr) { code += "."; - code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false); } if (anode->index_expression != nullptr) { @@ -951,7 +995,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge SL::OperatorNode *onode = (SL::OperatorNode *)p_node; switch (onode->op) { - case SL::OP_ASSIGN: case SL::OP_ASSIGN_ADD: case SL::OP_ASSIGN_SUB: @@ -979,7 +1022,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge case SL::OP_CALL: case SL::OP_STRUCT: case SL::OP_CONSTRUCT: { - ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String()); SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0]; @@ -990,7 +1032,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } else if (onode->op == SL::OP_CONSTRUCT) { code += String(vnode->name); } else { - if (internal_functions.has(vnode->name)) { code += vnode->name; is_texture_func = texture_functions.has(vnode->name); @@ -1004,11 +1045,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += "("; for (int i = 1; i < onode->arguments.size(); i++) { - if (i > 1) + if (i > 1) { code += ", "; + } String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); if (is_texture_func && i == 1 && onode->arguments[i]->type == SL::Node::TYPE_VARIABLE) { - //need to map from texture to sampler in order to sample const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]); @@ -1054,7 +1095,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += ")"; } break; case SL::OP_INDEX: { - code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "["; code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); @@ -1062,7 +1102,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; case SL::OP_SELECT_IF: { - code += "("; code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); code += "?"; @@ -1074,8 +1113,13 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge } break; default: { - - code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")"; + if (p_use_scope) { + code += "("; + } + code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (p_use_scope) { + code += ")"; + } break; } } @@ -1084,37 +1128,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge case SL::Node::TYPE_CONTROL_FLOW: { SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node; if (cfnode->flow_op == SL::FLOW_OP_IF) { - code += _mktab(p_level) + "if (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); if (cfnode->blocks.size() == 2) { - code += _mktab(p_level) + "else\n"; code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } } else if (cfnode->flow_op == SL::FLOW_OP_SWITCH) { - code += _mktab(p_level) + "switch (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_CASE) { - code += _mktab(p_level) + "case " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_DEFAULT) { - code += _mktab(p_level) + "default:\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_DO) { - code += _mktab(p_level) + "do"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");"; } else if (cfnode->flow_op == SL::FLOW_OP_WHILE) { - code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_FOR) { - String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); @@ -1122,14 +1158,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning); } else if (cfnode->flow_op == SL::FLOW_OP_RETURN) { - if (cfnode->expressions.size()) { code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ";"; } else { code = "return;"; } } else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) { - if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) { *p_actions.usage_flag_pointers["DISCARD"] = true; used_flag_pointers.insert("DISCARD"); @@ -1137,10 +1171,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code = "discard;"; } else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) { - code = "continue;"; } else if (cfnode->flow_op == SL::FLOW_OP_BREAK) { - code = "break;"; } @@ -1166,11 +1198,9 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName & } Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { - Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type); if (err != OK) { - Vector<String> shader = p_code.split("\n"); for (int i = 0; i < shader.size(); i++) { print_line(itos(i + 1) + " " + shader[i]); diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h index 16d53197a7..ce94fb743f 100644 --- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h +++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h @@ -39,7 +39,6 @@ class ShaderCompilerRD { public: struct IdentifierActions { - Map<StringName, Pair<int *, int>> render_mode_values; Map<StringName, bool *> render_mode_flags; Map<StringName, bool *> usage_flag_pointers; @@ -49,7 +48,6 @@ public: }; struct GeneratedCode { - Vector<String> defines; struct Texture { StringName name; @@ -77,7 +75,6 @@ public: }; struct DefaultIdentifierActions { - Map<StringName, String> renames; Map<StringName, String> render_mode_defines; Map<StringName, String> usage_defines; @@ -99,7 +96,7 @@ private: String _get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat); void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added); - String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning); + String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true); const ShaderLanguage::ShaderNode *shader; const ShaderLanguage::FunctionNode *function; diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/rasterizer_rd/shader_rd.cpp index d60a58813e..8c57651263 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.cpp +++ b/servers/rendering/rasterizer_rd/shader_rd.cpp @@ -35,7 +35,6 @@ #include "servers/rendering/rendering_device.h" void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) { - name = p_name; //split vertex and shader code (thank you, shader compiler programmers from you know what company). if (p_vertex_code) { @@ -64,7 +63,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { vertex_code1 = code.ascii(); } else { - vertex_code1 = code.substr(0, cpos).ascii(); String code2 = code.substr(cpos + globals_tag.length(), code.length()); @@ -72,7 +70,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { vertex_code2 = code2.ascii(); } else { - vertex_code2 = code2.substr(0, cpos).ascii(); vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); } @@ -106,7 +103,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code1 = code.ascii(); } else { - fragment_code1 = code.substr(0, cpos).ascii(); //print_line("CODE1:\n"+String(fragment_code1.get_data())); @@ -116,7 +112,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code2 = code2.ascii(); } else { - fragment_code2 = code2.substr(0, cpos).ascii(); //print_line("CODE2:\n"+String(fragment_code2.get_data())); @@ -126,7 +121,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { fragment_code3 = code3.ascii(); } else { - fragment_code3 = code3.substr(0, cpos).ascii(); //print_line("CODE3:\n"+String(fragment_code3.get_data())); fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii(); @@ -165,7 +159,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { compute_code1 = code.ascii(); } else { - compute_code1 = code.substr(0, cpos).ascii(); String code2 = code.substr(cpos + globals_tag.length(), code.length()); @@ -173,7 +166,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con if (cpos == -1) { compute_code2 = code2.ascii(); } else { - compute_code2 = code2.substr(0, cpos).ascii(); compute_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii(); } @@ -183,7 +175,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con } RID ShaderRD::version_create() { - //initialize() was never called ERR_FAIL_COND_V(variant_defines.size() == 0, RID()); @@ -208,7 +199,6 @@ void ShaderRD::_clear_version(Version *p_version) { } void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { - Vector<RD::ShaderStageData> stages; String error; @@ -250,7 +240,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_VERTEX; stages.push_back(stage); } @@ -295,7 +284,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_FRAGMENT; stages.push_back(stage); } @@ -336,7 +324,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { if (stage.spir_v.size() == 0) { build_ok = false; } else { - stage.shader_stage = RD::SHADER_STAGE_COMPUTE; stages.push_back(stage); } @@ -361,7 +348,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } void ShaderRD::_compile_version(Version *p_version) { - _clear_version(p_version); p_version->valid = false; @@ -373,7 +359,6 @@ void ShaderRD::_compile_version(Version *p_version) { RasterizerRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); #else for (int i = 0; i < variant_defines.size(); i++) { - _compile_variant(i, p_version); } #endif @@ -402,7 +387,6 @@ void ShaderRD::_compile_version(Version *p_version) { } void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines) { - ERR_FAIL_COND(is_compute); Version *version = version_owner.getornull(p_version); @@ -427,7 +411,6 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S } void ShaderRD::version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines) { - ERR_FAIL_COND(!is_compute); Version *version = version_owner.getornull(p_version); @@ -460,7 +443,6 @@ bool ShaderRD::version_is_valid(RID p_version) { } bool ShaderRD::version_free(RID p_version) { - if (version_owner.owns(p_version)) { Version *version = version_owner.getornull(p_version); _clear_version(version); @@ -477,7 +459,6 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String ERR_FAIL_COND(p_variant_defines.size() == 0); general_defines = p_general_defines.utf8(); for (int i = 0; i < p_variant_defines.size(); i++) { - variant_defines.push_back(p_variant_defines[i].utf8()); } } diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/rasterizer_rd/shader_rd.h index 6635b08cc8..d9bb068ba6 100644 --- a/servers/rendering/rasterizer_rd/shader_rd.h +++ b/servers/rendering/rasterizer_rd/shader_rd.h @@ -43,7 +43,6 @@ */ class ShaderRD { - //versions CharString general_defines; Vector<CharString> variant_defines; diff --git a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl index 7153fe6b17..63f086a83d 100644 --- a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -8,7 +7,6 @@ VERSION_DEFINES #define BLOCK_SIZE 8 layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; -/* clang-format on */ #ifdef MODE_GEN_BLUR_SIZE layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image; @@ -69,7 +67,6 @@ float get_depth_at_pos(vec2 uv) { } float get_blur_size(float depth) { - if (params.blur_near_active && depth < params.blur_near_begin) { return -(1.0 - smoothstep(params.blur_near_end, params.blur_near_begin, depth)) * params.blur_size - DEPTH_GAP; //near blur is negative } @@ -95,7 +92,6 @@ float hash12n(vec2 p) { #if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL) vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { - dir *= pixel_size; vec4 color = texture(color_texture, uv); @@ -109,7 +105,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { } for (int i = -params.blur_steps; i <= params.blur_steps; i++) { - if (i == 0) { continue; } @@ -141,7 +136,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) { #endif void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.size))) { //too large, do nothing @@ -218,7 +212,6 @@ void main() { float radius = params.blur_scale; for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) { - vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius; vec4 sample_color = texture(color_texture, suv); float sample_size = abs(sample_color.a); diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl index 28135fce31..e33b3face9 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 @@ -7,7 +6,6 @@ VERSION_DEFINES #ifdef USE_ATTRIBUTES layout(location = 0) in vec2 vertex_attrib; -/* clang-format on */ layout(location = 3) in vec4 color_attrib; layout(location = 4) in vec2 uv_attrib; @@ -40,7 +38,6 @@ VERTEX_SHADER_GLOBALS /* clang-format on */ void main() { - vec4 instance_custom = vec4(0.0); #ifdef USE_PRIMITIVE @@ -88,7 +85,6 @@ void main() { #if 0 if (draw_data.flags & FLAGS_INSTANCING_ENABLED) { - uint offset = draw_data.flags & FLAGS_INSTANCING_STRIDE_MASK; offset *= gl_InstanceIndex; mat4 instance_xform = mat4( @@ -149,7 +145,6 @@ VERTEX_SHADER_CODE color_interp = color; if (bool(draw_data.flags & FLAGS_USE_PIXEL_SNAP)) { - vertex = floor(vertex + 0.5); // precision issue on some hardware creates artifacts within texture // offset uv by a small amount to avoid @@ -160,7 +155,6 @@ VERTEX_SHADER_CODE #if 0 if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone //skeleton transform - ivec4 bone_indicesi = ivec4(bone_indices); uvec2 tex_ofs = bone_indicesi.x * 2; @@ -211,8 +205,7 @@ VERTEX_SHADER_CODE #endif } -/* clang-format off */ -[fragment] +#[fragment] #version 450 @@ -221,7 +214,6 @@ VERSION_DEFINES #include "canvas_uniforms_inc.glsl" layout(location = 0) in vec2 uv_interp; -/* clang-format on */ layout(location = 1) in vec4 color_interp; layout(location = 2) in vec2 vertex_interp; @@ -258,7 +250,6 @@ vec4 light_compute( vec2 screen_uv, vec2 uv, vec4 color) { - vec4 light = vec4(0.0); /* clang-format off */ LIGHT_SHADER_CODE @@ -271,7 +262,6 @@ LIGHT_SHADER_CODE #ifdef USE_NINEPATCH float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { - float tex_size = 1.0 / tex_pixel_size; if (pixel < margin_begin) { @@ -313,7 +303,6 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo #endif void main() { - vec4 color = color_interp; vec2 uv = uv_interp; vec2 vertex = vertex_interp; @@ -335,7 +324,6 @@ void main() { #endif if (bool(draw_data.flags & FLAGS_CLIP_RECT_UV)) { - uv = clamp(uv, draw_data.src_rect.xy, draw_data.src_rect.xy + abs(draw_data.src_rect.zw)); } @@ -348,7 +336,6 @@ void main() { vec3 normal; #if defined(NORMAL_USED) - bool normal_used = true; #else bool normal_used = false; @@ -458,7 +445,6 @@ FRAGMENT_SHADER_CODE light_color.rgb *= light_base_color.rgb * light_base_color.a; if (normal_used) { - vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height); vec3 pos = light_vertex; vec3 light_vec = normalize(light_pos - pos); @@ -490,7 +476,6 @@ FRAGMENT_SHADER_CODE } if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) { - vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations. vec2 pos_norm = normalize(shadow_pos); diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl index 7b30cc8fe9..99e70a1976 100644 --- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl +++ b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl @@ -1,13 +1,10 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 layout(location = 0) in highp vec3 vertex; -/* clang-format on */ layout(push_constant, binding = 0, std430) uniform Constants { - mat4 projection; mat2x4 modelview; vec2 direction; @@ -18,23 +15,19 @@ constants; layout(location = 0) out highp float depth; void main() { - highp vec4 vtx = vec4(vertex, 1.0) * mat4(constants.modelview[0], constants.modelview[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); depth = dot(constants.direction, vtx.xy); gl_Position = constants.projection * vtx; } -/* clang-format off */ -[fragment] +#[fragment] #version 450 layout(location = 0) in highp float depth; -/* clang-format on */ layout(location = 0) out highp float distance_buf; void main() { - distance_buf = depth; } diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index 2d7661f65f..eb39c28fa9 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ #define FLAG_HORIZONTAL (1 << 0) #define FLAG_USE_BLUR_SECTION (1 << 1) @@ -39,7 +37,13 @@ layout(push_constant, binding = 1, std430) uniform Params { } params; +#ifdef MODE_CUBEMAP_ARRAY_TO_PANORAMA +layout(set = 0, binding = 0) uniform samplerCubeArray source_color; +#elif defined(MODE_CUBEMAP_TO_PANORAMA) +layout(set = 0, binding = 0) uniform samplerCube source_color; +#else layout(set = 0, binding = 0) uniform sampler2D source_color; +#endif #ifdef GLOW_USE_AUTO_EXPOSURE layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; @@ -54,10 +58,9 @@ layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_bu #endif void main() { - // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing + if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing return; } @@ -78,7 +81,6 @@ void main() { //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = (pos + params.section.xy) << 1; vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607; color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879; @@ -89,7 +91,6 @@ void main() { color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303; imageStore(dest_buffer, pos + params.target, color); } else { - ivec2 base_pos = (pos + params.section.xy); vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774; color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477; @@ -115,7 +116,6 @@ void main() { vec4 color = vec4(0.0); if (bool(params.flags & FLAG_HORIZONTAL)) { - ivec2 base_pos = (pos + params.section.xy) << 1; ivec2 section_begin = params.section.xy << 1; ivec2 section_end = section_begin + (params.section.zw << 1); @@ -129,7 +129,6 @@ void main() { GLOW_ADD(ivec2(-3, 0), 0.106595); color *= params.glow_strength; } else { - ivec2 base_pos = pos + params.section.xy; ivec2 section_begin = params.section.xy; ivec2 section_end = section_begin + params.section.zw; @@ -217,4 +216,25 @@ void main() { imageStore(dest_buffer, pos + params.target, color); #endif + +#if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) + + const float PI = 3.14159265359; + vec2 uv = vec2(pos) / vec2(params.section.zw); + uv.y = 1.0 - uv.y; + float phi = uv.x * 2.0 * PI; + float theta = uv.y * PI; + + vec3 normal; + normal.x = sin(phi) * sin(theta) * -1.0; + normal.y = cos(theta); + normal.z = cos(phi) * sin(theta) * -1.0; + +#ifdef MODE_CUBEMAP_TO_PANORAMA + vec4 color = textureLod(source_color, normal, params.camera_z_far); //the biggest the lod the least the acne +#else + vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne +#endif + imageStore(dest_buffer, pos + params.target, color); +#endif } diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl index 07f8d09743..b1cfe1e91e 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 VERSION_DEFINES layout(location = 0) out vec2 uv_interp; -/* clang-format on */ layout(push_constant, binding = 1, std430) uniform Params { vec4 section; @@ -20,7 +18,6 @@ layout(push_constant, binding = 1, std430) uniform Params { params; void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; @@ -36,8 +33,7 @@ void main() { } } -/* clang-format off */ -[fragment] +#[fragment] #version 450 @@ -52,18 +48,16 @@ layout(push_constant, binding = 1, std430) uniform Params { bool force_luminance; bool alpha_to_zero; uint pad[2]; -} params; - +} +params; layout(location = 0) in vec2 uv_interp; -/* clang-format on */ layout(set = 0, binding = 0) uniform sampler2D source_color; layout(location = 0) out vec4 frag_color; void main() { - vec2 uv = uv_interp; #ifdef MODE_PANORAMA_TO_DP @@ -83,8 +77,9 @@ void main() { vec2 st = vec2(atan(normal.x, normal.z), acos(normal.y)); - if (st.x < 0.0) + if (st.x < 0.0) { st.x += M_PI * 2.0; + } uv = st / vec2(M_PI * 2.0, M_PI); diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl index 02ebe1a53b..54d67db6c6 100644 --- a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform samplerCube source_cube; @@ -23,7 +21,6 @@ params; layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing return; diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl index 9f3ecf6053..7f269b7af3 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl @@ -18,8 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -28,7 +27,6 @@ VERSION_DEFINES #define BLOCK_SIZE 8 layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform samplerCube source_cubemap; @@ -46,26 +44,31 @@ void get_dir_0(out vec3 dir, in float u, in float v) { dir[1] = v; dir[2] = -u; } + void get_dir_1(out vec3 dir, in float u, in float v) { dir[0] = -1.0; dir[1] = v; dir[2] = u; } + void get_dir_2(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = 1.0; dir[2] = -v; } + void get_dir_3(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = -1.0; dir[2] = v; } + void get_dir_4(out vec3 dir, in float u, in float v) { dir[0] = u; dir[1] = v; dir[2] = 1.0; } + void get_dir_5(out vec3 dir, in float u, in float v) { dir[0] = -u; dir[1] = v; diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl index 193d0a8a3c..987545fb76 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl @@ -18,8 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -28,7 +27,6 @@ VERSION_DEFINES #define GROUP_SIZE 64 layout(local_size_x = GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform samplerCube source_cubemap; layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly imageCube dest_cubemap0; diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl index e85996fa1a..5cbb00baa4 100644 --- a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -8,7 +7,6 @@ VERSION_DEFINES #define GROUP_SIZE 8 layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform samplerCube source_cube; @@ -119,10 +117,8 @@ void main() { //vec4 color = color_interp; if (params.use_direct_write) { - imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0)); } else { - vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) { @@ -135,7 +131,6 @@ void main() { float ndotl = clamp(dot(N, L), 0.0, 1.0); if (ndotl > 0.0) { - sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl; sum.a += ndotl; } diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl index fd09f96a57..ea4237a45e 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -10,7 +9,6 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #else layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; #endif -/* clang-format on */ #ifndef MODE_DYNAMIC @@ -47,7 +45,6 @@ cell_data; #if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING) struct Light { - uint type; float energy; float radius; @@ -191,7 +188,6 @@ layout(r16ui, set = 0, binding = 13) uniform restrict writeonly uimage3D aniso_n #if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING) float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { - vec3 cell_size = 1.0 / vec3(params.limits); float occlusion = 1.0; while (distance > 0.5) { //use this to avoid precision errors @@ -213,14 +209,11 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { } bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) { - if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) { - light_pos = pos - lights.data[light].direction * length(vec3(params.limits)); attenuation = 1.0; } else { - light_pos = lights.data[light].position; float distance = length(pos - light_pos); if (distance >= lights.data[light].radius) { @@ -230,7 +223,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation); if (lights.data[light].type == LIGHT_TYPE_SPOT) { - vec3 rel = normalize(pos - light_pos); float angle = acos(dot(rel, lights.data[light].direction)); if (angle > lights.data[light].spot_angle_radians) { @@ -246,7 +238,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 } float get_normal_advance(vec3 p_normal) { - vec3 normal = p_normal; vec3 unorm = abs(normal); @@ -269,7 +260,6 @@ float get_normal_advance(vec3 p_normal) { } void clip_segment(vec4 plane, vec3 begin, inout vec3 end) { - vec3 segment = begin - end; float den = dot(plane.xyz, segment); @@ -302,7 +292,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i } if (lights.data[index].has_shadow) { - float distance_adv = get_normal_advance(light_dir); vec3 to = pos; @@ -352,7 +341,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i #endif // MODE COMPUTE LIGHT void main() { - #ifndef MODE_DYNAMIC uint cell_index = gl_GlobalInvocationID.x; @@ -383,7 +371,6 @@ void main() { #endif for (uint i = 0; i < params.light_count; i++) { - vec3 light; vec3 light_dir; if (!compute_light_at_pos(i, pos, normal.xyz, light, light_dir)) { @@ -394,7 +381,6 @@ void main() { #ifdef MODE_ANISOTROPIC for (uint j = 0; j < 6; j++) { - accum[j] += max(0.0, dot(accum_dirs[j], -light_dir)) * light; } #else @@ -461,7 +447,6 @@ void main() { #endif if (length(normal.xyz) > 0.2) { - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); vec3 tangent = normalize(cross(v0, normal.xyz)); vec3 bitangent = normalize(cross(tangent, normal.xyz)); @@ -481,11 +466,9 @@ void main() { float tan_half_angle = 0.577; for (int i = 0; i < MAX_CONE_DIRS; i++) { - vec3 direction = normal_mat * cone_dirs[i]; vec4 color = vec4(0.0); { - float dist = 1.5; float max_distance = length(vec3(params.limits)); vec3 cell_size = 1.0 / vec3(params.limits); @@ -519,7 +502,6 @@ void main() { color *= cone_weights[i] * vec4(albedo.rgb, 1.0) * params.dynamic_range; //restore range #ifdef MODE_ANISOTROPIC for (uint j = 0; j < 6; j++) { - accum[j] += max(0.0, dot(accum_dirs[j], direction)) * color.rgb; } #else @@ -594,7 +576,6 @@ void main() { #ifdef MODE_WRITE_TEXTURE { - #ifdef MODE_ANISOTROPIC vec3 accum_total = vec3(0.0); accum_total += outputs.data[cell_index * 6 + 0].rgb; @@ -665,7 +646,6 @@ void main() { vec3 accum = vec3(0.0); for (uint i = 0; i < params.light_count; i++) { - vec3 light; vec3 light_dir; if (!compute_light_at_pos(i, vec3(pos) * params.pos_multiplier, normal, light, light_dir)) { diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl index b1784e7eee..515cc35507 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 @@ -11,7 +10,6 @@ struct CellData { uint emission; //rgb normalized with e as multiplier uint normal; //RGB normal encoded }; -/* clang-format on */ layout(set = 0, binding = 1, std140) buffer CellDataBuffer { CellData data[]; @@ -28,7 +26,6 @@ layout(set = 0, binding = 5) uniform texture3D aniso_neg_tex; #endif layout(push_constant, binding = 0, std430) uniform Params { - mat4 projection; uint cell_offset; float dynamic_range; @@ -42,7 +39,6 @@ params; layout(location = 0) out vec4 color_interp; void main() { - const vec3 cube_triangles[36] = vec3[]( vec3(-1.0f, -1.0f, -1.0f), vec3(-1.0f, -1.0f, 1.0f), @@ -130,12 +126,24 @@ void main() { float strength = 0.0; switch (side) { - case POS_X: strength = aniso_pos.x; break; - case POS_Y: strength = aniso_pos.y; break; - case POS_Z: strength = aniso_pos.z; break; - case NEG_X: strength = aniso_neg.x; break; - case NEG_Y: strength = aniso_neg.y; break; - case NEG_Z: strength = aniso_neg.z; break; + case POS_X: + strength = aniso_pos.x; + break; + case POS_Y: + strength = aniso_pos.y; + break; + case POS_Z: + strength = aniso_pos.z; + break; + case NEG_X: + strength = aniso_neg.x; + break; + case NEG_Y: + strength = aniso_neg.y; + break; + case NEG_Z: + strength = aniso_neg.z; + break; } color_interp.xyz *= strength; @@ -160,19 +168,16 @@ void main() { #endif } -/* clang-format off */ -[fragment] +#[fragment] #version 450 VERSION_DEFINES layout(location = 0) in vec4 color_interp; -/* clang-format on */ layout(location = 0) out vec4 frag_color; void main() { - frag_color = color_interp; #ifdef MODE_DEBUG_LIGHT_FULL @@ -184,22 +189,38 @@ void main() { int index = x + y * 4; float limit = 0.0; if (x < 8) { - if (index == 0) limit = 0.0625; - if (index == 1) limit = 0.5625; - if (index == 2) limit = 0.1875; - if (index == 3) limit = 0.6875; - if (index == 4) limit = 0.8125; - if (index == 5) limit = 0.3125; - if (index == 6) limit = 0.9375; - if (index == 7) limit = 0.4375; - if (index == 8) limit = 0.25; - if (index == 9) limit = 0.75; - if (index == 10) limit = 0.125; - if (index == 11) limit = 0.625; - if (index == 12) limit = 1.0; - if (index == 13) limit = 0.5; - if (index == 14) limit = 0.875; - if (index == 15) limit = 0.375; + if (index == 0) + limit = 0.0625; + if (index == 1) + limit = 0.5625; + if (index == 2) + limit = 0.1875; + if (index == 3) + limit = 0.6875; + if (index == 4) + limit = 0.8125; + if (index == 5) + limit = 0.3125; + if (index == 6) + limit = 0.9375; + if (index == 7) + limit = 0.4375; + if (index == 8) + limit = 0.25; + if (index == 9) + limit = 0.75; + if (index == 10) + limit = 0.125; + if (index == 11) + limit = 0.625; + if (index == 12) + limit = 1.0; + if (index == 13) + limit = 0.5; + if (index == 14) + limit = 0.875; + if (index == 15) + limit = 0.375; } if (frag_color.a < limit) { discard; diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl index d089236723..5b3dec0ee7 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; -/* clang-format on */ #define MAX_DISTANCE 100000 @@ -45,7 +43,6 @@ layout(push_constant, binding = 0, std430) uniform Params { params; void main() { - vec3 pos = vec3(gl_GlobalInvocationID); float closest_dist = 100000.0; @@ -71,19 +68,17 @@ void main() { #if 0 layout(push_constant, binding = 0, std430) uniform Params { - ivec3 limits; uint stack_size; -} params; +} +params; float distance_to_aabb(ivec3 pos, ivec3 aabb_pos, ivec3 aabb_size) { - vec3 delta = vec3(max(ivec3(0), max(aabb_pos - pos, pos - (aabb_pos + aabb_size - ivec3(1))))); return length(delta); } void main() { - ivec3 pos = ivec3(gl_GlobalInvocationID); uint stack[10] = uint[](0, 0, 0, 0, 0, 0, 0, 0, 0, 0); @@ -107,7 +102,6 @@ void main() { int stack_pos = 0; while (true) { - uint index = stack_indices[stack_pos] >> 24; if (index == 8) { diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl index c832223b1e..9c794f1bcc 100644 --- a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; -/* clang-format on */ #define NO_CHILDREN 0xFFFFFFFF #define GREY_VEC vec3(0.33333, 0.33333, 0.33333) @@ -84,24 +82,20 @@ output; #ifdef MODE_COMPUTE_LIGHT uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { - uint result = NO_CHILDREN; ivec3 size = ivec3(max(max(params.limits.x, params.limits.y), params.limits.z)); while (distance > -distance_adv) { //use this to avoid precision errors - uint cell = 0; ivec3 pos = ivec3(from); if (all(greaterThanEqual(pos, ivec3(0))) && all(lessThan(pos, size))) { - ivec3 ofs = ivec3(0); ivec3 half_size = size / 2; for (int i = 0; i < params.stack_size - 1; i++) { - bvec3 greater = greaterThanEqual(pos, ofs + half_size); ofs += mix(ivec3(0), half_size, greater); @@ -118,8 +112,9 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { } cell = cell_children.data[cell].children[child]; - if (cell == NO_CHILDREN) + if (cell == NO_CHILDREN) { break; + } half_size >>= ivec3(1); } @@ -137,14 +132,10 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) { } bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation, out vec3 light_pos) { - if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) { - light_pos = pos - lights.data[light].direction * length(vec3(params.limits)); attenuation = 1.0; - } else { - light_pos = lights.data[light].position; float distance = length(pos - light_pos); if (distance >= lights.data[light].radius) { @@ -154,7 +145,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation); if (lights.data[light].type == LIGHT_TYPE_SPOT) { - vec3 rel = normalize(pos - light_pos); float angle = acos(dot(rel, lights.data[light].direction)); if (angle > lights.data[light].spot_angle_radians) { @@ -170,7 +160,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation } float get_normal_advance(vec3 p_normal) { - vec3 normal = p_normal; vec3 unorm = abs(normal); @@ -195,7 +184,6 @@ float get_normal_advance(vec3 p_normal) { #endif void main() { - uint cell_index = gl_GlobalInvocationID.x; if (cell_index >= params.cell_count) { return; @@ -220,7 +208,6 @@ void main() { #endif for (uint i = 0; i < params.light_count; i++) { - float attenuation; vec3 light_pos; @@ -237,7 +224,6 @@ void main() { } if (lights.data[i].has_shadow) { - float distance_adv = get_normal_advance(light_dir); distance += distance_adv - mod(distance, distance_adv); //make it reach the center of the box always diff --git a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl index 4bf5b7e7f1..8a11c35b78 100644 --- a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 @@ -8,7 +7,6 @@ VERSION_DEFINES #define BLOCK_SIZE 8 layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; -/* clang-format on */ shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE]; @@ -40,12 +38,10 @@ layout(push_constant, binding = 1, std430) uniform Params { params; void main() { - uint t = gl_LocalInvocationID.y * BLOCK_SIZE + gl_LocalInvocationID.x; ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(lessThan(pos, params.source_size))) { - #ifdef READ_TEXTURE vec3 v = texelFetch(source_texture, pos, 0).rgb; tmp_data[t] = max(v.r, max(v.g, v.b)); @@ -69,7 +65,6 @@ void main() { barrier(); size >>= 1; - } while (size >= 1); if (t == 0) { diff --git a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl index 3637b1abb2..464895928a 100644 --- a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform sampler2D source_normal; layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_roughness; @@ -21,7 +19,6 @@ params; #define HALF_PI 1.5707963267948966 void main() { - // Pixel being shaded ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing @@ -53,14 +50,14 @@ void main() { float kappa = (3.0f * r - r * r2) / (1.0f - r2); float variance = 0.25f / kappa; limit = sqrt(min(2.0f * variance, threshold * threshold)); -//*/ + */ /* //Formula based on probability distribution graph float width = acos(max(0.0,r)); // convert to angle (width) float roughness = pow(width,1.7)*0.854492; //approximate (crappy) formula to convert to roughness limit = min(sqrt(roughness), threshold); //convert to perceptual roughness and apply threshold -//*/ + */ limit = min(sqrt(pow(acos(max(0.0, r)) / HALF_PI, params.curve)), threshold); //convert to perceptual roughness and apply threshold diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl index ec47887036..9f42b0f814 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl @@ -1,5 +1,4 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 @@ -10,7 +9,6 @@ VERSION_DEFINES /* INPUT ATTRIBS */ layout(location = 0) in vec3 vertex_attrib; -/* clang-format on */ layout(location = 1) in vec3 normal_attrib; #if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED) layout(location = 2) in vec4 tangent_attrib; @@ -22,7 +20,7 @@ layout(location = 3) in vec4 color_attrib; layout(location = 4) in vec2 uv_attrib; -#if defined(UV2_USED) || defined(USE_LIGHTMAP) +#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(MODE_RENDER_MATERIAL) layout(location = 5) in vec2 uv2_attrib; #endif @@ -49,7 +47,7 @@ layout(location = 6) out vec3 binormal_interp; #endif #ifdef USE_MATERIAL_UNIFORMS -layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ +layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ MATERIAL_UNIFORMS /* clang-format on */ @@ -62,8 +60,6 @@ VERTEX_SHADER_GLOBALS /* clang-format on */ -// FIXME: This triggers a Mesa bug that breaks rendering, so disabled for now. -// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316 invariant gl_Position; layout(location = 7) flat out uint instance_index; @@ -75,7 +71,6 @@ layout(location = 8) out float dp_clip; #endif void main() { - instance_index = draw_call.instance_index; vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) @@ -263,10 +258,17 @@ VERTEX_SHADER_CODE } } #endif + +#ifdef MODE_RENDER_MATERIAL + if (scene_data.material_uv2_mode) { + gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0; + gl_Position.z = 0.00001; + gl_Position.w = 1.0; + } +#endif } -/* clang-format off */ -[fragment] +#[fragment] #version 450 @@ -277,7 +279,6 @@ VERSION_DEFINES /* Varyings */ layout(location = 0) in vec3 vertex_interp; -/* clang-format on */ layout(location = 1) in vec3 normal_interp; #if defined(COLOR_USED) @@ -315,7 +316,7 @@ layout(location = 8) in float dp_clip; #endif #ifdef USE_MATERIAL_UNIFORMS -layout(set = 5, binding = 0, std140) uniform MaterialUniforms{ +layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ /* clang-format off */ MATERIAL_UNIFORMS /* clang-format on */ @@ -420,7 +421,8 @@ float SchlickFresnel(float u) { } float GTR1(float NdotH, float a) { - if (a >= 1.0) return 1.0 / M_PI; + if (a >= 1.0) + return 1.0 / M_PI; float a2 = a * a; float t = 1.0 + (a2 - 1.0) * NdotH * NdotH; return (a2 - 1.0) / (M_PI * log(a2) * t); @@ -684,7 +686,6 @@ float quick_hash(vec2 pos) { } float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - vec2 pos = coord.xy; float depth = coord.z; @@ -711,7 +712,6 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve } float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { - vec2 pos = coord.xy; float depth = coord.z; @@ -738,7 +738,6 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) { } float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) { - //find blocker float blocker_count = 0.0; float blocker_average = 0.0; @@ -752,7 +751,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex } for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) { - vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale; float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; if (d < pssm_coord.z) { @@ -762,7 +760,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (pssm_coord.z - blocker_average) / blocker_average; @@ -820,7 +817,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float size_A = 0.0; if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } @@ -874,7 +870,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; @@ -883,11 +878,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 uv_rect = lights.data[idx].atlas_rect; if (pos.z >= 0.0) { - pos.z += 1.0; uv_rect.y += uv_rect.w; } else { - pos.z = 1.0 - pos.z; } @@ -904,7 +897,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (z_norm - blocker_average) / blocker_average; @@ -915,7 +907,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 0.0; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy; vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y; @@ -923,11 +914,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 uv_rect = lights.data[idx].atlas_rect; if (pos.z >= 0.0) { - pos.z += 1.0; uv_rect.y += uv_rect.w; } else { - pos.z = 1.0 - pos.z; } @@ -945,12 +934,10 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v shadow = 1.0; } } else { - splane.xyz = normalize(splane.xyz); vec4 clamp_rect = lights.data[idx].atlas_rect; if (splane.z >= 0.0) { - splane.z += 1.0; clamp_rect.y += clamp_rect.w; @@ -970,7 +957,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED { - vec4 clamp_rect = lights.data[idx].atlas_rect; //redo shadowmapping, but shrink the model a bit to avoid arctifacts @@ -980,11 +966,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v splane = normalize(splane.xyz); if (splane.z >= 0.0) { - splane.z += 1.0; } else { - splane.z = 1.0 - splane.z; } @@ -1002,19 +986,16 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 no_shadow = vec3(1.0); if (lights.data[idx].projector_rect != vec4(0.0)) { - vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz; local_v = normalize(local_v); vec4 atlas_rect = lights.data[idx].projector_rect; if (local_v.z >= 0.0) { - local_v.z += 1.0; atlas_rect.y += atlas_rect.w; } else { - local_v.z = 1.0 - local_v.z; } @@ -1029,10 +1010,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v local_v_ddx = normalize(local_v_ddx); if (local_v_ddx.z >= 0.0) { - local_v_ddx.z += 1.0; } else { - local_v_ddx.z = 1.0 - local_v_ddx.z; } @@ -1045,10 +1024,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v local_v_ddy = normalize(local_v_ddy); if (local_v_ddy.z >= 0.0) { - local_v_ddy.z += 1.0; } else { - local_v_ddy.z = 1.0 - local_v_ddy.z; } @@ -1136,7 +1113,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float size_A = 0.0; if (lights.data[idx].size > 0.0) { - float t = lights.data[idx].size / max(0.001, light_length); size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t)); } @@ -1193,7 +1169,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale; vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw; for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) { - vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size; suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max); float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r; @@ -1204,7 +1179,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } if (blocker_count > 0.0) { - //blockers found, do soft shadow blocker_average /= blocker_count; float penumbra = (z_norm - blocker_average) / blocker_average; @@ -1234,7 +1208,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec3 no_shadow = vec3(1.0); if (lights.data[idx].projector_rect != vec4(0.0)) { - splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); splane /= splane.w; @@ -1257,7 +1230,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED { - splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0)); splane /= splane.w; splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy; @@ -1301,7 +1273,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v } void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) { - vec3 box_extents = reflections.data[ref_index].box_extents; vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz; @@ -1368,7 +1339,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes ambient_out.rgb *= ambient_out.a; ambient_accum += ambient_out; } else { - vec4 ambient_out; ambient_out.a = blend; ambient_out.rgb = reflections.data[ref_index].ambient.rgb; @@ -1385,7 +1355,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes //standard voxel cone trace vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); @@ -1412,7 +1381,6 @@ vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, #ifdef GI_PROBE_USE_ANISOTROPY vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); float radius = max(0.5, tan_half_angle * dist); @@ -1444,7 +1412,6 @@ vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_po #else vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); float radius = max(0.5, tan_half_angle * dist); @@ -1476,7 +1443,6 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 //standard voxel cone trace vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) { - float dist = p_bias; vec4 color = vec4(0.0); @@ -1507,7 +1473,6 @@ vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3 #endif void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) { - position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz; ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz); normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz); @@ -1568,7 +1533,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 vec3 light = vec3(0.0); for (int i = 0; i < MAX_CONE_DIRS; i++) { - vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz); #if defined(GI_PROBE_HIGH_QUALITY) || defined(GI_PROBE_LOW_QUALITY) @@ -1600,7 +1564,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 light *= gi_probes.data[index].dynamic_range; if (gi_probes.data[index].ambient_occlusion > 0.001) { - float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0; float taps, blend; @@ -1641,7 +1604,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) void main() { - #ifdef MODE_DUAL_PARABOLOID if (dp_clip > 0.0) @@ -1793,7 +1755,6 @@ FRAGMENT_SHADER_CODE //do outside for performance and avoiding arctifacts for (uint i = 0; i < decal_count; i++) { - uint decal_index = cluster_data.indices[decal_pointer + i]; if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked @@ -1822,7 +1783,6 @@ FRAGMENT_SHADER_CODE albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); if (decals.data[decal_index].normal_rect != vec4(0.0)) { - vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); @@ -1833,7 +1793,6 @@ FRAGMENT_SHADER_CODE } if (decals.data[decal_index].orm_rect != vec4(0.0)) { - vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; #if defined(AO_USED) ao = mix(ao, decal_orm.r, decal_albedo.a); @@ -1867,7 +1826,6 @@ FRAGMENT_SHADER_CODE } if (scene_data.use_reflection_cubemap) { - vec3 ref_vec = reflect(-view, normal); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -1887,7 +1845,6 @@ FRAGMENT_SHADER_CODE #ifndef USE_LIGHTMAP //lightmap overrides everything if (scene_data.use_ambient_light) { - ambient_light = scene_data.ambient_light_color_energy.rgb; if (scene_data.use_ambient_cubemap) { @@ -1916,42 +1873,95 @@ FRAGMENT_SHADER_CODE #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //gi probes +#ifdef USE_LIGHTMAP + //lightmap + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture + uint index = instances.data[instance_index].gi_offset; + + vec3 wnormal = mat3(scene_data.camera_matrix) * normal; + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + ambient_light += (c1 * lightmap_captures.data[index].sh[8].rgb * (wnormal.x * wnormal.x - wnormal.y * wnormal.y) + + c3 * lightmap_captures.data[index].sh[6].rgb * wnormal.z * wnormal.z + + c4 * lightmap_captures.data[index].sh[0].rgb - + c5 * lightmap_captures.data[index].sh[6].rgb + + 2.0 * c1 * lightmap_captures.data[index].sh[4].rgb * wnormal.x * wnormal.y + + 2.0 * c1 * lightmap_captures.data[index].sh[7].rgb * wnormal.x * wnormal.z + + 2.0 * c1 * lightmap_captures.data[index].sh[5].rgb * wnormal.y * wnormal.z + + 2.0 * c2 * lightmap_captures.data[index].sh[3].rgb * wnormal.x + + 2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y + + 2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z); + + } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap + bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP); + uint ofs = instances.data[instance_index].gi_offset & 0xFFF; + vec3 uvw; + uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy; + uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF); + + if (uses_sh) { + uvw.z *= 4.0; //SH textures use 4 times more data + vec3 lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb; + vec3 lm_light_l1n1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb; + vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb; + vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb; + + uint idx = instances.data[instance_index].gi_offset >> 20; + vec3 n = normalize(lightmaps.data[idx].normal_xform * normal); + + ambient_light += lm_light_l0 * 0.282095f; + ambient_light += lm_light_l1n1 * 0.32573 * n.y; + ambient_light += lm_light_l1_0 * 0.32573 * n.z; + ambient_light += lm_light_l1p1 * 0.32573 * n.x; + if (metallic > 0.01) { // since the more direct bounced light is lost, we can kind of fake it with this trick + vec3 r = reflect(normalize(-vertex), normal); + specular_light += lm_light_l1n1 * 0.32573 * r.y; + specular_light += lm_light_l1_0 * 0.32573 * r.z; + specular_light += lm_light_l1p1 * 0.32573 * r.x; + } + } else { + ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw, 0.0).rgb; + } + } +#endif //lightmap capture #ifdef USE_VOXEL_CONE_TRACING - { // process giprobes - uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; - if (index1 != 0xFFFF) { - vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); - //find arbitrary tangent and bitangent, then build a matrix - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); - vec3 tangent = normalize(cross(v0, normal)); - vec3 bitangent = normalize(cross(tangent, normal)); - mat3 normal_mat = mat3(tangent, bitangent, normal); + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes - vec4 amb_accum = vec4(0.0); - vec4 spec_accum = vec4(0.0); - gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; + vec3 ref_vec = normalize(reflect(normalize(vertex), normal)); + //find arbitrary tangent and bitangent, then build a matrix + vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, normal)); + vec3 bitangent = normalize(cross(tangent, normal)); + mat3 normal_mat = mat3(tangent, bitangent, normal); - uint index2 = instances.data[instance_index].gi_offset >> 16; + vec4 amb_accum = vec4(0.0); + vec4 spec_accum = vec4(0.0); + gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - if (index2 != 0xFFFF) { - gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); - } + uint index2 = instances.data[instance_index].gi_offset >> 16; - if (amb_accum.a > 0.0) { - amb_accum.rgb /= amb_accum.a; - } + if (index2 != 0xFFFF) { + gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + } - if (spec_accum.a > 0.0) { - spec_accum.rgb /= spec_accum.a; - } + if (amb_accum.a > 0.0) { + amb_accum.rgb /= amb_accum.a; + } - specular_light = spec_accum.rgb; - ambient_light = amb_accum.rgb; + if (spec_accum.a > 0.0) { + spec_accum.rgb /= spec_accum.a; } + + specular_light = spec_accum.rgb; + ambient_light = amb_accum.rgb; } #endif @@ -1964,7 +1974,6 @@ FRAGMENT_SHADER_CODE uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK; for (uint i = 0; i < reflection_probe_count; i++) { - uint ref_index = cluster_data.indices[reflection_probe_pointer + i]; reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } @@ -1981,7 +1990,6 @@ FRAGMENT_SHADER_CODE } { - #if defined(DIFFUSE_TOON) //simplify for toon, as specular_light *= specular * metallic * albedo * 2.0; @@ -2006,7 +2014,6 @@ FRAGMENT_SHADER_CODE { //directional light for (uint i = 0; i < scene_data.directional_light_count; i++) { - if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } @@ -2066,7 +2073,6 @@ FRAGMENT_SHADER_CODE } #endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 1) @@ -2099,7 +2105,6 @@ FRAGMENT_SHADER_CODE } #endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -2133,7 +2138,6 @@ FRAGMENT_SHADER_CODE #endif } else { - vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -2169,7 +2173,6 @@ FRAGMENT_SHADER_CODE } if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); float pssm_blend; float shadow2; @@ -2279,7 +2282,6 @@ FRAGMENT_SHADER_CODE uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK; for (uint i = 0; i < omni_light_count; i++) { - uint light_index = cluster_data.indices[omni_light_pointer + i]; if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { @@ -2318,7 +2320,6 @@ FRAGMENT_SHADER_CODE uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK; for (uint i = 0; i < spot_light_count; i++) { - uint light_index = cluster_data.indices[spot_light_pointer + i]; if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { @@ -2423,7 +2424,6 @@ FRAGMENT_SHADER_CODE ao_light_affect = mix(1.0, ao, ao_light_affect); specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect); diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect); - #else if (scene_data.ssao_enabled) { diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl index ce4fabf9f2..1cac12406a 100644 --- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl +++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl @@ -3,7 +3,8 @@ layout(push_constant, binding = 0, std430) uniform DrawCall { uint instance_index; - uint pad[3]; //16 bits minimum size + uint pad; //16 bits minimum size + vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise } draw_call; @@ -27,7 +28,6 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12]; layout(set = 0, binding = 2) uniform sampler shadow_sampler; layout(set = 0, binding = 3, std140) uniform SceneData { - mat4 projection_matrix; mat4 inv_projection_matrix; @@ -77,6 +77,10 @@ layout(set = 0, binding = 3, std140) uniform SceneData { bool roughness_limiter_enabled; vec4 ao_color; + bool material_uv2_mode; + uint pad_material0; + uint pad_material1; + uint pad_material2; #if 0 vec4 ambient_light_color; @@ -113,13 +117,13 @@ layout(set = 0, binding = 3, std140) uniform SceneData { float fog_height_curve; #endif } -scene_data; -#define INSTANCE_FLAGS_FORWARD_MASK 0x7 -#define INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT 3 -#define INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT 6 -#define INSTANCE_FLAGS_FORWARD_DECAL_SHIFT 9 +scene_data; +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) +#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) @@ -135,8 +139,9 @@ struct InstanceData { mat4 normal_transform; uint flags; uint instance_uniforms_ofs; //base offset in global buffer for instance variables - uint gi_offset; //GI information when using lightmapping (VCT or lightmap) + uint gi_offset; //GI information when using lightmapping (VCT or lightmap index) uint layer_mask; + vec4 lightmap_uv_scale; }; layout(set = 0, binding = 4, std430) restrict readonly buffer Instances { @@ -171,7 +176,6 @@ layout(set = 0, binding = 5, std430) restrict readonly buffer Lights { lights; struct ReflectionData { - vec3 box_extents; float index; vec3 box_offset; @@ -248,12 +252,35 @@ gi_probes; layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TEXTURES]; +#define LIGHTMAP_FLAG_USE_DIRECTION 1 +#define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2 + +struct Lightmap { + mat3 normal_xform; +}; + +layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps { + Lightmap data[]; +} +lightmaps; + +layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; + +struct LightmapCapture { + vec4 sh[9]; +}; + +layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures { + LightmapCapture data[]; +} +lightmap_captures; + #define CLUSTER_COUNTER_SHIFT 20 #define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1) #define CLUSTER_COUNTER_MASK 0xfff -layout(set = 0, binding = 10) uniform texture2D decal_atlas; -layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 13) uniform texture2D decal_atlas; +layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb; struct DecalData { mat4 xform; //to decal transform @@ -273,21 +300,21 @@ struct DecalData { float normal_fade; }; -layout(set = 0, binding = 12, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 15, std430) restrict readonly buffer Decals { DecalData data[]; } decals; -layout(set = 0, binding = 13) uniform utexture3D cluster_texture; +layout(set = 0, binding = 16) uniform utexture3D cluster_texture; -layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData { +layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData { uint indices[]; } cluster_data; -layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas; +layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas; -layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } global_variables; @@ -312,7 +339,7 @@ layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas; layout(set = 2, binding = 1) uniform texture2D shadow_atlas; -/* Set 1, Render Buffers */ +/* Set 3, Render Buffers */ layout(set = 3, binding = 0) uniform texture2D depth_buffer; layout(set = 3, binding = 1) uniform texture2D color_buffer; diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl index e3c26c9b72..084f28d932 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl @@ -1,16 +1,11 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES - - layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ - layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_diffuse; layout(r32f, set = 0, binding = 1) uniform restrict readonly image2D source_depth; layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D ssr_image; @@ -24,7 +19,6 @@ layout(set = 3, binding = 1) uniform sampler2D source_roughness; #endif layout(push_constant, binding = 2, std430) uniform Params { - vec4 proj_info; ivec2 screen_size; @@ -64,11 +58,10 @@ vec3 reconstructCSPosition(vec2 S, float z) { } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -156,7 +149,6 @@ void main() { float steps_taken = 0.0; for (int i = 0; i < params.num_steps; i++) { - pos += line_advance; z += z_advance; w += w_advance; @@ -187,7 +179,6 @@ void main() { } if (found) { - float margin_blend = 1.0; vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin @@ -220,7 +211,6 @@ void main() { float roughness = texelFetch(source_roughness, ssC << 1, 0).r; if (roughness > 0.001) { - float cone_angle = min(roughness, 0.999) * M_PI * 0.5; float cone_len = length(final_pos - line_begin); float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl index 1a5dd5ab55..a5afe74cb2 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl @@ -1,16 +1,11 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES - - layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ - layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_ssr; layout(r8, set = 0, binding = 1) uniform restrict readonly image2D source_radius; layout(rgba8, set = 1, binding = 0) uniform restrict readonly image2D source_normal; @@ -22,7 +17,6 @@ layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius; layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth; layout(push_constant, binding = 2, std430) uniform Params { - vec4 proj_info; bool orthogonal; @@ -58,7 +52,6 @@ const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[]( ); float gauss_weight(float p_val) { - float idxf; float c = modf(max(0.0, p_val * float(GAUSS_TABLE_SIZE)), idxf); int idx = int(idxf); @@ -80,7 +73,6 @@ vec3 reconstructCSPosition(vec2 S, float z) { } void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) { - for (int i = 1; i < params.steps; i++) { float d = float(i * params.increment); ivec2 tc = texcoord + increment * i; @@ -104,7 +96,6 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, } if (d < radius) { - float w = gauss_weight(d / radius); accum += imageLoad(source_ssr, tc) * w; #ifndef VERTICAL_PASS @@ -116,11 +107,10 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl index cec6c14c76..218605a962 100644 --- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl @@ -1,15 +1,11 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES - layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ - layout(set = 0, binding = 0) uniform sampler2D source_ssr; layout(set = 1, binding = 0) uniform sampler2D source_depth; layout(set = 1, binding = 1) uniform sampler2D source_normal; @@ -18,7 +14,6 @@ layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal; layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; float camera_z_near; float camera_z_far; @@ -30,11 +25,10 @@ layout(push_constant, binding = 1, std430) uniform Params { params; void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } //do not filter, SSR will generate arctifacts if this is done @@ -45,13 +39,11 @@ void main() { vec3 normal; if (params.filtered) { - color = vec4(0.0); depth = 0.0; normal = vec3(0.0); for (int i = 0; i < 4; i++) { - ivec2 ofs = ssC << 1; if (bool(i & 1)) { ofs.x += 1; @@ -75,7 +67,6 @@ void main() { color /= 4.0; depth /= 4.0; normal = normalize(normal / 4.0) * 0.5 + 0.5; - } else { color = texelFetch(source_ssr, ssC << 1, 0); depth = texelFetch(source_depth, ssC << 1, 0).r; diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl index 536077980d..9c59be6841 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 VERSION_DEFINES layout(location = 0) out vec2 uv_interp; -/* clang-format on */ layout(push_constant, binding = 1, std430) uniform Params { mat3 orientation; @@ -17,14 +15,12 @@ layout(push_constant, binding = 1, std430) uniform Params { params; void main() { - vec2 base_arr[4] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0), vec2(1.0, -1.0)); uv_interp = base_arr[gl_VertexIndex]; gl_Position = vec4(uv_interp, 1.0, 1.0); } -/* clang-format off */ -[fragment] +#[fragment] #version 450 @@ -33,7 +29,6 @@ VERSION_DEFINES #define M_PI 3.14159265359 layout(location = 0) in vec2 uv_interp; -/* clang-format on */ layout(push_constant, binding = 1, std430) uniform Params { mat3 orientation; @@ -109,6 +104,7 @@ struct DirectionalLightData { layout(set = 3, binding = 0, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } + directional_lights; /* clang-format off */ @@ -120,7 +116,6 @@ FRAGMENT_SHADER_GLOBALS layout(location = 0) out vec4 frag_color; void main() { - vec3 cube_normal; cube_normal.z = -1.0; cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y; diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl index b28250318e..0b8f406213 100644 --- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl +++ b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl @@ -1,30 +1,25 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 VERSION_DEFINES layout(location = 0) out vec2 uv_interp; -/* clang-format on */ void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); } -/* clang-format off */ -[fragment] +#[fragment] #version 450 VERSION_DEFINES layout(location = 0) in vec2 uv_interp; -/* clang-format on */ layout(set = 0, binding = 0) uniform sampler2D specular; @@ -43,13 +38,12 @@ layout(set = 2, binding = 0) uniform sampler2D diffuse; layout(location = 0) out vec4 frag_color; void main() { - frag_color.rgb = texture(specular, uv_interp).rgb; frag_color.a = 0.0; #ifdef MODE_SSR - vec4 ssr = texture(ssr, uv_interp); - frag_color.rgb = mix(frag_color.rgb, ssr.rgb, ssr.a); + vec4 ssr_color = texture(ssr, uv_interp); + frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a); #endif #ifdef MODE_MERGE diff --git a/servers/rendering/rasterizer_rd/shaders/ssao.glsl b/servers/rendering/rasterizer_rd/shaders/ssao.glsl index c9d7134610..346338181a 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ #define TWO_PI 6.283185307179586476925286766559 @@ -49,7 +47,6 @@ const int ROTATIONS[] = int[]( 29, 21, 19, 27, 31, 29, 21, 18, 17, 29, 31, 31, 23, 18, 25, 26, 25, 23, 19, 34, 19, 27, 21, 25, 39, 29, 17, 21, 27); -/* clang-format on */ //#define NUM_SPIRAL_TURNS (7) const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1]; @@ -212,7 +209,7 @@ float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in f void main() { // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl index e90c788e08..3e63e3cb59 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ layout(set = 0, binding = 0) uniform sampler2D source_ssao; layout(set = 1, binding = 0) uniform sampler2D source_depth; @@ -46,10 +44,9 @@ const float gaussian[R + 1] = //float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -122,7 +119,6 @@ void main() { // We already handled the zero case above. This loop should be unrolled and the static branch optimized out, // so the IF statement has no runtime cost if (r != 0) { - ivec2 ppos = ssC + params.axis * (r * params.filter_scale); float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r; ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit); diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl index 8728154347..263fca386f 100644 --- a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl +++ b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl @@ -1,12 +1,10 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ layout(push_constant, binding = 1, std430) uniform Params { vec2 pixel_size; @@ -26,7 +24,6 @@ layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_imag layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_image; void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThan(pos, params.source_size >> 1))) { //too large, do nothing diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl index 41f8fde3ca..88a953562f 100644 --- a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl +++ b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl @@ -1,16 +1,11 @@ -/* clang-format off */ -[compute] +#[compute] #version 450 VERSION_DEFINES - - layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -/* clang-format on */ - #ifdef USE_25_SAMPLES const int kernel_size = 13; @@ -93,7 +88,6 @@ const vec4 skin_kernel[kernel_size] = vec4[]( #endif //USE_11_SAMPLES layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; float camera_z_far; float camera_z_near; @@ -113,7 +107,6 @@ layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D dest_im layout(set = 2, binding = 0) uniform sampler2D source_depth; void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, bool p_skin) { - // Accumulate the other samples: for (int i = 1; i < kernel_size; i++) { // Fetch color and depth for current sample: @@ -138,11 +131,10 @@ void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, b } void main() { - // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing return; } @@ -153,7 +145,6 @@ void main() { float strength = abs(base_color.a); if (strength > 0.0) { - vec2 dir = params.vertical ? vec2(0.0, 1.0) : vec2(1.0, 0.0); // Fetch linear depth of current pixel: diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl index a142d263e2..b7c46a7d0e 100644 --- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl +++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl @@ -1,29 +1,24 @@ -/* clang-format off */ -[vertex] +#[vertex] #version 450 VERSION_DEFINES layout(location = 0) out vec2 uv_interp; -/* clang-format on */ void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); } -/* clang-format off */ -[fragment] +#[fragment] #version 450 VERSION_DEFINES layout(location = 0) in vec2 uv_interp; -/* clang-format on */ layout(set = 0, binding = 0) uniform sampler2D source_color; layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; @@ -260,7 +255,6 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) { } vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { - const float FXAA_REDUCE_MIN = (1.0 / 128.0); const float FXAA_REDUCE_MUL = (1.0 / 8.0); const float FXAA_SPAN_MAX = 8.0; @@ -298,10 +292,11 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) { textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz * exposure); float lumaB = dot(rgbB, luma); - if ((lumaB < lumaMin) || (lumaB > lumaMax)) + if ((lumaB < lumaMin) || (lumaB > lumaMax)) { return rgbA; - else + } else { return rgbB; + } } void main() { @@ -320,7 +315,6 @@ void main() { // Early Tonemap & SRGB Conversion if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) { - vec3 glow = gather_glow(source_glow, uv_interp); color.rgb = mix(color.rgb, glow, params.glow_intensity); } @@ -335,7 +329,6 @@ void main() { // Glow if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) { - vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity; // high dynamic range -> SRGB diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 75ef38354a..55b65d2747 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "rendering_device.h" +#include "core/method_bind_ext.gen.inc" +#include "rendering_device_binds.h" RenderingDevice *RenderingDevice::singleton = nullptr; @@ -42,6 +44,7 @@ RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr; void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) { compile_function = p_function; } + void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) { cache_function = p_function; } @@ -59,6 +62,741 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage, return compile_function(p_stage, p_source_code, p_language, r_error); } +RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) { + ERR_FAIL_COND_V(p_format.is_null(), RID()); + ERR_FAIL_COND_V(p_view.is_null(), RID()); + Vector<Vector<uint8_t>> data; + for (int i = 0; i < p_data.size(); i++) { + Vector<uint8_t> byte_slice = p_data[i]; + ERR_FAIL_COND_V(byte_slice.empty(), RID()); + data.push_back(byte_slice); + } + return texture_create(p_format->base, p_view->base, data); +} + +RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared(p_view->base, p_with_texture); +} + +RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) { + ERR_FAIL_COND_V(p_view.is_null(), RID()); + + return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type); +} + +RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) { + Vector<AttachmentFormat> attachments; + attachments.resize(p_attachments.size()); + + for (int i = 0; i < p_attachments.size(); i++) { + Ref<RDAttachmentFormat> af = p_attachments[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + attachments.write[i] = af->base; + } + return framebuffer_format_create(attachments); +} + +RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) { + Vector<RID> textures = Variant(p_textures); + return framebuffer_create(textures, p_format_check); +} + +RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) { + ERR_FAIL_COND_V(p_state.is_null(), RID()); + + return sampler_create(p_state->base); +} + +RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) { + Vector<VertexAttribute> descriptions; + descriptions.resize(p_vertex_formats.size()); + + for (int i = 0; i < p_vertex_formats.size(); i++) { + Ref<RDVertexAttribute> af = p_vertex_formats[i]; + ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID); + descriptions.write[i] = af->base; + } + return vertex_format_create(descriptions); +} + +RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) { + Vector<RID> buffers = Variant(p_src_buffers); + + return vertex_array_create(p_vertex_count, p_vertex_format, buffers); +} + +Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) { + ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>()); + + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error; + + ShaderStage stage = ShaderStage(i); + Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache); + bytecode->set_stage_bytecode(stage, spirv); + bytecode->set_stage_compile_error(stage, error); + } + return bytecode; +} + +RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode) { + ERR_FAIL_COND_V(p_bytecode.is_null(), RID()); + + Vector<ShaderStageData> stage_data; + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + ShaderStage stage = ShaderStage(i); + ShaderStageData sd; + sd.shader_stage = stage; + String error = p_bytecode->get_stage_compile_error(stage); + ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode."); + sd.spir_v = p_bytecode->get_stage_bytecode(stage); + if (sd.spir_v.empty()) { + continue; + } + stage_data.push_back(sd); + } + + return shader_create(stage_data); +} + +RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) { + Vector<Uniform> uniforms; + uniforms.resize(p_uniforms.size()); + for (int i = 0; i < p_uniforms.size(); i++) { + Ref<RDUniform> uniform = p_uniforms[i]; + ERR_FAIL_COND_V(!uniform.is_valid(), RID()); + uniforms.write[i] = uniform->base; + } + return uniform_set_create(uniforms, p_shader, p_shader_set); +} + +Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) { + return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw); +} + +RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) { + PipelineRasterizationState rasterization_state; + if (p_rasterization_state.is_valid()) { + rasterization_state = p_rasterization_state->base; + } + + PipelineMultisampleState multisample_state; + if (p_multisample_state.is_valid()) { + multisample_state = p_multisample_state->base; + for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) { + int64_t mask = p_multisample_state->sample_masks[i]; + multisample_state.sample_mask.push_back(mask); + } + } + + PipelineDepthStencilState depth_stencil_state; + if (p_depth_stencil_state.is_valid()) { + depth_stencil_state = p_depth_stencil_state->base; + } + + PipelineColorBlendState color_blend_state; + if (p_blend_state.is_valid()) { + color_blend_state = p_blend_state->base; + for (int i = 0; i < p_blend_state->attachments.size(); i++) { + Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i]; + if (attachment.is_valid()) { + color_blend_state.attachments.push_back(attachment->base); + } + } + } + + return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags); +} + +Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) { + Vector<DrawListID> splits; + splits.resize(p_splits); + draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region); + + Vector<int64_t> split_ids; + split_ids.resize(splits.size()); + for (int i = 0; i < splits.size(); i++) { + split_ids.write[i] = splits[i]; + } + + return split_ids; +} + +void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) { + ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size); + compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size); +} + +void RenderingDevice::_bind_methods() { + ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared); + ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D)); + + ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data); + + ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage); + + ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared); + ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid); + + ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create); + ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples); + ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID)); + ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format); + + ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create); + + ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create); + + ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create); + + ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::shader_create_from_bytecode); + ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask); + + ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>())); + ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>())); + + ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create); + ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid); + + ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data); + + ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0)); + ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create); + ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid); + + ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format); + + ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color())); + + ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i())); + + ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline); + ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array); + ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array); + ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant); + + ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i())); + ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor); + + ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end); + + ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin); + ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline); + ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant); + ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set); + ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch); + ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier); + ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end); + + ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free); + + ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count); + ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time); + ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name); + + ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get); + ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay); + ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit); + ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync); + + ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device); + + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8); + BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT); + BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG); + BIND_ENUM_CONSTANT(DATA_FORMAT_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY); + BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64); + BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT); + BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT); + + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A); + BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP); + BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D); + + BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST); + BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE); + BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX); + + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE); + BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX); + + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX); + BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE); + + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16); + BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32); + + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type) + BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO). + BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly + BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX); + + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH); + BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX); + + BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED); + BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT); + BIND_ENUM_CONSTANT(POLYGON_CULL_BACK); + + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE); + BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE); + + BIND_ENUM_CONSTANT(STENCIL_OP_KEEP); + BIND_ENUM_CONSTANT(STENCIL_OP_ZERO); + BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP); + BIND_ENUM_CONSTANT(STENCIL_OP_INVERT); + BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP); + BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(COMPARE_OP_NEVER); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS); + BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER); + BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL); + BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS); + BIND_ENUM_CONSTANT(COMPARE_OP_MAX); + + BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR); + BIND_ENUM_CONSTANT(LOGIC_OP_AND); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY); + BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP); + BIND_ENUM_CONSTANT(LOGIC_OP_XOR); + BIND_ENUM_CONSTANT(LOGIC_OP_OR); + BIND_ENUM_CONSTANT(LOGIC_OP_NOR); + BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT); + BIND_ENUM_CONSTANT(LOGIC_OP_INVERT); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE); + BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED); + BIND_ENUM_CONSTANT(LOGIC_OP_NAND); + BIND_ENUM_CONSTANT(LOGIC_OP_SET); + BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D + + BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR); + BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA); + BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX); + + BIND_ENUM_CONSTANT(BLEND_OP_ADD); + BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT); + BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM); + BIND_ENUM_CONSTANT(BLEND_OP_MAX); + + BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK); + BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); + + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) + BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it + BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) + BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from) + BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering + BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish" + BIND_ENUM_CONSTANT(FINAL_ACTION_MAX); + + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE); + BIND_ENUM_CONSTANT(SHADER_STAGE_MAX); + BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT); + BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT); + + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL); + BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL); + + BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET); + BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT); + BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE); + BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE); + BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS); + BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE); + BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y); + BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z); + + BIND_CONSTANT(INVALID_ID); + BIND_CONSTANT(INVALID_FORMAT_ID); +} + RenderingDevice::RenderingDevice() { if (singleton == nullptr) { // there may be more rendering devices later singleton = this; diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 6c58b8fd57..ee39ee11ed 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -32,8 +32,22 @@ #define RENDERING_DEVICE_H #include "core/object.h" +#include "core/typed_array.h" #include "servers/display_server.h" +class RDTextureFormat; +class RDTextureView; +class RDAttachmentFormat; +class RDSamplerState; +class RDVertexAttribute; +class RDShaderSource; +class RDShaderBytecode; +class RDUniforms; +class RDPipelineRasterizationState; +class RDPipelineMultisampleState; +class RDPipelineDepthStencilState; +class RDPipelineColorBlendState; + class RenderingDevice : public Object { GDCLASS(RenderingDevice, Object) public: @@ -65,10 +79,14 @@ private: static RenderingDevice *singleton; +protected: + static void _bind_methods(); + public: //base numeric ID for all types enum { - INVALID_ID = -1 + INVALID_ID = -1, + INVALID_FORMAT_ID = -1 }; /*****************/ @@ -530,13 +548,13 @@ public: VERTEX_FREQUENCY_INSTANCE, }; - struct VertexDescription { + struct VertexAttribute { uint32_t location; //shader location uint32_t offset; DataFormat format; uint32_t stride; VertexFrequency frequency; - VertexDescription() { + VertexAttribute() { location = 0; offset = 0; stride = 0; @@ -549,7 +567,7 @@ public: typedef int64_t VertexFormatID; // This ID is warranted to be unique for the same formats, does not need to be freed - virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0; + virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0; virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0; enum IndexBufferFormat { @@ -578,6 +596,7 @@ public: } }; + RID shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode); virtual RID shader_create(const Vector<ShaderStageData> &p_stages) = 0; virtual uint32_t shader_get_vertex_input_attribute_mask(RID p_shader) = 0; @@ -595,7 +614,7 @@ public: UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO). UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly - UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly + UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly UNIFORM_TYPE_MAX }; @@ -767,7 +786,6 @@ public: }; struct PipelineDepthStencilState { - bool enable_depth_test; bool enable_depth_write; CompareOperator depth_compare_operator; @@ -796,8 +814,8 @@ public: } }; - StencilOperationState stencil_operation_front; - StencilOperationState stencil_operation_back; + StencilOperationState front_op; + StencilOperationState back_op; PipelineDepthStencilState() { enable_depth_test = false; @@ -811,7 +829,6 @@ public: }; struct PipelineColorBlendState { - bool enable_logic_op; LogicOperation logic_op; struct Attachment { @@ -852,7 +869,6 @@ public: static PipelineColorBlendState create_blend(int p_attachments = 1) { PipelineColorBlendState bs; for (int i = 0; i < p_attachments; i++) { - Attachment ba; ba.enable_blend = true; ba.src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA; @@ -884,8 +900,8 @@ public: DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6), }; - virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; virtual bool render_pipeline_is_valid(RID p_pipeline) = 0; + virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0; /**************************/ /**** COMPUTE PIPELINE ****/ @@ -932,7 +948,7 @@ public: virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0; virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0; virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0; - virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0; @@ -950,7 +966,7 @@ public: virtual ComputeListID compute_list_begin() = 0; virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0; virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0; - virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0; + virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0; virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0; virtual void compute_list_add_barrier(ComputeListID p_list) = 0; @@ -1027,12 +1043,65 @@ public: virtual void submit() = 0; virtual void sync() = 0; + virtual uint64_t get_memory_usage() const = 0; + virtual RenderingDevice *create_local_device() = 0; static RenderingDevice *get_singleton(); RenderingDevice(); + +protected: + //binders to script API + RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array()); + RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture); + RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D); + + FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments); + RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID); + RID _sampler_create(const Ref<RDSamplerState> &p_state); + VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats); + RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers); + + Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true); + + RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set); + + Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false); + + RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0); + + Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2()); + void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); + void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size); }; +VARIANT_ENUM_CAST(RenderingDevice::ShaderStage) +VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage) +VARIANT_ENUM_CAST(RenderingDevice::CompareOperator) +VARIANT_ENUM_CAST(RenderingDevice::DataFormat) +VARIANT_ENUM_CAST(RenderingDevice::TextureType) +VARIANT_ENUM_CAST(RenderingDevice::TextureSamples) +VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits) +VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle) +VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType) +VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter) +VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode) +VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor) +VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency) +VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat) +VARIANT_ENUM_CAST(RenderingDevice::UniformType) +VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive) +VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode) +VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace) +VARIANT_ENUM_CAST(RenderingDevice::StencilOperation) +VARIANT_ENUM_CAST(RenderingDevice::LogicOperation) +VARIANT_ENUM_CAST(RenderingDevice::BlendFactor) +VARIANT_ENUM_CAST(RenderingDevice::BlendOperation) +VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags) +VARIANT_ENUM_CAST(RenderingDevice::InitialAction) +VARIANT_ENUM_CAST(RenderingDevice::FinalAction) +VARIANT_ENUM_CAST(RenderingDevice::Limit) + typedef RenderingDevice RD; #endif // RENDERING_DEVICE_H diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp new file mode 100644 index 0000000000..0400cebfdc --- /dev/null +++ b/servers/rendering/rendering_device_binds.cpp @@ -0,0 +1,205 @@ +/*************************************************************************/ +/* rendering_device_binds.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "rendering_device_binds.h" + +Error RDShaderFile::parse_versions_from_text(const String &p_text, const String p_defines, OpenIncludeFunction p_include_func, void *p_include_func_userdata) { + Vector<String> lines = p_text.split("\n"); + + bool reading_versions = false; + bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false }; + RD::ShaderStage stage = RD::SHADER_STAGE_MAX; + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute", + }; + String stage_code[RD::SHADER_STAGE_MAX]; + int stages_found = 0; + Map<StringName, String> version_texts; + + versions.clear(); + base_error = ""; + + for (int lidx = 0; lidx < lines.size(); lidx++) { + String line = lines[lidx]; + + { + String ls = line.strip_edges(); + if (ls.begins_with("#[") && ls.ends_with("]")) { + String section = ls.substr(2, ls.length() - 3).strip_edges(); + if (section == "versions") { + if (stages_found) { + base_error = "Invalid shader file, #[versions] must be the first section found."; + break; + } + reading_versions = true; + } else { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + if (section == stage_str[i]) { + if (stage_found[i]) { + base_error = "Invalid shader file, stage appears twice: " + section; + break; + } + + stage_found[i] = true; + stages_found++; + + stage = RD::ShaderStage(i); + reading_versions = false; + break; + } + } + + if (base_error != String()) { + break; + } + } + + continue; + } + } + + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + line = line.strip_edges(); + if (line.begins_with("//") || line.begins_with("/*")) { + continue; //assuming comment (single line) + } + } + + if (reading_versions) { + String l = line.strip_edges(); + if (l != "") { + if (l.find("=") == -1) { + base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`."; + break; + } + if (l.find(";") == -1) { + // We don't require a semicolon per se, but it's needed for clang-format to handle things properly. + base_error = "Missing `;` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`."; + break; + } + Vector<String> slices = l.get_slice(";", 0).split("="); + String version = slices[0].strip_edges(); + if (!version.is_valid_identifier()) { + base_error = "Version names must be valid identifiers, found '" + version + "' instead."; + break; + } + String define = slices[1].strip_edges(); + if (!define.begins_with("\"") || !define.ends_with("\"")) { + base_error = "Version text must be quoted using \"\", instead found '" + define + "'."; + break; + } + define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; // Add newline before and after just in case. + + version_texts[version] = define + "\n" + p_defines; + } + } else { + if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") { + base_error = "Text was found that does not belong to a valid section: " + line; + break; + } + + if (stage != RD::SHADER_STAGE_MAX) { + if (line.strip_edges().begins_with("#include")) { + if (p_include_func) { + //process include + String include = line.replace("#include", "").strip_edges(); + if (!include.begins_with("\"") || !include.ends_with("\"")) { + base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include; + break; + } + include = include.substr(1, include.length() - 2).strip_edges(); + String include_text = p_include_func(include, p_include_func_userdata); + if (include_text != String()) { + stage_code[stage] += "\n" + include_text + "\n"; + } else { + base_error = "#include failed for file '" + include + "'"; + } + } else { + base_error = "#include used, but no include function provided."; + } + } else { + stage_code[stage] += line + "\n"; + } + } + } + } + + Ref<RDShaderFile> shader_file; + shader_file.instance(); + + if (base_error == "") { + if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) { + ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present."); + } + + if (version_texts.empty()) { + version_texts[""] = ""; //make sure a default version exists + } + + bool errors_found = false; + + /* STEP 2, Compile the versions, add to shader file */ + + for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) { + Ref<RDShaderBytecode> bytecode; + bytecode.instance(); + + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String code = stage_code[i]; + if (code == String()) { + continue; + } + code = code.replace("VERSION_DEFINES", E->get()); + String error; + Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false); + bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv); + if (error != "") { + error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n"; + Vector<String> sclines = code.split("\n"); + for (int j = 0; j < sclines.size(); j++) { + error += itos(j + 1) + "\t\t" + sclines[j] + "\n"; + } + errors_found = true; + } + bytecode->set_stage_compile_error(RD::ShaderStage(i), error); + } + + set_bytecode(bytecode, E->key()); + } + + return errors_found ? ERR_PARSE_ERROR : OK; + } else { + return ERR_PARSE_ERROR; + } +} diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h new file mode 100644 index 0000000000..319c6d9fde --- /dev/null +++ b/servers/rendering/rendering_device_binds.h @@ -0,0 +1,629 @@ +/*************************************************************************/ +/* rendering_device_binds.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RENDERING_DEVICE_BINDS_H +#define RENDERING_DEVICE_BINDS_H + +#include "servers/rendering/rendering_device.h" + +#define RD_SETGET(m_type, m_member) \ + void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \ + m_type get_##m_member() const { return base.m_member; } + +#define RD_BIND(m_variant_type, m_class, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member)) + +#define RD_SETGET_SUB(m_type, m_sub, m_member) \ + void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \ + m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; } + +#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \ + ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \ + ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \ + ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member)) + +class RDTextureFormat : public Reference { + GDCLASS(RDTextureFormat, Reference) + friend class RenderingDevice; + + RD::TextureFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, width) + RD_SETGET(uint32_t, height) + RD_SETGET(uint32_t, depth) + RD_SETGET(uint32_t, array_layers) + RD_SETGET(uint32_t, mipmaps) + RD_SETGET(RD::TextureType, type) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_bits) + + void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); } + void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureFormat, format); + RD_BIND(Variant::INT, RDTextureFormat, width); + RD_BIND(Variant::INT, RDTextureFormat, height); + RD_BIND(Variant::INT, RDTextureFormat, depth); + RD_BIND(Variant::INT, RDTextureFormat, array_layers); + RD_BIND(Variant::INT, RDTextureFormat, mipmaps); + RD_BIND(Variant::INT, RDTextureFormat, type); + RD_BIND(Variant::INT, RDTextureFormat, samples); + RD_BIND(Variant::INT, RDTextureFormat, usage_bits); + ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format); + ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format); + } +}; + +class RDTextureView : public Reference { + GDCLASS(RDTextureView, Reference) + + friend class RenderingDevice; + + RD::TextureView base; + +public: + RD_SETGET(RD::DataFormat, format_override) + RD_SETGET(RD::TextureSwizzle, swizzle_r) + RD_SETGET(RD::TextureSwizzle, swizzle_g) + RD_SETGET(RD::TextureSwizzle, swizzle_b) + RD_SETGET(RD::TextureSwizzle, swizzle_a) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDTextureView, format_override); + RD_BIND(Variant::INT, RDTextureView, swizzle_r); + RD_BIND(Variant::INT, RDTextureView, swizzle_g); + RD_BIND(Variant::INT, RDTextureView, swizzle_b); + RD_BIND(Variant::INT, RDTextureView, swizzle_a); + } +}; + +class RDAttachmentFormat : public Reference { + GDCLASS(RDAttachmentFormat, Reference) + friend class RenderingDevice; + + RD::AttachmentFormat base; + +public: + RD_SETGET(RD::DataFormat, format) + RD_SETGET(RD::TextureSamples, samples) + RD_SETGET(uint32_t, usage_flags) +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDAttachmentFormat, format); + RD_BIND(Variant::INT, RDAttachmentFormat, samples); + RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags); + } +}; + +class RDSamplerState : public Reference { + GDCLASS(RDSamplerState, Reference) + friend class RenderingDevice; + + RD::SamplerState base; + +public: + RD_SETGET(RD::SamplerFilter, mag_filter) + RD_SETGET(RD::SamplerFilter, min_filter) + RD_SETGET(RD::SamplerFilter, mip_filter) + RD_SETGET(RD::SamplerRepeatMode, repeat_u) + RD_SETGET(RD::SamplerRepeatMode, repeat_v) + RD_SETGET(RD::SamplerRepeatMode, repeat_w) + RD_SETGET(float, lod_bias) + RD_SETGET(bool, use_anisotropy) + RD_SETGET(float, anisotropy_max) + RD_SETGET(bool, enable_compare) + RD_SETGET(RD::CompareOperator, compare_op) + RD_SETGET(float, min_lod) + RD_SETGET(float, max_lod) + RD_SETGET(RD::SamplerBorderColor, border_color) + RD_SETGET(bool, unnormalized_uvw) + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDSamplerState, mag_filter); + RD_BIND(Variant::INT, RDSamplerState, min_filter); + RD_BIND(Variant::INT, RDSamplerState, mip_filter); + RD_BIND(Variant::INT, RDSamplerState, repeat_u); + RD_BIND(Variant::INT, RDSamplerState, repeat_v); + RD_BIND(Variant::INT, RDSamplerState, repeat_w); + RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias); + RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy); + RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max); + RD_BIND(Variant::BOOL, RDSamplerState, enable_compare); + RD_BIND(Variant::INT, RDSamplerState, compare_op); + RD_BIND(Variant::FLOAT, RDSamplerState, min_lod); + RD_BIND(Variant::FLOAT, RDSamplerState, max_lod); + RD_BIND(Variant::INT, RDSamplerState, border_color); + RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw); + } +}; + +class RDVertexAttribute : public Reference { + GDCLASS(RDVertexAttribute, Reference) + friend class RenderingDevice; + RD::VertexAttribute base; + +public: + RD_SETGET(uint32_t, location) + RD_SETGET(uint32_t, offset) + RD_SETGET(RD::DataFormat, format) + RD_SETGET(uint32_t, stride) + RD_SETGET(RD::VertexFrequency, frequency) + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDVertexAttribute, location); + RD_BIND(Variant::INT, RDVertexAttribute, offset); + RD_BIND(Variant::INT, RDVertexAttribute, format); + RD_BIND(Variant::INT, RDVertexAttribute, stride); + RD_BIND(Variant::INT, RDVertexAttribute, frequency); + } +}; +class RDShaderSource : public Reference { + GDCLASS(RDShaderSource, Reference) + String source[RD::SHADER_STAGE_MAX]; + RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL; + +public: + void set_stage_source(RD::ShaderStage p_stage, const String &p_source) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + source[p_stage] = p_source; + } + + String get_stage_source(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return source[p_stage]; + } + + void set_language(RD::ShaderLanguage p_language) { + language = p_language; + } + + RD::ShaderLanguage get_language() const { + return language; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source); + ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source); + + ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language); + ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language); + + ADD_GROUP("Source", "source_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Syntax", "source_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language"); + } +}; + +class RDShaderBytecode : public Resource { + GDCLASS(RDShaderBytecode, Resource) + + Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX]; + String compile_error[RD::SHADER_STAGE_MAX]; + +public: + void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + bytecode[p_stage] = p_bytecode; + } + + Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>()); + return bytecode[p_stage]; + } + + void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) { + ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX); + compile_error[p_stage] = p_compile_error; + } + + String get_stage_compile_error(RD::ShaderStage p_stage) const { + ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String()); + return compile_error[p_stage]; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode); + ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode); + + ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error); + ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error); + + ADD_GROUP("Bytecode", "bytecode_"); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE); + ADD_GROUP("Compile Error", "compile_error_"); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION); + ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE); + } +}; + +class RDShaderFile : public Resource { + GDCLASS(RDShaderFile, Resource) + + Map<StringName, Ref<RDShaderBytecode>> versions; + String base_error; + +public: + void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) { + ERR_FAIL_COND(p_bytecode.is_null()); + versions[p_version] = p_bytecode; + emit_changed(); + } + + Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const { + ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>()); + return versions[p_version]; + } + + Vector<StringName> get_version_list() const { + Vector<StringName> vnames; + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + vnames.push_back(E->key()); + } + vnames.sort_custom<StringName::AlphCompare>(); + return vnames; + } + + void set_base_error(const String &p_error) { + base_error = p_error; + emit_changed(); + } + + String get_base_error() const { + return base_error; + } + + void print_errors(const String &p_file) { + if (base_error != "") { + ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error); + } else { + for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) { + for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) { + String error = E->get()->get_stage_compile_error(RD::ShaderStage(i)); + if (error != String()) { + static const char *stage_str[RD::SHADER_STAGE_MAX] = { + "vertex", + "fragment", + "tesselation_control", + "tesselation_evaluation", + "compute" + }; + + ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E->key()) + "', stage '" + stage_str[i] + "':\n\n" + error); + } + } + } + } + } + + typedef String (*OpenIncludeFunction)(const String &, void *userdata); + Error parse_versions_from_text(const String &p_text, const String p_defines = String(), OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr); + +protected: + Dictionary _get_versions() const { + Vector<StringName> vnames = get_version_list(); + Dictionary ret; + for (int i = 0; i < vnames.size(); i++) { + ret[vnames[i]] = versions[vnames[i]]; + } + return ret; + } + void _set_versions(const Dictionary &p_versions) { + versions.clear(); + List<Variant> keys; + p_versions.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + StringName name = E->get(); + Ref<RDShaderBytecode> bc = p_versions[E->get()]; + ERR_CONTINUE(bc.is_null()); + versions[name] = bc; + } + + emit_changed(); + } + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName())); + ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list); + + ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error); + ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error); + + ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions); + ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error"); + } +}; + +class RDUniform : public Reference { + GDCLASS(RDUniform, Reference) + friend class RenderingDevice; + RD::Uniform base; + +public: + RD_SETGET(RD::UniformType, type) + RD_SETGET(int32_t, binding) + + void add_id(const RID &p_id) { base.ids.push_back(p_id); } + void clear_ids() { base.ids.clear(); } + Array get_ids() const { + Array ids; + for (int i = 0; i < base.ids.size(); i++) { + ids.push_back(base.ids[i]); + } + return ids; + } + +protected: + void _set_ids(const Array &p_ids) { + base.ids.clear(); + for (int i = 0; i < p_ids.size(); i++) { + RID id = p_ids[i]; + ERR_FAIL_COND(id.is_null()); + base.ids.push_back(id); + } + } + static void _bind_methods() { + RD_BIND(Variant::INT, RDUniform, type); + RD_BIND(Variant::INT, RDUniform, binding); + ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id); + ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids); + ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids); + ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids"); + } +}; +class RDPipelineRasterizationState : public Reference { + GDCLASS(RDPipelineRasterizationState, Reference) + friend class RenderingDevice; + + RD::PipelineRasterizationState base; + +public: + RD_SETGET(bool, enable_depth_clamp) + RD_SETGET(bool, discard_primitives) + RD_SETGET(bool, wireframe) + RD_SETGET(RD::PolygonCullMode, cull_mode) + RD_SETGET(RD::PolygonFrontFace, front_face) + RD_SETGET(bool, depth_bias_enable) + RD_SETGET(float, depth_bias_constant_factor) + RD_SETGET(float, depth_bias_clamp) + RD_SETGET(float, depth_bias_slope_factor) + RD_SETGET(float, line_width) + RD_SETGET(uint32_t, patch_control_points) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe); + RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode); + RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face); + RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor); + RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width); + RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points); + } +}; + +class RDPipelineMultisampleState : public Reference { + GDCLASS(RDPipelineMultisampleState, Reference) + friend class RenderingDevice; + + RD::PipelineMultisampleState base; + TypedArray<int64_t> sample_masks; + +public: + RD_SETGET(RD::TextureSamples, sample_count) + RD_SETGET(bool, enable_sample_shading) + RD_SETGET(float, min_sample_shading) + RD_SETGET(bool, enable_alpha_to_coverage) + RD_SETGET(bool, enable_alpha_to_one) + + void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; } + TypedArray<int64_t> get_sample_masks() const { return sample_masks; } + +protected: + static void _bind_methods() { + RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading); + RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage); + RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one); + + ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks); + ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks"); + } +}; + +class RDPipelineDepthStencilState : public Reference { + GDCLASS(RDPipelineDepthStencilState, Reference) + friend class RenderingDevice; + + RD::PipelineDepthStencilState base; + +public: + RD_SETGET(bool, enable_depth_test) + RD_SETGET(bool, enable_depth_write) + RD_SETGET(RD::CompareOperator, depth_compare_operator) + RD_SETGET(bool, enable_depth_range) + RD_SETGET(float, depth_range_min) + RD_SETGET(float, depth_range_max) + RD_SETGET(bool, enable_stencil) + + RD_SETGET_SUB(RD::StencilOperation, front_op, fail) + RD_SETGET_SUB(RD::StencilOperation, front_op, pass) + RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, front_op, compare) + RD_SETGET_SUB(uint32_t, front_op, compare_mask) + RD_SETGET_SUB(uint32_t, front_op, write_mask) + RD_SETGET_SUB(uint32_t, front_op, reference) + + RD_SETGET_SUB(RD::StencilOperation, back_op, fail) + RD_SETGET_SUB(RD::StencilOperation, back_op, pass) + RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail) + RD_SETGET_SUB(RD::CompareOperator, back_op, compare) + RD_SETGET_SUB(uint32_t, back_op, compare_mask) + RD_SETGET_SUB(uint32_t, back_op, write_mask) + RD_SETGET_SUB(uint32_t, back_op, reference) + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write); + RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min); + RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max); + RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference); + + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask); + RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference); + } +}; + +class RDPipelineColorBlendStateAttachment : public Reference { + GDCLASS(RDPipelineColorBlendStateAttachment, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState::Attachment base; + +public: + RD_SETGET(bool, enable_blend) + RD_SETGET(RD::BlendFactor, src_color_blend_factor) + RD_SETGET(RD::BlendFactor, dst_color_blend_factor) + RD_SETGET(RD::BlendOperation, color_blend_op) + RD_SETGET(RD::BlendFactor, src_alpha_blend_factor) + RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor) + RD_SETGET(RD::BlendOperation, alpha_blend_op) + RD_SETGET(bool, write_r) + RD_SETGET(bool, write_g) + RD_SETGET(bool, write_b) + RD_SETGET(bool, write_a) + + void set_as_mix() { + base = RD::PipelineColorBlendState::Attachment(); + base.enable_blend = true; + base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA; + base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + } + +protected: + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix); + + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor); + RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b); + RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a); + } +}; + +class RDPipelineColorBlendState : public Reference { + GDCLASS(RDPipelineColorBlendState, Reference) + friend class RenderingDevice; + RD::PipelineColorBlendState base; + + TypedArray<RDPipelineColorBlendStateAttachment> attachments; + +public: + RD_SETGET(bool, enable_logic_op) + RD_SETGET(RD::LogicOperation, logic_op) + RD_SETGET(Color, blend_constant) + + void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) { + attachments.push_back(p_attachments); + } + + TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const { + return attachments; + } + +protected: + static void _bind_methods() { + RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op); + RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op); + RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant); + + ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments); + ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments"); + } +}; + +#endif // RENDERING_DEVICE_BINDS_H diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp index 5d6dcfd2c1..5c0741bb3b 100644 --- a/servers/rendering/rendering_server_canvas.cpp +++ b/servers/rendering/rendering_server_canvas.cpp @@ -29,6 +29,8 @@ /*************************************************************************/ #include "rendering_server_canvas.h" + +#include "core/math/geometry_2d.h" #include "rendering_server_globals.h" #include "rendering_server_raster.h" #include "rendering_server_viewport.h" @@ -36,7 +38,6 @@ static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1; void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) { - RENDER_TIMESTAMP("Cull CanvasItem Tree"); memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *)); @@ -53,8 +54,9 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can RasterizerCanvas::Item *list_end = nullptr; for (int i = 0; i < z_range; i++) { - if (!z_list[i]) + if (!z_list[i]) { continue; + } if (!list) { list = z_list[i]; list_end = z_last_list[i]; @@ -83,8 +85,9 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo r_index++; - if (child_items[i]->sort_y) + if (child_items[i]->sort_y) { _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index); + } } } } @@ -97,14 +100,13 @@ void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<Re } void RenderingServerCanvas::_cull_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; - if (!ci->visible) + if (!ci->visible) { return; + } if (ci->children_order_dirty) { - ci->child_items.sort_custom<ItemIndexSort>(); ci->children_order_dirty = false; } @@ -114,17 +116,18 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo Rect2 global_rect = xform.xform(rect); global_rect.position += p_clip_rect.position; - if (ci->use_parent_material && p_material_owner) + if (ci->use_parent_material && p_material_owner) { ci->material_owner = p_material_owner; - else { + } else { p_material_owner = ci; ci->material_owner = nullptr; } Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a); - if (modulate.a < 0.007) + if (modulate.a < 0.007) { return; + } int child_item_count = ci->child_items.size(); Item **child_items = ci->child_items.ptrw(); @@ -142,7 +145,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } if (ci->sort_y) { - if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count); @@ -158,15 +160,16 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo sorter.sort(child_items, child_item_count); } - if (ci->z_relative) + if (ci->z_relative) { p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX); - else + } else { p_z = ci->z_index; + } for (int i = 0; i < child_item_count; i++) { - - if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) + if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) { continue; + } if (ci->sort_y) { _cull_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, (Item *)child_items[i]->material_owner); } else { @@ -175,7 +178,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } if (ci->copy_back_buffer) { - ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect); } @@ -208,9 +210,9 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } for (int i = 0; i < child_item_count; i++) { - - if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) + if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) { continue; + } if (ci->sort_y) { _cull_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, (Item *)child_items[i]->material_owner); } else { @@ -220,17 +222,15 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo } void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) { - - if (!p_masked_lights) + if (!p_masked_lights) { return; + } RasterizerCanvas::Item *ci = p_canvas_item; while (ci) { - RasterizerCanvas::Light *light = p_masked_lights; while (light) { - if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { ci->light_masked = true; } @@ -243,11 +243,9 @@ void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas:: } void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) { - RENDER_TIMESTAMP(">Render Canvas"); if (p_canvas->children_order_dirty) { - p_canvas->child_items.sort(); p_canvas->children_order_dirty = false; } @@ -264,29 +262,24 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } if (!has_mirror) { - _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights); } else { //used for parallaxlayer mirroring for (int i = 0; i < l; i++) { - const Canvas::ChildItem &ci2 = p_canvas->child_items[i]; _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights); //mirroring (useful for scrolling backgrounds) if (ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0)); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0) { - Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y)); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } if (ci2.mirror.y != 0 && ci2.mirror.x != 0) { - Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror); _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights); } @@ -297,7 +290,6 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, } RID RenderingServerCanvas::canvas_create() { - Canvas *canvas = memnew(Canvas); ERR_FAIL_COND_V(!canvas, RID()); RID rid = canvas_owner.make_rid(canvas); @@ -306,7 +298,6 @@ RID RenderingServerCanvas::canvas_create() { } void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) { - Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -316,8 +307,8 @@ void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, ERR_FAIL_COND(idx == -1); canvas->child_items.write[idx].mirror = p_mirroring; } -void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) { +void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) { Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); canvas->modulate = p_color; @@ -328,7 +319,6 @@ void RenderingServerCanvas::canvas_set_disable_scale(bool p_disable) { } void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) { - Canvas *canvas = canvas_owner.getornull(p_canvas); ERR_FAIL_COND(!canvas); @@ -337,7 +327,6 @@ void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float } RID RenderingServerCanvas::canvas_item_create() { - Item *canvas_item = memnew(Item); ERR_FAIL_COND_V(!canvas_item, RID()); @@ -345,18 +334,14 @@ RID RenderingServerCanvas::canvas_item_create() { } void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); if (canvas_item->parent.is_valid()) { - if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); item_owner->child_items.erase(canvas_item); @@ -370,14 +355,12 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { if (p_parent.is_valid()) { if (canvas_owner.owns(p_parent)) { - Canvas *canvas = canvas_owner.getornull(p_parent); Canvas::ChildItem ci; ci.item = canvas_item; canvas->child_items.push_back(ci); canvas->children_order_dirty = true; } else if (canvas_item_owner.owns(p_parent)) { - Item *item_owner = canvas_item_owner.getornull(p_parent); item_owner->child_items.push_back(canvas_item); item_owner->children_order_dirty = true; @@ -387,15 +370,14 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) { } } else { - ERR_FAIL_MSG("Invalid parent."); } } canvas_item->parent = p_parent; } -void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { +void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -403,8 +385,8 @@ void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { +void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -412,43 +394,42 @@ void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) { } void RenderingServerCanvas::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->xform = p_transform; } -void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) { +void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clip = p_clip; } -void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->distance_field = p_enable; } -void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { +void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->custom_rect = p_custom_rect; canvas_item->rect = p_rect; } -void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) { +void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->modulate = p_color; } -void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { +void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -456,7 +437,6 @@ void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Colo } void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -464,7 +444,6 @@ void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool } void RenderingServerCanvas::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); @@ -472,28 +451,24 @@ void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool } void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->texture_filter = p_filter; } void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->texture_repeat = p_repeat; } void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>(); ERR_FAIL_COND(!line); if (p_width > 1.001) { - Vector2 t = (p_from - p_to).tangent().normalized(); line->points[0] = p_from + t * p_width; line->points[1] = p_from - t * p_width; @@ -512,7 +487,6 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro } void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { - ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -604,7 +578,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po } void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { - ERR_FAIL_COND(p_points.size() < 2); Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -625,7 +598,6 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P } void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -636,7 +608,6 @@ void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect } void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -674,7 +645,6 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p } void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -690,12 +660,10 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 } if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } @@ -708,7 +676,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 } void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -722,22 +689,18 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons rect->flags = RasterizerCanvas::CANVAS_RECT_REGION; if (p_rect.size.x < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->rect.size.x = -rect->rect.size.x; } if (p_src_rect.size.x < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_H; rect->source.size.x = -rect->source.size.x; } if (p_rect.size.y < 0) { - rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } if (p_src_rect.size.y < 0) { - rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_V; rect->source.size.y = -rect->source.size.y; } @@ -753,7 +716,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons } void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -772,8 +734,8 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 & style->axis_x = p_x_axis_mode; style->axis_y = p_y_axis_mode; } -void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { +void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { uint32_t pc = p_points.size(); ERR_FAIL_COND(pc == 0 || pc > 4); @@ -804,7 +766,6 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P } void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); #ifdef DEBUG_ENABLED @@ -815,7 +776,7 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi ERR_FAIL_COND(color_size != 0 && color_size != 1 && color_size != pointcount); ERR_FAIL_COND(uv_size != 0 && (uv_size != pointcount)); #endif - Vector<int> indices = Geometry::triangulate_polygon(p_points); + Vector<int> indices = Geometry2D::triangulate_polygon(p_points); ERR_FAIL_COND_MSG(indices.empty(), "Invalid polygon data, triangulation failed."); Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>(); @@ -827,7 +788,6 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi } void RenderingServerCanvas::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, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -850,7 +810,6 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec } void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -860,7 +819,6 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran } void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -872,8 +830,8 @@ void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, m->transform = p_transform; m->modulate = p_modulate; } -void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { +void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -888,7 +846,6 @@ void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particle } void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -900,7 +857,6 @@ void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RI } void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -908,8 +864,8 @@ void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignor ERR_FAIL_COND(!ci); ci->ignore = p_ignore; } -void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -917,8 +873,8 @@ void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool _mark_ysort_dirty(canvas_item, canvas_item_owner); } -void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { +void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX); Item *canvas_item = canvas_item_owner.getornull(p_item); @@ -926,8 +882,8 @@ void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) { canvas_item->z_index = p_z; } -void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { +void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -935,7 +891,6 @@ void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, } void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -943,7 +898,6 @@ void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skelet } void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) { @@ -962,14 +916,13 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool } void RenderingServerCanvas::canvas_item_clear(RID p_item) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); canvas_item->clear(); } -void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) { +void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -989,7 +942,6 @@ void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) } void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -997,7 +949,6 @@ void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) } void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { - Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -1005,57 +956,54 @@ void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool } RID RenderingServerCanvas::canvas_light_create() { - RasterizerCanvas::Light *clight = memnew(RasterizerCanvas::Light); clight->light_internal = RSG::canvas_render->light_create(); return canvas_light_owner.make_rid(clight); } -void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { +void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); canvas->lights.erase(clight); } - if (!canvas_owner.owns(p_canvas)) + if (!canvas_owner.owns(p_canvas)) { p_canvas = RID(); + } clight->canvas = p_canvas; if (clight->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(clight->canvas); canvas->lights.insert(clight); } } void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { +void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->scale = p_scale; } -void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { +void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->xform = p_transform; } -void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) { +void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1063,66 +1011,66 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) clight->version++; RSG::canvas_render->light_set_texture(clight->light_internal, p_texture); } -void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { +void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->texture_offset = p_offset; } -void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) { +void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->color = p_color; } -void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) { +void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->height = p_height; } -void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) { +void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->energy = p_energy; } -void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { +void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->z_min = p_min_z; clight->z_max = p_max_z; } -void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { +void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->layer_max = p_max_layer; clight->layer_min = p_min_layer; } -void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { +void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { +void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->item_shadow_mask = p_mask; } -void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { +void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1130,7 +1078,6 @@ void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMo } void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1143,15 +1090,15 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ } void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_size) { - ERR_FAIL_COND(p_size < 32 || p_size > 16384); RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); int new_size = next_power_of_2(p_size); - if (new_size == clight->shadow_buffer_size) + if (new_size == clight->shadow_buffer_size) { return; + } clight->shadow_buffer_size = next_power_of_2(p_size); clight->version++; @@ -1160,14 +1107,13 @@ void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int } void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_filter = p_filter; } -void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { +void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) { RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); @@ -1175,49 +1121,46 @@ void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Col } void RenderingServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) { - RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light); ERR_FAIL_COND(!clight); clight->shadow_smooth = p_smooth; } RID RenderingServerCanvas::canvas_light_occluder_create() { - RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance); return canvas_light_occluder_owner.make_rid(occluder); } -void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { +void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.erase(occluder); } - if (!canvas_owner.owns(p_canvas)) + if (!canvas_owner.owns(p_canvas)) { p_canvas = RID(); + } occluder->canvas = p_canvas; if (occluder->canvas.is_valid()) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.insert(occluder); } } -void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { +void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->enabled = p_enabled; } -void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { +void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); @@ -1244,15 +1187,15 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI } } } -void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { +void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); occluder->xform = p_xform; } -void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { +void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) { RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder); ERR_FAIL_COND(!occluder); @@ -1260,13 +1203,12 @@ void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, } RID RenderingServerCanvas::canvas_occluder_polygon_create() { - LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon); occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create(); return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); } -void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { +void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) { if (p_shape.size() < 3) { canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, p_shape); return; @@ -1285,7 +1227,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol max--; } for (int i = 0; i < max; i++) { - Vector2 a = r[i]; Vector2 b = r[(i + 1) % (lc / 2)]; w[i * 2 + 0] = a; @@ -1295,8 +1236,8 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, lines); } -void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) { +void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) { LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); ERR_FAIL_COND(p_shape.size() & 1); @@ -1306,10 +1247,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ { const Vector2 *r = p_shape.ptr(); for (int i = 0; i < lc; i++) { - if (i == 0) + if (i == 0) { occluder_poly->aabb.position = r[i]; - else + } else { occluder_poly->aabb.expand_to(r[i]); + } } } @@ -1320,7 +1262,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ } void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon); ERR_FAIL_COND(!occluder_poly); occluder_poly->cull_mode = p_mode; @@ -1331,14 +1272,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder } bool RenderingServerCanvas::free(RID p_rid) { - if (canvas_owner.owns(p_rid)) { - Canvas *canvas = canvas_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas, false); while (canvas->viewports.size()) { - RenderingServerViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get()); ERR_FAIL_COND_V(!vp, true); @@ -1350,17 +1288,14 @@ bool RenderingServerCanvas::free(RID p_rid) { } for (int i = 0; i < canvas->child_items.size(); i++) { - canvas->child_items[i].item->parent = RID(); } for (Set<RasterizerCanvas::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) { - E->get()->canvas = RID(); } for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) { - E->get()->canvas = RID(); } @@ -1369,18 +1304,14 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas); } else if (canvas_item_owner.owns(p_rid)) { - Item *canvas_item = canvas_item_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas_item, true); if (canvas_item->parent.is_valid()) { - if (canvas_owner.owns(canvas_item->parent)) { - Canvas *canvas = canvas_owner.getornull(canvas_item->parent); canvas->erase_item(canvas_item); } else if (canvas_item_owner.owns(canvas_item->parent)) { - Item *item_owner = canvas_item_owner.getornull(canvas_item->parent); item_owner->child_items.erase(canvas_item); @@ -1391,7 +1322,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } for (int i = 0; i < canvas_item->child_items.size(); i++) { - canvas_item->child_items[i]->parent = RID(); } @@ -1406,14 +1336,14 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_item); } else if (canvas_light_owner.owns(p_rid)) { - RasterizerCanvas::Light *canvas_light = canvas_light_owner.getornull(p_rid); ERR_FAIL_COND_V(!canvas_light, true); if (canvas_light->canvas.is_valid()) { Canvas *canvas = canvas_owner.getornull(canvas_light->canvas); - if (canvas) + if (canvas) { canvas->lights.erase(canvas_light); + } } RSG::canvas_render->free(canvas_light->light_internal); @@ -1422,12 +1352,10 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(canvas_light); } else if (canvas_light_occluder_owner.owns(p_rid)) { - RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid); ERR_FAIL_COND_V(!occluder, true); if (occluder->polygon.is_valid()) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(occluder->polygon); if (occluder_poly) { occluder_poly->owners.erase(occluder); @@ -1435,7 +1363,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { - Canvas *canvas = canvas_owner.getornull(occluder->canvas); canvas->occluders.erase(occluder); } @@ -1444,13 +1371,11 @@ bool RenderingServerCanvas::free(RID p_rid) { memdelete(occluder); } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { - LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid); ERR_FAIL_COND_V(!occluder_poly, true); RSG::canvas_render->free(occluder_poly->occluder); while (occluder_poly->owners.size()) { - occluder_poly->owners.front()->get()->polygon = RID(); occluder_poly->owners.erase(occluder_poly->owners.front()); } @@ -1465,7 +1390,6 @@ bool RenderingServerCanvas::free(RID p_rid) { } RenderingServerCanvas::RenderingServerCanvas() { - z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *)); @@ -1473,7 +1397,6 @@ RenderingServerCanvas::RenderingServerCanvas() { } RenderingServerCanvas::~RenderingServerCanvas() { - memfree(z_list); memfree(z_last_list); } diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h index 9da11462db..59c0d1fa52 100644 --- a/servers/rendering/rendering_server_canvas.h +++ b/servers/rendering/rendering_server_canvas.h @@ -37,7 +37,6 @@ class RenderingServerCanvas { public: struct Item : public RasterizerCanvas::Item { - RID parent; // canvas it belongs to List<Item *>::Element *E; int z_index; @@ -76,26 +75,22 @@ public: }; struct ItemIndexSort { - _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const { - return p_left->index < p_right->index; } }; struct ItemPtrSort { - _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const { - - if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) + if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) { return p_left->ysort_pos.x < p_right->ysort_pos.x; + } return p_left->ysort_pos.y < p_right->ysort_pos.y; } }; struct LightOccluderPolygon { - bool active; Rect2 aabb; RS::CanvasOccluderPolygonCullMode cull_mode; @@ -113,10 +108,8 @@ public: RID_PtrOwner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner; struct Canvas : public RenderingServerViewport::CanvasBase { - Set<RID> viewports; struct ChildItem { - Point2 mirror; Item *item; bool operator<(const ChildItem &p_item) const { @@ -136,15 +129,17 @@ public: int find_item(Item *p_item) { for (int i = 0; i < child_items.size(); i++) { - if (child_items[i].item == p_item) + if (child_items[i].item == p_item) { return i; + } } return -1; } void erase_item(Item *p_item) { int idx = find_item(p_item); - if (idx >= 0) + if (idx >= 0) { child_items.remove(idx); + } } Canvas() { diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp index c6f3273339..d30160702b 100644 --- a/servers/rendering/rendering_server_raster.cpp +++ b/servers/rendering/rendering_server_raster.cpp @@ -45,7 +45,6 @@ int RenderingServerRaster::changes = 0; /* BLACK BARS */ void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) { - black_margin[MARGIN_LEFT] = p_left; black_margin[MARGIN_TOP] = p_top; black_margin[MARGIN_RIGHT] = p_right; @@ -53,7 +52,6 @@ void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_ } void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) { - black_image[MARGIN_LEFT] = p_left; black_image[MARGIN_TOP] = p_top; black_image[MARGIN_RIGHT] = p_right; @@ -61,30 +59,32 @@ void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_r } void RenderingServerRaster::_draw_margins() { - RSG::canvas_render->draw_window_margins(black_margin, black_image); }; /* FREE */ void RenderingServerRaster::free(RID p_rid) { - - if (RSG::storage->free(p_rid)) + if (RSG::storage->free(p_rid)) { return; - if (RSG::canvas->free(p_rid)) + } + if (RSG::canvas->free(p_rid)) { return; - if (RSG::viewport->free(p_rid)) + } + if (RSG::viewport->free(p_rid)) { return; - if (RSG::scene->free(p_rid)) + } + if (RSG::scene->free(p_rid)) { return; - if (RSG::scene_render->free(p_rid)) + } + if (RSG::scene_render->free(p_rid)) { return; + } } /* EVENT QUEUING */ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) { - ERR_FAIL_NULL(p_where); FrameDrawnCallbacks fdc; fdc.object = p_where->get_instance_id(); @@ -95,7 +95,6 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const } void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { - //needs to be done before changes is reset to 0, to not force the editor to redraw RS::get_singleton()->emit_signal("frame_pre_draw"); @@ -117,7 +116,6 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { RSG::rasterizer->end_frame(p_swap_buffers); while (frame_drawn_callbacks.front()) { - Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object); if (obj) { Callable::CallError ce; @@ -163,18 +161,19 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) { frame_profile_frame = RSG::storage->get_captured_timestamps_frame(); } + void RenderingServerRaster::sync() { } -bool RenderingServerRaster::has_changed() const { +bool RenderingServerRaster::has_changed() const { return changes > 0; } -void RenderingServerRaster::init() { +void RenderingServerRaster::init() { RSG::rasterizer->initialize(); } -void RenderingServerRaster::finish() { +void RenderingServerRaster::finish() { if (test_cube.is_valid()) { free(test_cube); } @@ -185,17 +184,14 @@ void RenderingServerRaster::finish() { /* STATUS INFORMATION */ int RenderingServerRaster::get_render_info(RenderInfo p_info) { - return RSG::storage->get_render_info(p_info); } String RenderingServerRaster::get_video_adapter_name() const { - return RSG::storage->get_video_adapter_name(); } String RenderingServerRaster::get_video_adapter_vendor() const { - return RSG::storage->get_video_adapter_vendor(); } @@ -214,16 +210,15 @@ Vector<RenderingServer::FrameProfileArea> RenderingServerRaster::get_frame_profi /* TESTING */ void RenderingServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) { - redraw_request(); RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter); } + void RenderingServerRaster::set_default_clear_color(const Color &p_color) { RSG::viewport->set_default_clear_color(p_color); } bool RenderingServerRaster::has_feature(Features p_feature) const { - return false; } @@ -235,12 +230,10 @@ RID RenderingServerRaster::get_test_cube() { } bool RenderingServerRaster::has_os_feature(const String &p_feature) const { - return RSG::storage->has_os_feature(p_feature); } void RenderingServerRaster::set_debug_generate_wireframes(bool p_generate) { - RSG::storage->set_debug_generate_wireframes(p_generate); } @@ -255,8 +248,8 @@ bool RenderingServerRaster::is_low_end() const { //return RSG::rasterizer->is_low_end(); return false; } -RenderingServerRaster::RenderingServerRaster() { +RenderingServerRaster::RenderingServerRaster() { RSG::canvas = memnew(RenderingServerCanvas); RSG::viewport = memnew(RenderingServerViewport); RSG::scene = memnew(RenderingServerScene); @@ -274,7 +267,6 @@ RenderingServerRaster::RenderingServerRaster() { } RenderingServerRaster::~RenderingServerRaster() { - memdelete(RSG::canvas); memdelete(RSG::viewport); memdelete(RSG::rasterizer); diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index f7b963a015..8a3c55118d 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -40,7 +40,6 @@ #include "servers/rendering_server.h" class RenderingServerRaster : public RenderingServer { - enum { MAX_INSTANCE_CULL = 8192, @@ -61,7 +60,6 @@ class RenderingServerRaster : public RenderingServer { RID black_image[4]; struct FrameDrawnCallbacks { - ObjectID object; StringName method; Variant param; @@ -108,8 +106,12 @@ public: m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); } #define BIND2RC(m_r, m_name, m_type1, m_type2) \ m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); } +#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); } #define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); } +#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ + m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } #define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); } @@ -170,7 +172,7 @@ public: //these also go pass-through BIND0R(RID, texture_2d_placeholder_create) - BIND0R(RID, texture_2d_layered_placeholder_create) + BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType) BIND0R(RID, texture_3d_placeholder_create) BIND1RC(Ref<Image>, texture_2d_get, RID) @@ -404,23 +406,19 @@ public: BIND2(gi_probe_set_anisotropy_strength, RID, float) BIND1RC(float, gi_probe_get_anisotropy_strength, RID) - /* LIGHTMAP CAPTURE */ - - BIND0R(RID, lightmap_capture_create) - - BIND2(lightmap_capture_set_bounds, RID, const AABB &) - BIND1RC(AABB, lightmap_capture_get_bounds, RID) + /* LIGHTMAP */ - BIND2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &) - BIND1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID) + BIND0R(RID, lightmap_create) - BIND2(lightmap_capture_set_octree_cell_transform, RID, const Transform &) - BIND1RC(Transform, lightmap_capture_get_octree_cell_transform, RID) - BIND2(lightmap_capture_set_octree_cell_subdiv, RID, int) - BIND1RC(int, lightmap_capture_get_octree_cell_subdiv, RID) - - BIND2(lightmap_capture_set_energy, RID, float) - BIND1RC(float, lightmap_capture_get_energy, RID) + BIND3(lightmap_set_textures, RID, RID, bool) + BIND2(lightmap_set_probe_bounds, RID, const AABB &) + BIND2(lightmap_set_probe_interior, RID, bool) + BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) + BIND1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ @@ -532,6 +530,7 @@ public: BIND2(sky_set_radiance_size, RID, int) BIND2(sky_set_mode, RID, SkyMode) BIND2(sky_set_material, RID, RID) + BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) BIND0R(RID, environment_create) @@ -565,6 +564,8 @@ public: BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) + BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + BIND2(screen_space_roughness_limiter_set_active, bool, float) BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) BIND2(sub_surface_scattering_set_scale, float, float) @@ -605,7 +606,6 @@ public: BIND3(instance_set_blend_shape_weight, RID, int, float) BIND3(instance_set_surface_material, RID, int, RID) BIND2(instance_set_visible, RID, bool) - BIND3(instance_set_use_lightmap, RID, RID, RID) BIND2(instance_set_custom_aabb, RID, AABB) @@ -625,12 +625,15 @@ public: BIND5(instance_geometry_set_draw_range, RID, float, float, float, float) BIND2(instance_geometry_set_as_instance_lod, RID, RID) + BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + #undef BINDBASE //from now on, calls forwarded to this singleton #define BINDBASE RSG::canvas diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index 9d141ea570..7b8504036e 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -39,13 +39,11 @@ /* CAMERA API */ RID RenderingServerScene::camera_create() { - Camera *camera = memnew(Camera); return camera_owner.make_rid(camera); } void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::PERSPECTIVE; @@ -55,7 +53,6 @@ void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_deg } void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->type = Camera::ORTHOGONAL; @@ -75,14 +72,12 @@ void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector } void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->transform = p_transform.orthonormalized(); } void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); @@ -90,21 +85,18 @@ void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) } void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->env = p_env; } void RenderingServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->effects = p_fx; } void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) { - Camera *camera = camera_owner.getornull(p_camera); ERR_FAIL_COND(!camera); camera->vaspect = p_enable; @@ -113,7 +105,6 @@ void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_e /* SCENARIO API */ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) { - //RenderingServerScene *self = (RenderingServerScene*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -124,7 +115,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan } if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -135,14 +125,12 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan List<InstanceLightData::PairInfo>::Element *E = light->geometries.push_back(pinfo); if (geom->can_cast_shadows) { - light->shadow_dirty = true; } geom->lighting_dirty = true; return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -156,7 +144,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -169,21 +156,22 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan geom->decal_dirty = true; return E; //this element should make freeing faster - } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); + } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - InstanceLightmapCaptureData::PairInfo pinfo; - pinfo.geometry = A; - pinfo.L = geom->lightmap_captures.push_back(B); - - List<InstanceLightmapCaptureData::PairInfo>::Element *E = lightmap_capture->geometries.push_back(pinfo); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + if (A->dynamic_gi) { + InstanceLightmapData::PairInfo pinfo; + pinfo.geometry = A; + pinfo.L = geom->lightmap_captures.push_back(B); + List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.push_back(pinfo); + ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + return E; //this element should make freeing faster + } else { + return nullptr; + } - return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -203,15 +191,14 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan return E; //this element should make freeing faster } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); return gi_probe->lights.insert(A); } return nullptr; } -void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { +void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) { //RenderingServerScene *self = (RenderingServerScene*)p_self; Instance *A = p_A; Instance *B = p_B; @@ -222,7 +209,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta } if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -237,7 +223,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->lighting_dirty = true; } else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -248,7 +233,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->reflection_dirty = true; } else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -258,19 +242,19 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta decal->geometries.erase(E); geom->decal_dirty = true; - } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { + if (udata) { //only for dynamic geometries + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data); + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data); - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); + List<InstanceLightmapData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapData::PairInfo>::Element *>(udata); - List<InstanceLightmapCaptureData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapCaptureData::PairInfo>::Element *>(udata); - - geom->lightmap_captures.erase(E->get().L); - lightmap_capture->geometries.erase(E); - ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + geom->lightmap_captures.erase(E->get().L); + lightmap_data->geometries.erase(E); + ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture + } } else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -286,7 +270,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta geom->gi_probes_dirty = true; } else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); Set<Instance *>::Element *E = reinterpret_cast<Set<Instance *>::Element *>(udata); @@ -295,7 +278,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta } RID RenderingServerScene::scenario_create() { - Scenario *scenario = memnew(Scenario); ERR_FAIL_COND_V(!scenario, RID()); RID scenario_rid = scenario_owner.make_rid(scenario); @@ -314,35 +296,30 @@ RID RenderingServerScene::scenario_create() { } void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->debug = p_debug_mode; } void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->environment = p_environment; } void RenderingServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->camera_effects = p_camera_effects; } void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); scenario->fallback_environment = p_environment; } void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); RSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count); @@ -351,20 +328,21 @@ void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, in /* INSTANCING API */ void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) { - - if (p_update_aabb) + if (p_update_aabb) { p_instance->update_aabb = true; - if (p_update_dependencies) + } + if (p_update_dependencies) { p_instance->update_dependencies = true; + } - if (p_instance->update_item.in_list()) + if (p_instance->update_item.in_list()) { return; + } _instance_update_list.add(&p_instance->update_item); } RID RenderingServerScene::instance_create() { - Instance *instance = memnew(Instance); ERR_FAIL_COND_V(!instance, RID()); @@ -375,7 +353,6 @@ RID RenderingServerScene::instance_create() { } void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -391,7 +368,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { switch (instance->base_type) { case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); #ifdef DEBUG_ENABLED if (light->geometries.size()) { @@ -405,7 +381,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { RSG::scene_render->free(light->instance); } break; case RS::INSTANCE_REFLECTION_PROBE: { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data); RSG::scene_render->free(reflection_probe->instance); if (reflection_probe->update_list.in_list()) { @@ -413,21 +388,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { } } break; case RS::INSTANCE_DECAL: { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data); RSG::scene_render->free(decal->instance); } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(instance->base_data); + case RS::INSTANCE_LIGHTMAP: { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data); //erase dependencies, since no longer a lightmap - while (lightmap_capture->users.front()) { - instance_set_use_lightmap(lightmap_capture->users.front()->get()->self, RID(), RID()); + while (lightmap_data->users.front()) { + instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0); } } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); #ifdef DEBUG_ENABLED if (gi_probe->geometries.size()) { @@ -443,14 +415,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { gi_probe_update_list.remove(&gi_probe->update_element); } - if (instance->lightmap_capture) { - Instance *capture = (Instance *)instance->lightmap_capture; - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(capture->base_data); - lightmap_capture->users.erase(instance); - instance->lightmap_capture = nullptr; - instance->lightmap = RID(); - } - RSG::scene_render->free(gi_probe->probe_instance); } break; @@ -471,13 +435,11 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { instance->base = RID(); if (p_base.is_valid()) { - instance->base_type = RSG::storage->get_base_type(p_base); ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE); switch (instance->base_type) { case RS::INSTANCE_LIGHT: { - InstanceLightData *light = memnew(InstanceLightData); if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) { @@ -492,7 +454,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_MULTIMESH: case RS::INSTANCE_IMMEDIATE: case RS::INSTANCE_PARTICLES: { - InstanceGeometryData *geom = memnew(InstanceGeometryData); instance->base_data = geom; if (instance->base_type == RS::INSTANCE_MESH) { @@ -500,7 +461,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { } } break; case RS::INSTANCE_REFLECTION_PROBE: { - InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData); reflection_probe->owner = instance; instance->base_data = reflection_probe; @@ -508,21 +468,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base); } break; case RS::INSTANCE_DECAL: { - InstanceDecalData *decal = memnew(InstanceDecalData); decal->owner = instance; instance->base_data = decal; decal->instance = RSG::scene_render->decal_instance_create(p_base); } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { - - InstanceLightmapCaptureData *lightmap_capture = memnew(InstanceLightmapCaptureData); - instance->base_data = lightmap_capture; - //lightmap_capture->instance = RSG::scene_render->lightmap_capture_instance_create(p_base); + case RS::INSTANCE_LIGHTMAP: { + InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData); + instance->base_data = lightmap_data; + //lightmap_data->instance = RSG::scene_render->lightmap_data_instance_create(p_base); } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData); instance->base_data = gi_probe; gi_probe->owner = instance; @@ -546,13 +503,12 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) { _instance_queue_update(instance, true, true); } -void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { +void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); if (instance->scenario) { - instance->scenario->instances.remove(&instance->scenario_item); if (instance->octree_id) { @@ -561,9 +517,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } switch (instance->base_type) { - case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); #ifdef DEBUG_ENABLED if (light->geometries.size()) { @@ -581,7 +535,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); #ifdef DEBUG_ENABLED @@ -607,7 +560,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } if (p_scenario.is_valid()) { - Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND(!scenario); @@ -616,9 +568,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) scenario->instances.add(&instance->scenario_item); switch (instance->base_type) { - case RS::INSTANCE_LIGHT: { - InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data); if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) { @@ -626,7 +576,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) } } break; case RS::INSTANCE_GI_PROBE: { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data); if (!gi_probe->update_element.in_list()) { gi_probe_update_list.add(&gi_probe->update_element); @@ -639,20 +588,21 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) _instance_queue_update(instance, true, true); } } -void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { +void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->layer_mask = p_mask; } -void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) { +void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->transform == p_transform) + if (instance->transform == p_transform) { return; //must be checked to avoid worst evil + } #ifdef DEBUG_ENABLED @@ -670,15 +620,15 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor instance->transform = p_transform; _instance_queue_update(instance, true); } -void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { +void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->object_id = p_id; } -void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { +void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -691,7 +641,6 @@ void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p } void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -708,12 +657,12 @@ void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_s } void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->visible == p_visible) + if (instance->visible == p_visible) { return; + } instance->visible = p_visible; @@ -736,9 +685,9 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) } } break; - case RS::INSTANCE_LIGHTMAP_CAPTURE: { + case RS::INSTANCE_LIGHTMAP: { if (instance->octree_id && instance->scenario) { - instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP_CAPTURE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); + instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0); } } break; @@ -752,49 +701,24 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) } } } + inline bool is_geometry_instance(RenderingServer::InstanceType p_type) { return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE; } -void RenderingServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap) { - - Instance *instance = instance_owner.getornull(p_instance); - ERR_FAIL_COND(!instance); - - if (instance->lightmap_capture) { - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data); - lightmap_capture->users.erase(instance); - instance->lightmap = RID(); - instance->lightmap_capture = nullptr; - } - - if (p_lightmap_instance.is_valid()) { - Instance *lightmap_instance = instance_owner.getornull(p_lightmap_instance); - ERR_FAIL_COND(!lightmap_instance); - ERR_FAIL_COND(lightmap_instance->base_type != RS::INSTANCE_LIGHTMAP_CAPTURE); - instance->lightmap_capture = lightmap_instance; - - InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data); - lightmap_capture->users.insert(instance); - instance->lightmap = p_lightmap; - } -} - void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); if (p_aabb != AABB()) { - // Set custom AABB - if (instance->custom_aabb == nullptr) + if (instance->custom_aabb == nullptr) { instance->custom_aabb = memnew(AABB); + } *instance->custom_aabb = p_aabb; } else { - // Clear custom AABB if (instance->custom_aabb != nullptr) { memdelete(instance->custom_aabb); @@ -802,17 +726,18 @@ void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) } } - if (instance->scenario) + if (instance->scenario) { _instance_queue_update(instance, true, false); + } } void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); - if (instance->skeleton == p_skeleton) + if (instance->skeleton == p_skeleton) { return; + } instance->skeleton = p_skeleton; @@ -835,7 +760,6 @@ void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance, } Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { - Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -847,19 +771,19 @@ Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, R culled = scenario->octree.cull_aabb(p_aabb, cull, 1024); for (int i = 0; i < culled; i++) { - Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { +Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -872,16 +796,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, for (int i = 0; i < culled; i++) { Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } return instances; } -Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { +Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.getornull(p_scenario); ERR_FAIL_COND_V(!scenario, instances); @@ -893,11 +818,11 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> culled = scenario->octree.cull_convex(p_convex, cull, 1024); for (int i = 0; i < culled; i++) { - Instance *instance = cull[i]; ERR_CONTINUE(!instance); - if (instance->object_id.is_null()) + if (instance->object_id.is_null()) { continue; + } instances.push_back(instance->object_id); } @@ -906,21 +831,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> } void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) { - Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); //ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK)); switch (p_flags) { - case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: { - instance->baked_light = p_enabled; } break; case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: { - if (p_enabled == instance->dynamic_gi) { //bye, redundant return; @@ -938,7 +859,6 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan } break; case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: { - instance->redraw_if_visible = p_enabled; } break; @@ -946,16 +866,16 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan } } } -void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { +void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); instance->cast_shadows = p_shadow_casting_setting; _instance_queue_update(instance, false, true); } -void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) { +void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -965,11 +885,33 @@ void RenderingServerScene::instance_geometry_set_material_override(RID p_instanc void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { } + void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { } -void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { +void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { + Instance *instance = instance_owner.getornull(p_instance); + ERR_FAIL_COND(!instance); + + if (instance->lightmap) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data); + lightmap_data->users.erase(instance); + instance->lightmap = nullptr; + } + + Instance *lightmap_instance = instance_owner.getornull(p_lightmap); + instance->lightmap = lightmap_instance; + instance->lightmap_uv_scale = p_lightmap_uv_scale; + instance->lightmap_slice_index = p_slice_index; + + if (lightmap_instance) { + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data); + lightmap_data->users.insert(instance); + } +} + +void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) { Instance *instance = instance_owner.getornull(p_instance); ERR_FAIL_COND(!instance); @@ -991,7 +933,6 @@ void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance } Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1002,7 +943,6 @@ Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_insta } Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const { - const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance); ERR_FAIL_COND_V(!instance, Variant()); @@ -1030,11 +970,9 @@ void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_ins } void RenderingServerScene::_update_instance(Instance *p_instance) { - p_instance->version++; if (p_instance->base_type == RS::INSTANCE_LIGHT) { - InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); RSG::scene_render->light_instance_set_transform(light->instance, p_instance->transform); @@ -1042,7 +980,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); RSG::scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform); @@ -1050,21 +987,18 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if (p_instance->base_type == RS::INSTANCE_DECAL) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data); RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_GI_PROBE) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data); RSG::scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform); } if (p_instance->base_type == RS::INSTANCE_PARTICLES) { - RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform); } @@ -1073,7 +1007,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); //make sure lights are updated if it casts shadow @@ -1084,16 +1017,28 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } } - if (!p_instance->lightmap_capture && geom->lightmap_captures.size()) { + if (!p_instance->lightmap && geom->lightmap_captures.size()) { //affected by lightmap captures, must update capture info! _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 + if (!p_instance->lightmap_sh.empty()) { + p_instance->lightmap_sh.clear(); //don't need SH + p_instance->lightmap_target_sh.clear(); //don't need SH } } } + if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) { + //if this moved, update the captured objects + InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data); + //erase dependencies, since no longer a lightmap + + for (List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) { + Instance *geom = E->get().geometry; + _instance_queue_update(geom, true, false); + } + } + p_instance->mirror = p_instance->transform.basis.determinant() < 0.0; AABB new_aabb; @@ -1103,18 +1048,15 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { p_instance->transformed_aabb = new_aabb; if (!p_instance->scenario) { - return; } if (p_instance->octree_id == 0) { - uint32_t base_type = 1 << p_instance->base_type; uint32_t pairable_mask = 0; bool pairable = false; - if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) { - + if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP) { pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0; pairable = true; } @@ -1129,7 +1071,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { p_instance->octree_id = p_instance->scenario->octree.create(p_instance, new_aabb, 0, pairable, base_type, pairable_mask); } else { - /* if (new_aabb==p_instance->data.transformed_aabb) return; @@ -1140,72 +1081,65 @@ void RenderingServerScene::_update_instance(Instance *p_instance) { } void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { - AABB new_aabb; ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid()); switch (p_instance->base_type) { case RenderingServer::INSTANCE_NONE: { - // do nothing } break; case RenderingServer::INSTANCE_MESH: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); + } } break; case RenderingServer::INSTANCE_MULTIMESH: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_IMMEDIATE: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->immediate_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_PARTICLES: { - - if (p_instance->custom_aabb) + if (p_instance->custom_aabb) { new_aabb = *p_instance->custom_aabb; - else + } else { new_aabb = RSG::storage->particles_get_aabb(p_instance->base); + } } break; case RenderingServer::INSTANCE_LIGHT: { - new_aabb = RSG::storage->light_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_REFLECTION_PROBE: { - new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_DECAL: { - new_aabb = RSG::storage->decal_get_aabb(p_instance->base); } break; case RenderingServer::INSTANCE_GI_PROBE: { - new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base); } break; - case RenderingServer::INSTANCE_LIGHTMAP_CAPTURE: { - - new_aabb = RSG::storage->lightmap_capture_get_bounds(p_instance->base); + case RenderingServer::INSTANCE_LIGHTMAP: { + new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base); } break; default: { @@ -1213,247 +1147,92 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) { } // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs - if (p_instance->extra_margin) + if (p_instance->extra_margin) { new_aabb.grow_by(p_instance->extra_margin); + } p_instance->aabb = new_aabb; } -_FORCE_INLINE_ static void _light_capture_sample_octree(const RasterizerStorage::LightmapCaptureOctree *p_octree, int p_cell_subdiv, const Vector3 &p_pos, const Vector3 &p_dir, float p_level, Vector3 &r_color, float &r_alpha) { - - static const Vector3 aniso_normal[6] = { - Vector3(-1, 0, 0), - Vector3(1, 0, 0), - Vector3(0, -1, 0), - Vector3(0, 1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, 1) - }; - - int size = 1 << (p_cell_subdiv - 1); - - int clamp_v = size - 1; - //first of all, clamp - Vector3 pos; - pos.x = CLAMP(p_pos.x, 0, clamp_v); - pos.y = CLAMP(p_pos.y, 0, clamp_v); - pos.z = CLAMP(p_pos.z, 0, clamp_v); - - float level = (p_cell_subdiv - 1) - p_level; - - int target_level; - float level_filter; - if (level <= 0.0) { - level_filter = 0; - target_level = 0; - } else { - target_level = Math::ceil(level); - level_filter = target_level - level; - } - - Vector3 color[2][8]; - float alpha[2][8]; - zeromem(alpha, sizeof(float) * 2 * 8); - - //find cell at given level first - - for (int c = 0; c < 2; c++) { - - int current_level = MAX(0, target_level - c); - int level_cell_size = (1 << (p_cell_subdiv - 1)) >> current_level; - - for (int n = 0; n < 8; n++) { - - int x = int(pos.x); - int y = int(pos.y); - int z = int(pos.z); +void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) { + bool first_set = p_instance->lightmap_sh.size() == 0; + p_instance->lightmap_sh.resize(9); //using SH + p_instance->lightmap_target_sh.resize(9); //using SH + Color *instance_sh = p_instance->lightmap_target_sh.ptrw(); + bool inside = false; + Color accum_sh[9]; + float accum_blend = 0.0; - if (n & 1) - x += level_cell_size; - if (n & 2) - y += level_cell_size; - if (n & 4) - z += level_cell_size; + InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { + Instance *lightmap = E->get(); - int ofs_x = 0; - int ofs_y = 0; - int ofs_z = 0; + bool interior = RSG::storage->lightmap_is_interior(lightmap->base); - x = CLAMP(x, 0, clamp_v); - y = CLAMP(y, 0, clamp_v); - z = CLAMP(z, 0, clamp_v); + if (inside && !interior) { + continue; //we are inside, ignore exteriors + } - int half = size / 2; - uint32_t cell = 0; - for (int i = 0; i < current_level; i++) { + Transform to_bounds = lightmap->transform.affine_inverse(); + Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center - const RasterizerStorage::LightmapCaptureOctree *bc = &p_octree[cell]; + Vector3 lm_pos = to_bounds.xform(center); - int child = 0; - if (x >= ofs_x + half) { - child |= 1; - ofs_x += half; - } - if (y >= ofs_y + half) { - child |= 2; - ofs_y += half; - } - if (z >= ofs_z + half) { - child |= 4; - ofs_z += half; - } + AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base); + if (!bounds.has_point(lm_pos)) { + continue; //not in this lightmap + } - cell = bc->children[child]; - if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY) - break; + Color sh[9]; + RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh); - half >>= 1; + //rotate it + Basis rot = lightmap->transform.basis.orthonormalized(); + for (int i = 0; i < 3; i++) { + float csh[9]; + for (int j = 0; j < 9; j++) { + csh[j] = sh[j][i]; } - - if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY) { - alpha[c][n] = 0; - } else { - alpha[c][n] = p_octree[cell].alpha; - - for (int i = 0; i < 6; i++) { - //anisotropic read light - float amount = p_dir.dot(aniso_normal[i]); - if (amount < 0) - amount = 0; - color[c][n].x += p_octree[cell].light[i][0] / 1024.0 * amount; - color[c][n].y += p_octree[cell].light[i][1] / 1024.0 * amount; - color[c][n].z += p_octree[cell].light[i][2] / 1024.0 * amount; - } + rot.rotate_sh(csh); + for (int j = 0; j < 9; j++) { + sh[j][i] = csh[j]; } - - //print_line("\tlev " + itos(c) + " - " + itos(n) + " alpha: " + rtos(cells[test_cell].alpha) + " col: " + color[c][n]); } - } - - float target_level_size = size >> target_level; - Vector3 pos_fract[2]; - - pos_fract[0].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[0].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[0].z = Math::fmod(pos.z, target_level_size) / target_level_size; - - target_level_size = size >> MAX(0, target_level - 1); - - pos_fract[1].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[1].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[1].z = Math::fmod(pos.z, target_level_size) / target_level_size; - float alpha_interp[2]; - Vector3 color_interp[2]; + Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0); - for (int i = 0; i < 2; i++) { - - Vector3 color_x00 = color[i][0].linear_interpolate(color[i][1], pos_fract[i].x); - Vector3 color_xy0 = color[i][2].linear_interpolate(color[i][3], pos_fract[i].x); - Vector3 blend_z0 = color_x00.linear_interpolate(color_xy0, pos_fract[i].y); - - Vector3 color_x0z = color[i][4].linear_interpolate(color[i][5], pos_fract[i].x); - Vector3 color_xyz = color[i][6].linear_interpolate(color[i][7], pos_fract[i].x); - Vector3 blend_z1 = color_x0z.linear_interpolate(color_xyz, pos_fract[i].y); - - color_interp[i] = blend_z0.linear_interpolate(blend_z1, pos_fract[i].z); - - float alpha_x00 = Math::lerp(alpha[i][0], alpha[i][1], pos_fract[i].x); - float alpha_xy0 = Math::lerp(alpha[i][2], alpha[i][3], pos_fract[i].x); - float alpha_z0 = Math::lerp(alpha_x00, alpha_xy0, pos_fract[i].y); - - float alpha_x0z = Math::lerp(alpha[i][4], alpha[i][5], pos_fract[i].x); - float alpha_xyz = Math::lerp(alpha[i][6], alpha[i][7], pos_fract[i].x); - float alpha_z1 = Math::lerp(alpha_x0z, alpha_xyz, pos_fract[i].y); - - alpha_interp[i] = Math::lerp(alpha_z0, alpha_z1, pos_fract[i].z); - } - - 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)); -} - -_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) { - - float bias = 0.0; //no need for bias here - float max_distance = (Vector3(1, 1, 1) * (1 << (p_cell_subdiv - 1))).length(); - - float dist = bias; - float alpha = 0.0; - Vector3 color; - - Vector3 scolor; - float salpha; - - while (dist < max_distance && alpha < 0.95) { - float diameter = MAX(1.0, 2.0 * p_aperture * dist); - _light_capture_sample_octree(p_octree, p_cell_subdiv, p_pos + dist * p_dir, p_dir, log2(diameter), scolor, salpha); - float a = (1.0 - alpha); - color += scolor * a; - alpha += a * salpha; - dist += diameter * 0.5; - } - - return Color(color.x, color.y, color.z, alpha); -} - -void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) { - - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); + float blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z)); + //make blend more rounded + blend = Math::lerp(inner_pos.length(), blend, blend); + blend *= blend; + blend = MAX(0.0, 1.0 - blend); - static const Vector3 cone_traces[12] = { - Vector3(0, 0, 1), - Vector3(0.866025, 0, 0.5), - Vector3(0.267617, 0.823639, 0.5), - Vector3(-0.700629, 0.509037, 0.5), - Vector3(-0.700629, -0.509037, 0.5), - Vector3(0.267617, -0.823639, 0.5), - Vector3(0, 0, -1), - Vector3(0.866025, 0, -0.5), - Vector3(0.267617, 0.823639, -0.5), - Vector3(-0.700629, 0.509037, -0.5), - Vector3(-0.700629, -0.509037, -0.5), - Vector3(0.267617, -0.823639, -0.5) - }; - - float cone_aperture = 0.577; // tan(angle) 60 degrees - - if (p_instance->lightmap_capture_data.empty()) { - p_instance->lightmap_capture_data.resize(12); + if (interior && !inside) { + //do not blend, just replace + for (int j = 0; j < 9; j++) { + accum_sh[j] = sh[j] * blend; + } + accum_blend = blend; + inside = true; + } else { + for (int j = 0; j < 9; j++) { + accum_sh[j] += sh[j] * blend; + } + accum_blend += blend; + } } - //print_line("update captures for pos: " + p_instance->transform.origin); - - for (int i = 0; i < 12; i++) - new (&p_instance->lightmap_capture_data.ptrw()[i]) Color; - - //this could use some sort of blending.. - for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { - const Vector<RasterizerStorage::LightmapCaptureOctree> *octree = RSG::storage->lightmap_capture_get_octree_ptr(E->get()->base); - //print_line("octree size: " + itos(octree->size())); - if (octree->size() == 0) - continue; - Transform to_cell_xform = RSG::storage->lightmap_capture_get_octree_cell_transform(E->get()->base); - int cell_subdiv = RSG::storage->lightmap_capture_get_octree_cell_subdiv(E->get()->base); - to_cell_xform = to_cell_xform * E->get()->transform.affine_inverse(); - - const RasterizerStorage::LightmapCaptureOctree *octree_r = octree->ptr(); - - Vector3 pos = to_cell_xform.xform(p_instance->transform.origin); - - for (int i = 0; i < 12; i++) { - - Vector3 dir = to_cell_xform.basis.xform(cone_traces[i]).normalized(); - Color capture = _light_capture_voxel_cone_trace(octree_r, pos, dir, cone_aperture, cell_subdiv); - p_instance->lightmap_capture_data.write[i] += capture; + if (accum_blend > 0.0) { + for (int j = 0; j < 9; j++) { + instance_sh[j] = accum_sh[j] / accum_blend; + if (first_set) { + p_instance->lightmap_sh.write[j] = instance_sh[j]; + } } } } bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) { - InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform light_transform = p_instance->transform; @@ -1462,9 +1241,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c bool animated_material_found = false; switch (RSG::storage->light_get_type(p_instance->base)) { - case RS::LIGHT_DIRECTIONAL: { - real_t max_distance = p_cam_projection.get_z_far(); real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera @@ -1489,7 +1266,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t z_min = 1e20; for (int i = 0; i < cull_count; i++) { - Instance *instance = instance_shadow_cull_result[i]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { continue; @@ -1523,9 +1299,15 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c int splits = 0; switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) { - case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: splits = 1; break; - case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: splits = 2; break; - case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break; + case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: + splits = 1; + break; + case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: + splits = 2; + break; + case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: + splits = 4; + break; } real_t distances[5]; @@ -1546,7 +1328,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0; for (int i = 0; i < splits; i++) { - RENDER_TIMESTAMP("Culling Directional Light split" + itos(i)); // setup a camera matrix for that range! @@ -1555,12 +1336,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t aspect = p_cam_projection.get_aspect(); if (p_cam_orthogonal) { - Vector2 vp_he = p_cam_projection.get_viewport_half_extents(); camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } else { - real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); } @@ -1597,25 +1376,30 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //used for culling for (int j = 0; j < 8; j++) { - real_t d_x = x_vec.dot(endpoints[j]); real_t d_y = y_vec.dot(endpoints[j]); real_t d_z = z_vec.dot(endpoints[j]); - if (j == 0 || d_x < x_min) + if (j == 0 || d_x < x_min) { x_min = d_x; - if (j == 0 || d_x > x_max) + } + if (j == 0 || d_x > x_max) { x_max = d_x; + } - if (j == 0 || d_y < y_min) + if (j == 0 || d_y < y_min) { y_min = d_y; - if (j == 0 || d_y > y_max) + } + if (j == 0 || d_y > y_max) { y_max = d_y; + } - if (j == 0 || d_z < z_min) + if (j == 0 || d_z < z_min) { z_min = d_z; - if (j == 0 || d_z > z_max) + } + if (j == 0 || d_z > z_max) { z_max = d_z; + } } real_t radius = 0; @@ -1626,7 +1410,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //camera viewport stuff for (int j = 0; j < 8; j++) { - center += endpoints[j]; } center /= 8.0; @@ -1634,10 +1417,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c //center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5; for (int j = 0; j < 8; j++) { - real_t d = center.distance_to(endpoints[j]); - if (d > radius) + if (d > radius) { radius = d; + } } radius *= texture_size / (texture_size - 2.0); //add a texel by each side @@ -1651,11 +1434,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c z_min_cam = z_vec.dot(center) - radius; { - float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE); if (soft_shadow_angle > 0.0 && pancake_size > 0.0) { - float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam; soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range; @@ -1708,7 +1489,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t cull_max = 0; for (int j = 0; j < cull_count; j++) { - real_t min, max; Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { @@ -1735,14 +1515,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } if (aspect != 1.0) { - // if the aspect is different, then the radius will become larger. // if this happens, then bias needs to be adjusted too, as depth will increase // to do this, compare the depth of one that would have resulted from a square frustum CameraMatrix camera_matrix_square; if (p_cam_orthogonal) { - Vector2 vp_he = camera_matrix.get_viewport_half_extents(); if (p_cam_vaspect) { camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true); @@ -1756,10 +1534,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } else { camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false); } - - if (i == 0) { - //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents()); - } } Vector3 endpoints_square[8]; // frustum plane endpoints @@ -1769,13 +1543,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t z_max_square = 0; for (int j = 0; j < 8; j++) { - center_square += endpoints_square[j]; real_t d_z = z_vec.dot(endpoints_square[j]); - if (j == 0 || d_z > z_max_square) + if (j == 0 || d_z > z_max_square) { z_max_square = d_z; + } } if (cull_max > z_max_square) { @@ -1787,10 +1561,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t radius_square = 0; for (int j = 0; j < 8; j++) { - real_t d = center_square.distance_to(endpoints_square[j]); - if (d > radius_square) + if (d > radius_square) { radius_square = d; + } } radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side @@ -1809,7 +1583,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } { - CameraMatrix ortho_camera; real_t half_x = (x_max_cam - x_min_cam) * 0.5; real_t half_y = (y_max_cam - y_min_cam) * 0.5; @@ -1836,13 +1609,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } break; case RS::LIGHT_OMNI: { - RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base); if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::scene_render->light_instances_can_render_shadow_cube()) { - for (int i = 0; i < 2; i++) { - //using this one ensures that raster deferred will have it RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); @@ -1850,18 +1620,18 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c real_t z = i == 0 ? -1 : 1; Vector<Plane> planes; - planes.resize(5); + planes.resize(6); planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius)); planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius)); planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius)); planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius)); planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius)); + planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0)); int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK); Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1887,7 +1657,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c cm.set_perspective(90, 1, 0.01, radius); for (int i = 0; i < 6; i++) { - RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i)); //using this one ensures that raster deferred will have it @@ -1916,7 +1685,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(xform.origin, -xform.basis.get_axis(2)); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1941,7 +1709,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c } break; case RS::LIGHT_SPOT: { - RENDER_TIMESTAMP("Culling Spot Light"); real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); @@ -1955,7 +1722,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2)); for (int j = 0; j < cull_count; j++) { - Instance *instance = instance_shadow_cull_result[j]; if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { cull_count--; @@ -1992,7 +1758,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID switch (camera->type) { case Camera::ORTHOGONAL: { - camera_matrix.set_orthogonal( camera->size, p_viewport_size.width / (float)p_viewport_size.height, @@ -2002,7 +1767,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID ortho = true; } break; case Camera::PERSPECTIVE: { - camera_matrix.set_perspective( camera->fov, p_viewport_size.width / (float)p_viewport_size.height, @@ -2013,7 +1777,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID } break; case Camera::FRUSTUM: { - camera_matrix.set_frustum( camera->size, p_viewport_size.width / (float)p_viewport_size.height, @@ -2140,6 +1903,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const reflection_probe_cull_count = 0; decal_cull_count = 0; gi_probe_cull_count = 0; + lightmap_cull_count = 0; //light_samplers_culled=0; @@ -2154,9 +1918,10 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const //removed, will replace with culling /* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */ + uint64_t frame_number = RSG::rasterizer->get_frame_number(); + float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time(); for (int i = 0; i < instance_cull_count; i++) { - Instance *ins = instance_cull_result[i]; bool keep = false; @@ -2164,9 +1929,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const if ((camera_layer_mask & ins->layer_mask) == 0) { //failure } else if (ins->base_type == RS::INSTANCE_LIGHT && ins->visible) { - if (light_cull_count < MAX_LIGHTS_CULLED) { - InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data); if (!light->geometries.empty()) { @@ -2181,9 +1944,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } } else if (ins->base_type == RS::INSTANCE_REFLECTION_PROBE && ins->visible) { - if (reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data); if (p_reflection_probe != reflection_probe->instance) { @@ -2209,9 +1970,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } } else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) { - if (decal_cull_count < MAX_DECALS_CULLED) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data); if (!decal->geometries.empty()) { @@ -2222,7 +1981,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } } else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(ins->base_data); if (!gi_probe->update_element.in_list()) { gi_probe_update_list.add(&gi_probe->update_element); @@ -2232,9 +1990,13 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const gi_probe_instance_cull_result[gi_probe_cull_count] = gi_probe->probe_instance; gi_probe_cull_count++; } + } else if (ins->base_type == RS::INSTANCE_LIGHTMAP && ins->visible) { + if (lightmap_cull_count < MAX_LIGHTMAPS_CULLED) { + lightmap_cull_result[lightmap_cull_count] = ins; + lightmap_cull_count++; + } } else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) { - keep = true; InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data); @@ -2261,7 +2023,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->light_instances.resize(geom->lighting.size()); for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); ins->light_instances.write[l++] = light->instance; @@ -2276,7 +2037,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->reflection_probe_instances.resize(geom->reflection_probes.size()); for (List<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); ins->reflection_probe_instances.write[l++] = reflection_probe->instance; @@ -2291,7 +2051,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const ins->gi_probe_instances.resize(geom->gi_probes.size()); for (List<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) { - InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data); ins->gi_probe_instances.write[l++] = gi_probe->probe_instance; @@ -2300,6 +2059,14 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const geom->gi_probes_dirty = false; } + if (ins->last_frame_pass != frame_number && !ins->lightmap_target_sh.empty() && !ins->lightmap_sh.empty()) { + Color *sh = ins->lightmap_sh.ptrw(); + const Color *target_sh = ins->lightmap_target_sh.ptr(); + for (uint32_t j = 0; j < 9; j++) { + sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); + } + } + ins->depth = near_plane.distance_to(ins->transform.origin); ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15); } @@ -2311,9 +2078,9 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const i--; ins->last_render_pass = 0; // make invalid } else { - ins->last_render_pass = render_pass; } + ins->last_frame_pass = frame_number; } /* STEP 5 - PROCESS LIGHTS */ @@ -2323,18 +2090,17 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const // directional lights { - Instance **lights_with_shadow = (Instance **)alloca(sizeof(Instance *) * scenario->directional_lights.size()); int directional_shadow_count = 0; for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) { - if (light_cull_count + directional_light_count >= MAX_LIGHTS_CULLED) { break; } - if (!E->get()->visible) + if (!E->get()->visible) { continue; + } InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); @@ -2352,7 +2118,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const RSG::scene_render->set_directional_shadow_count(directional_shadow_count); for (int i = 0; i < directional_shadow_count; i++) { - RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i)); _light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario); @@ -2366,11 +2131,11 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const //SortArray<Instance*,_InstanceLightsort> sorter; //sorter.sort(light_cull_result,light_cull_count); for (int i = 0; i < light_cull_count; i++) { - Instance *ins = light_cull_result[i]; - if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) + if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) { continue; + } InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data); @@ -2386,9 +2151,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents(); switch (RSG::storage->light_get_type(ins->base)) { - case RS::LIGHT_OMNI: { - float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE); //get two points parallel to near plane @@ -2412,7 +2175,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y); } break; case RS::LIGHT_SPOT: { - float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE); float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE); @@ -2465,18 +2227,18 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const } void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) { - Scenario *scenario = scenario_owner.getornull(p_scenario); /* ENVIRONMENT */ RID environment; - if (p_force_environment.is_valid()) //camera has more environment priority + if (p_force_environment.is_valid()) { //camera has more environment priority environment = p_force_environment; - else if (scenario->environment.is_valid()) + } else if (scenario->environment.is_valid()) { environment = scenario->environment; - else + } else { environment = scenario->fallback_environment; + } RID camera_effects; if (p_force_camera_effects.is_valid()) { @@ -2487,27 +2249,26 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p /* PROCESS GEOMETRY AND DRAW SCENE */ RENDER_TIMESTAMP("Render Scene "); - RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); + RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RasterizerScene::InstanceBase **)lightmap_cull_result, lightmap_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass); } void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) { - #ifndef _3D_DISABLED Scenario *scenario = scenario_owner.getornull(p_scenario); RID environment; - if (scenario->environment.is_valid()) + if (scenario->environment.is_valid()) { environment = scenario->environment; - else + } else { environment = scenario->fallback_environment; + } RENDER_TIMESTAMP("Render Empty Scene "); - RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); + RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0); #endif } bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data); Scenario *scenario = p_instance->scenario; ERR_FAIL_COND_V(!scenario, true); @@ -2515,14 +2276,12 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i RenderingServerRaster::redraw_request(); //update, so it updates in editor if (p_step == 0) { - if (!RSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) { return true; //all full } } if (p_step >= 0 && p_step < 6) { - static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -2562,7 +2321,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base); if (use_shadows) { - shadow_atlas = scenario->reflection_probe_shadow_atlas; } @@ -2580,7 +2338,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i } void RenderingServerScene::render_probes() { - /* REFLECTION PROBES */ SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first(); @@ -2588,15 +2345,14 @@ void RenderingServerScene::render_probes() { bool busy = false; while (ref_probe) { - SelfList<InstanceReflectionProbeData> *next = ref_probe->next(); RID base = ref_probe->self()->owner->base; switch (RSG::storage->reflection_probe_get_update_mode(base)) { - case RS::REFLECTION_PROBE_UPDATE_ONCE: { - if (busy) //already rendering something + if (busy) { //already rendering something break; + } bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step); if (done) { @@ -2608,7 +2364,6 @@ void RenderingServerScene::render_probes() { busy = true; //do not render another one of this kind } break; case RS::REFLECTION_PROBE_UPDATE_ALWAYS: { - int step = 0; bool done = false; while (!done) { @@ -2632,7 +2387,6 @@ void RenderingServerScene::render_probes() { } while (gi_probe) { - SelfList<InstanceGIProbeData> *next = gi_probe->next(); InstanceGIProbeData *probe = gi_probe->self(); @@ -2643,7 +2397,6 @@ void RenderingServerScene::render_probes() { bool cache_dirty = false; int cache_count = 0; { - int light_cache_size = probe->light_cache.size(); const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr(); const RID *instance_caches = probe->light_instances.ptr(); @@ -2660,7 +2413,6 @@ void RenderingServerScene::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; if ( @@ -2683,7 +2435,6 @@ void RenderingServerScene::render_probes() { } for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) { - Instance *instance = E->get(); InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { @@ -2694,7 +2445,6 @@ void RenderingServerScene::render_probes() { } else if (idx >= light_cache_size) { cache_dirty = true; } else { - const InstanceGIProbeData::LightCache *cache = &caches[idx]; if ( @@ -2801,7 +2551,6 @@ void RenderingServerScene::render_probes() { ins->gi_probe_instances.resize(geom->gi_probes.size()); for (List<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) { - InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data); ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance; @@ -2823,7 +2572,6 @@ void RenderingServerScene::render_probes() { } void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) { - List<RasterizerStorage::InstanceShaderParam> plist; RSG::storage->material_get_instance_shader_parameters(p_material, &plist); for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) { @@ -2852,13 +2600,11 @@ void RenderingServerScene::_update_instance_shader_parameters_from_material(Map< } void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { - if (p_instance->update_aabb) { _update_instance_aabb(p_instance); } if (p_instance->update_dependencies) { - p_instance->instance_increase_version(); if (p_instance->base.is_valid()) { @@ -2885,7 +2631,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); bool can_cast_shadows = true; @@ -2903,7 +2648,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { is_animated = RSG::storage->material_is_animated(p_instance->material_override); _update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override); } else { - if (p_instance->base_type == RS::INSTANCE_MESH) { RID mesh = p_instance->base; @@ -2911,13 +2655,11 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { bool cast_shadows = false; for (int i = 0; i < p_instance->materials.size(); i++) { - RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -2940,19 +2682,16 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) { RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base); if (mesh.is_valid()) { - bool cast_shadows = false; int sc = RSG::storage->mesh_get_surface_count(mesh); for (int i = 0; i < sc; i++) { - RID mat = RSG::storage->mesh_surface_get_material(mesh, i); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -2973,7 +2712,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { RSG::storage->base_update_dependency(mesh, p_instance); } } else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) { - RID mat = RSG::storage->immediate_get_material(p_instance->base); if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) { @@ -2993,26 +2731,23 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } } else if (p_instance->base_type == RS::INSTANCE_PARTICLES) { - bool cast_shadows = false; int dp = RSG::storage->particles_get_draw_passes(p_instance->base); for (int i = 0; i < dp; i++) { - RID mesh = RSG::storage->particles_get_draw_pass_mesh(p_instance->base, i); - if (!mesh.is_valid()) + if (!mesh.is_valid()) { continue; + } int sc = RSG::storage->mesh_get_surface_count(mesh); for (int j = 0; j < sc; j++) { - RID mat = RSG::storage->mesh_surface_get_material(mesh, j); if (!mat.is_valid()) { cast_shadows = true; } else { - if (RSG::storage->material_casts_shadows(mat)) { cast_shadows = true; } @@ -3079,26 +2814,21 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) { } void RenderingServerScene::update_dirty_instances() { - RSG::storage->update_dirty_resources(); while (_instance_update_list.first()) { - _update_dirty_instance(_instance_update_list.first()->self()); } } bool RenderingServerScene::free(RID p_rid) { - if (camera_owner.owns(p_rid)) { - Camera *camera = camera_owner.getornull(p_rid); camera_owner.free(p_rid); memdelete(camera); } else if (scenario_owner.owns(p_rid)) { - Scenario *scenario = scenario_owner.getornull(p_rid); while (scenario->instances.first()) { @@ -3116,7 +2846,7 @@ bool RenderingServerScene::free(RID p_rid) { Instance *instance = instance_owner.getornull(p_rid); - instance_set_use_lightmap(p_rid, RID(), RID()); + instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0); instance_set_scenario(p_rid, RID()); instance_set_base(p_rid, RID()); instance_geometry_set_material_override(p_rid, RID()); @@ -3137,10 +2867,13 @@ bool RenderingServerScene::free(RID p_rid) { return true; } +TypedArray<Image> RenderingServerScene::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { + return RSG::scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size); +} + RenderingServerScene *RenderingServerScene::singleton = nullptr; RenderingServerScene::RenderingServerScene() { - render_pass = 1; singleton = this; } diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index db2fbd6707..f2e2918f21 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -33,7 +33,6 @@ #include "servers/rendering/rasterizer.h" -#include "core/math/geometry.h" #include "core/math/octree.h" #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -51,6 +50,7 @@ public: MAX_DECALS_CULLED = 4096, MAX_GI_PROBES_CULLED = 4096, MAX_ROOM_CULL = 32, + MAX_LIGHTMAPS_CULLED = 4096, MAX_EXTERIOR_PORTALS = 128, }; @@ -61,7 +61,6 @@ public: /* CAMERA API */ struct Camera { - enum Type { PERSPECTIVE, ORTHOGONAL, @@ -80,9 +79,8 @@ public: Transform transform; Camera() { - visible_layers = 0xFFFFFFFF; - fov = 70; + fov = 75; type = PERSPECTIVE; znear = 0.05; zfar = 100; @@ -109,7 +107,6 @@ public: struct Instance; struct Scenario { - RS::ScenarioDebugMode debug; RID self; @@ -143,12 +140,10 @@ public: /* INSTANCING API */ struct InstanceBaseData { - virtual ~InstanceBaseData() {} }; struct Instance : RasterizerScene::InstanceBase { - RID self; //scenario stuff OctreeElementID octree_id; @@ -171,6 +166,8 @@ public: float lod_end_hysteresis; RID lod_instance; + Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior + uint64_t last_render_pass; uint64_t last_frame_pass; @@ -195,7 +192,6 @@ public: Instance() : scenario_item(this), update_item(this) { - octree_id = 0; scenario = nullptr; @@ -220,11 +216,12 @@ public: } ~Instance() { - - if (base_data) + if (base_data) { memdelete(base_data); - if (custom_aabb) + } + if (custom_aabb) { memdelete(custom_aabb); + } } }; @@ -232,7 +229,6 @@ public: void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); struct InstanceGeometryData : public InstanceBaseData { - List<Instance *> lighting; bool lighting_dirty; bool can_cast_shadows; @@ -250,7 +246,6 @@ public: List<Instance *> lightmap_captures; InstanceGeometryData() { - lighting_dirty = false; reflection_dirty = true; can_cast_shadows = true; @@ -261,7 +256,6 @@ public: }; struct InstanceReflectionProbeData : public InstanceBaseData { - Instance *owner; struct PairInfo { @@ -278,14 +272,12 @@ public: InstanceReflectionProbeData() : update_list(this) { - reflection_dirty = true; render_step = -1; } }; struct InstanceDecalData : public InstanceBaseData { - Instance *owner; RID instance; @@ -302,7 +294,6 @@ public: SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list; struct InstanceLightData : public InstanceBaseData { - struct PairInfo { List<Instance *>::Element *L; //light iterator in geometry Instance *geometry; @@ -319,7 +310,6 @@ public: Instance *baked_light; InstanceLightData() { - shadow_dirty = true; D = nullptr; last_version = 0; @@ -328,7 +318,6 @@ public: }; struct InstanceGIProbeData : public InstanceBaseData { - Instance *owner; struct PairInfo { @@ -342,7 +331,6 @@ public: Set<Instance *> lights; struct LightCache { - RS::LightType type; Transform transform; Color color; @@ -374,8 +362,7 @@ public: SelfList<InstanceGIProbeData>::List gi_probe_update_list; - struct InstanceLightmapCaptureData : public InstanceBaseData { - + struct InstanceLightmapData : public InstanceBaseData { struct PairInfo { List<Instance *>::Element *L; //iterator in geometry Instance *geometry; @@ -384,7 +371,7 @@ public: Set<Instance *> users; - InstanceLightmapCaptureData() { + InstanceLightmapData() { } }; @@ -401,6 +388,8 @@ public: int decal_cull_count; RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED]; int gi_probe_cull_count; + Instance *lightmap_cull_result[MAX_LIGHTS_CULLED]; + int lightmap_cull_count; RID_PtrOwner<Instance> instance_owner; @@ -414,7 +403,6 @@ public: virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight); virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material); virtual void instance_set_visible(RID p_instance, bool p_visible); - virtual void instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap); virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb); @@ -434,6 +422,7 @@ public: virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin); virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance); + virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material); @@ -460,6 +449,8 @@ public: void render_probes(); + TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size); + bool free(RID p_rid); RenderingServerScene(); diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp index 6fb8f6ca63..48be6ca13b 100644 --- a/servers/rendering/rendering_server_viewport.cpp +++ b/servers/rendering/rendering_server_viewport.cpp @@ -36,7 +36,6 @@ #include "rendering_server_scene.h" static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) { - Transform2D xf = p_viewport->global_transform; float scale = 1.0; @@ -63,7 +62,6 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi } void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) { - RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); Ref<XRInterface> xr_interface; @@ -80,7 +78,6 @@ void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p } void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) { - if (p_viewport->measure_render_time) { String rt_id = "vp_begin_" + itos(p_viewport->self.get_id()); RSG::storage->capture_timestamp(rt_id); @@ -95,7 +92,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: Color bgcolor = RSG::storage->get_default_clear_color(); if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->scenario_owner.owns(p_viewport->scenario)) { - RenderingServerScene::Scenario *scenario = RSG::scene->scenario_owner.getornull(p_viewport->scenario); ERR_FAIL_COND(!scenario); if (RSG::scene_render->is_environment(scenario->environment)) { @@ -143,7 +139,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RENDER_TIMESTAMP("Cull Canvas Lights"); for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); @@ -151,7 +146,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: //find lights in canvas for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { - RasterizerCanvas::Light *cl = F->get(); if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. @@ -163,7 +157,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: cl->xform_cache = xf * cl->xform; if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { - cl->filter_next_ptr = lights; lights = cl; // cl->texture_cache = nullptr; @@ -173,7 +166,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: cl->light_shader_xform = cl->xform * scale; //cl->light_shader_pos = cl->xform_cache[2]; if (cl->use_shadow) { - cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == nullptr) { shadow_rect = cl->xform_cache.xform(cl->rect_cache); @@ -209,17 +201,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: //make list of occluders for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size); for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { - - if (!F->get()->enabled) + if (!F->get()->enabled) { continue; + } F->get()->xform_cache = xf * F->get()->xform; if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { - F->get()->next = occluders; occluders = F->get(); } @@ -229,7 +219,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: RasterizerCanvas::Light *light = lights_with_shadow; while (light) { - RENDER_TIMESTAMP("Render Shadow"); RSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders); @@ -250,7 +239,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) { - RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas); Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size); @@ -304,7 +292,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface:: } void RenderingServerViewport::draw_viewports() { - timestamp_vp_map.clear(); // get our xr interface in case we need it @@ -335,8 +322,9 @@ void RenderingServerViewport::draw_viewports() { Viewport *vp = active_viewports[i]; - if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) + if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) { continue; + } if (!vp->render_target.is_valid()) { continue; @@ -368,7 +356,6 @@ void RenderingServerViewport::draw_viewports() { } for (int i = 0; i < active_viewports.size(); i++) { - Viewport *vp = active_viewports[i]; if (vp->last_pass != draw_viewports_pass) { @@ -470,7 +457,6 @@ void RenderingServerViewport::draw_viewports() { } RID RenderingServerViewport::viewport_create() { - Viewport *viewport = memnew(Viewport); RID rid = viewport_owner.make_rid(viewport); @@ -493,7 +479,6 @@ void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) } void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) { - ERR_FAIL_COND(p_width < 0 && p_height < 0); Viewport *viewport = viewport_owner.getornull(p_viewport); @@ -512,7 +497,6 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int } void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -525,7 +509,6 @@ void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) } void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -533,7 +516,6 @@ void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p } void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -541,7 +523,6 @@ void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::Viewpo } void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -549,7 +530,6 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re // If using GLES2 we can optimize this operation by rendering directly to system_fbo // instead of rendering to fbo and copying to system_fbo after if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - RSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y); RSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y); } @@ -557,10 +537,8 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re viewport->viewport_to_screen_rect = p_rect; viewport->viewport_to_screen = p_screen; } else { - // if render_direct_to_screen was used, reset size and position if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) { - RSG::storage->render_target_set_position(viewport->render_target, 0, 0); RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); } @@ -574,12 +552,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); - if (p_enable == viewport->viewport_render_direct_to_screen) + if (p_enable == viewport->viewport_render_direct_to_screen) { return; + } // if disabled, reset render_target size and position if (!p_enable) { - RSG::storage->render_target_set_position(viewport->render_target, 0, 0); RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y); } @@ -589,14 +567,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor // if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) { - RSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y); RSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y); } } void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -604,7 +580,6 @@ void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::Viewp } RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const { - const Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, RID()); @@ -612,21 +587,20 @@ RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const { } void RenderingServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_scenario = p_hide; } -void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { +void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->hide_canvas = p_hide; } -void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { +void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -634,21 +608,20 @@ void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, b } void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->camera = p_camera; } -void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { +void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->scenario = p_scenario; } -void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { +void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -664,7 +637,6 @@ void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canva } void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -674,16 +646,16 @@ void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canva viewport->canvas_map.erase(p_canvas); canvas->viewports.erase(p_viewport); } -void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { +void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) { 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].transform = p_offset; } -void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { +void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -692,14 +664,13 @@ void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport } void RenderingServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->global_transform = p_transform; } -void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) { +void RenderingServerViewport::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); @@ -709,7 +680,6 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p } void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -719,7 +689,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int } void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -727,7 +696,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID } void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -754,18 +722,17 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V } int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) { - ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1); Viewport *viewport = viewport_owner.getornull(p_viewport); - if (!viewport) + if (!viewport) { return 0; //there should be a lock here.. + } return viewport->render_info[p_info]; } void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -773,7 +740,6 @@ void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::Viewpo } void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); @@ -781,7 +747,6 @@ void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, b } float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); @@ -789,7 +754,6 @@ float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewp } float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const { - Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND_V(!viewport, 0); @@ -797,9 +761,7 @@ float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewp } bool RenderingServerViewport::free(RID p_rid) { - if (viewport_owner.owns(p_rid)) { - Viewport *viewport = viewport_owner.getornull(p_rid); RSG::storage->free(viewport->render_target); @@ -825,7 +787,6 @@ bool RenderingServerViewport::free(RID p_rid) { } void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) { - RID *vp = timestamp_vp_map.getptr(p_timestamp); if (!vp) { return; diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h index fcba7886c5..0b90646e4f 100644 --- a/servers/rendering/rendering_server_viewport.h +++ b/servers/rendering/rendering_server_viewport.h @@ -43,7 +43,6 @@ public: }; struct Viewport { - RID self; RID parent; @@ -89,12 +88,12 @@ public: bool transparent_bg; struct CanvasKey { - int64_t stacking; RID canvas; bool operator<(const CanvasKey &p_canvas) const { - if (stacking == p_canvas.stacking) + if (stacking == p_canvas.stacking) { return canvas < p_canvas.canvas; + } return stacking < p_canvas.stacking; } CanvasKey() { @@ -109,7 +108,6 @@ public: }; struct CanvasData { - CanvasBase *canvas; Transform2D transform; int layer; @@ -154,12 +152,10 @@ public: struct ViewportSort { _FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const { - bool left_to_screen = p_left->viewport_to_screen_rect.size != Size2(); bool right_to_screen = p_right->viewport_to_screen_rect.size != Size2(); if (left_to_screen == right_to_screen) { - return p_right->parent == p_left->self; } return (right_to_screen ? 0 : 1) < (left_to_screen ? 0 : 1); diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp index 4ca13dbef9..9aa6593cbe 100644 --- a/servers/rendering/rendering_server_wrap_mt.cpp +++ b/servers/rendering/rendering_server_wrap_mt.cpp @@ -34,32 +34,26 @@ #include "servers/display_server.h" void RenderingServerWrapMT::thread_exit() { - exit = true; } void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) { - if (!atomic_decrement(&draw_pending)) { - rendering_server->draw(p_swap_buffers, frame_step); } } void RenderingServerWrapMT::thread_flush() { - atomic_decrement(&draw_pending); } void RenderingServerWrapMT::_thread_callback(void *_instance) { - RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance); vsmt->thread_loop(); } void RenderingServerWrapMT::thread_loop() { - server_thread = Thread::get_caller_id(); DisplayServer::get_singleton()->make_rendering_thread(); @@ -81,33 +75,25 @@ void RenderingServerWrapMT::thread_loop() { /* EVENT QUEUING */ void RenderingServerWrapMT::sync() { - if (create_thread) { - atomic_increment(&draw_pending); command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush); } else { - command_queue.flush_all(); //flush all pending from other threads } } void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) { - if (create_thread) { - atomic_increment(&draw_pending); command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step); } else { - rendering_server->draw(p_swap_buffers, frame_step); } } void RenderingServerWrapMT::init() { - if (create_thread) { - print_verbose("RenderingServerWrapMT: Creating render thread"); DisplayServer::get_singleton()->release_rendering_thread(); if (create_thread) { @@ -119,13 +105,11 @@ void RenderingServerWrapMT::init() { } print_verbose("RenderingServerWrapMT: Finished render thread"); } else { - rendering_server->init(); } } void RenderingServerWrapMT::finish() { - sky_free_cached_ids(); shader_free_cached_ids(); material_free_cached_ids(); @@ -138,7 +122,7 @@ void RenderingServerWrapMT::finish() { spot_light_free_cached_ids(); reflection_probe_free_cached_ids(); gi_probe_free_cached_ids(); - lightmap_capture_free_cached_ids(); + lightmap_free_cached_ids(); particles_free_cached_ids(); camera_free_cached_ids(); viewport_free_cached_ids(); @@ -152,7 +136,6 @@ void RenderingServerWrapMT::finish() { canvas_occluder_polygon_free_cached_ids(); if (thread) { - command_queue.push(this, &RenderingServerWrapMT::thread_exit); Thread::wait_to_finish(thread); memdelete(thread); @@ -164,7 +147,6 @@ void RenderingServerWrapMT::finish() { } void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) { - singleton_mt->call_set_use_vsync(p_enable); } @@ -172,7 +154,6 @@ RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr; RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) : command_queue(p_create_thread) { - singleton_mt = this; DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly @@ -191,7 +172,6 @@ RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool } RenderingServerWrapMT::~RenderingServerWrapMT() { - memdelete(rendering_server); //finish(); } diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index d4e58485b8..a746aa52b2 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -36,7 +36,6 @@ #include "servers/rendering_server.h" class RenderingServerWrapMT : public RenderingServer { - // the real visual server mutable RenderingServer *rendering_server; @@ -92,7 +91,7 @@ public: //these also go pass-through virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); } - virtual RID texture_2d_layered_placeholder_create() { return rendering_server->texture_2d_layered_placeholder_create(); } + virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); } virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); } FUNC1RC(Ref<Image>, texture_2d_get, RID) @@ -324,19 +323,17 @@ public: /* LIGHTMAP CAPTURE */ - FUNCRID(lightmap_capture) - - FUNC2(lightmap_capture_set_bounds, RID, const AABB &) - FUNC1RC(AABB, lightmap_capture_get_bounds, RID) + FUNCRID(lightmap) + FUNC3(lightmap_set_textures, RID, RID, bool) + FUNC2(lightmap_set_probe_bounds, RID, const AABB &) + FUNC2(lightmap_set_probe_interior, RID, bool) + FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &) + FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID) + FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID) + FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID) - FUNC2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &) - FUNC1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID) - FUNC2(lightmap_capture_set_octree_cell_transform, RID, const Transform &) - FUNC1RC(Transform, lightmap_capture_get_octree_cell_transform, RID) - FUNC2(lightmap_capture_set_octree_cell_subdiv, RID, int) - FUNC1RC(int, lightmap_capture_get_octree_cell_subdiv, RID) - FUNC2(lightmap_capture_set_energy, RID, float) - FUNC1RC(float, lightmap_capture_get_energy, RID) + FUNC1(lightmap_set_probe_capture_update_speed, float) /* PARTICLES */ @@ -442,6 +439,7 @@ public: FUNC2(sky_set_radiance_size, RID, int) FUNC2(sky_set_mode, RID, SkyMode) FUNC2(sky_set_material, RID, RID) + FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &) /* ENVIRONMENT API */ @@ -478,6 +476,8 @@ public: FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float) FUNC5(environment_set_fog_height, RID, bool, float, float, float) + FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) + FUNC2(screen_space_roughness_limiter_set_active, bool, float) FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality) FUNC2(sub_surface_scattering_set_scale, float, float) @@ -511,7 +511,6 @@ public: FUNC3(instance_set_blend_shape_weight, RID, int, float) FUNC3(instance_set_surface_material, RID, int, RID) FUNC2(instance_set_visible, RID, bool) - FUNC3(instance_set_use_lightmap, RID, RID, RID) FUNC2(instance_set_custom_aabb, RID, AABB) @@ -531,12 +530,17 @@ public: FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) FUNC2(instance_geometry_set_as_instance_lod, RID, RID) + FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int) FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &) FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &) FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &) FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *) + /* BAKE */ + + FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &) + /* CANVAS (2D) */ FUNCRID(canvas) diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index bec0958f71..2ec65b7ea8 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -34,22 +34,18 @@ #include "servers/rendering_server.h" static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } static bool _is_number(CharType c) { - return (c >= '0' && c <= '9'); } static bool _is_hex(CharType c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } String ShaderLanguage::get_operator_text(Operator p_op) { - static const char *op_names[OP_MAX] = { "==", "!=", "<", @@ -132,6 +128,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "TYPE_ISAMPLER3D", "TYPE_USAMPLER3D", "TYPE_SAMPLERCUBE", + "TYPE_SAMPLERCUBEARRAY", "INTERPOLATION_FLAT", "INTERPOLATION_SMOOTH", "CONST", @@ -225,7 +222,6 @@ const char *ShaderLanguage::token_names[TK_MAX] = { }; String ShaderLanguage::get_token_text(Token p_token) { - String name = token_names[p_token.type]; if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_REAL_CONSTANT) { name += "(" + rtos(p_token.constant) + ")"; @@ -239,7 +235,6 @@ String ShaderLanguage::get_token_text(Token p_token) { } ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type, const StringName &p_text) { - Token tk; tk.type = p_type; tk.text = p_text; @@ -283,6 +278,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { { TK_TYPE_ISAMPLER3D, "isampler3D" }, { TK_TYPE_USAMPLER3D, "usampler3D" }, { TK_TYPE_SAMPLERCUBE, "samplerCube" }, + { TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray" }, { TK_INTERPOLATION_FLAT, "flat" }, { TK_INTERPOLATION_SMOOTH, "smooth" }, { TK_CONST, "const" }, @@ -338,13 +334,11 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { }; ShaderLanguage::Token ShaderLanguage::_get_token() { - #define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0)) while (true) { char_idx++; switch (GETCHAR(-1)) { - case 0: return _make_token(TK_EOF); case 0xFFFF: @@ -357,7 +351,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { tk_line++; continue; case '/': { - switch (GETCHAR(0)) { case '*': { // block comment @@ -405,7 +398,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { continue; //a comment, continue to next token } break; case '=': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_EQUAL); @@ -494,7 +486,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_BIT_AND); } break; case '|': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_BIT_OR); @@ -506,7 +497,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } break; case '*': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_MUL); @@ -514,12 +504,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_MUL); } break; case '+': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_ADD); } else if (GETCHAR(0) == '+') { - char_idx++; return _make_token(TK_OP_INCREMENT); } @@ -527,12 +515,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_ADD); } break; case '-': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_SUB); } else if (GETCHAR(0) == '-') { - char_idx++; return _make_token(TK_OP_DECREMENT); } @@ -540,7 +526,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_SUB); } break; case '%': { - if (GETCHAR(0) == '=') { char_idx++; return _make_token(TK_OP_ASSIGN_MOD); @@ -549,7 +534,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_MOD); } break; default: { - char_idx--; //go back one, since we have no idea what this is if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) { @@ -565,32 +549,38 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { while (true) { if (GETCHAR(i) == '.') { - if (period_found || exponent_found || hexa_found || float_suffix_found) + if (period_found || exponent_found || hexa_found || float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } period_found = true; } else if (GETCHAR(i) == 'x') { - if (hexa_found || str.length() != 1 || str[0] != '0') + if (hexa_found || str.length() != 1 || str[0] != '0') { return _make_token(TK_ERROR, "Invalid numeric constant"); + } hexa_found = true; } else if (GETCHAR(i) == 'e') { - if (hexa_found || exponent_found || float_suffix_found) + if (hexa_found || exponent_found || float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } exponent_found = true; } else if (GETCHAR(i) == 'f') { - if (hexa_found || exponent_found) + if (hexa_found || exponent_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } float_suffix_found = true; } else if (_is_number(GETCHAR(i))) { - if (float_suffix_found) + if (float_suffix_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } } else if (hexa_found && _is_hex(GETCHAR(i))) { - } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) { - if (sign_found) + if (sign_found) { return _make_token(TK_ERROR, "Invalid numeric constant"); + } sign_found = true; - } else + } else { break; + } str += CharType(GETCHAR(i)); i++; @@ -646,10 +636,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx += str.length(); Token tk; - if (period_found || exponent_found || float_suffix_found) + if (period_found || exponent_found || float_suffix_found) { tk.type = TK_REAL_CONSTANT; - else + } else { tk.type = TK_INT_CONSTANT; + } if (hexa_found) { tk.constant = (double)str.hex_to_int64(true); @@ -672,7 +663,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { String str; while (_is_text_char(GETCHAR(0))) { - str += CharType(GETCHAR(0)); char_idx++; } @@ -682,9 +672,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { int idx = 0; while (keyword_list[idx].text) { - if (str == keyword_list[idx].text) { - return _make_token(keyword_list[idx].token); } idx++; @@ -695,10 +683,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_IDENTIFIER, str); } - if (GETCHAR(0) > 32) + if (GETCHAR(0) > 32) { return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'"); - else + } else { return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0))); + } } break; } @@ -710,7 +699,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { } String ShaderLanguage::token_debug(const String &p_code) { - clear(); code = p_code; @@ -719,7 +707,6 @@ String ShaderLanguage::token_debug(const String &p_code) { Token tk = _get_token(); while (tk.type != TK_EOF && tk.type != TK_ERROR) { - output += itos(tk_line) + ": " + get_token_text(tk) + "\n"; tk = _get_token(); } @@ -752,7 +739,6 @@ bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) { } bool ShaderLanguage::is_token_datatype(TokenType p_type) { - return ( p_type == TK_TYPE_VOID || p_type == TK_TYPE_BOOL || @@ -783,31 +769,29 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) { p_type == TK_TYPE_SAMPLER3D || p_type == TK_TYPE_ISAMPLER3D || p_type == TK_TYPE_USAMPLER3D || - p_type == TK_TYPE_SAMPLERCUBE); + p_type == TK_TYPE_SAMPLERCUBE || + p_type == TK_TYPE_SAMPLERCUBEARRAY); } ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { - return DataType(p_type - TK_TYPE_VOID); } bool ShaderLanguage::is_token_interpolation(TokenType p_type) { - return ( p_type == TK_INTERPOLATION_FLAT || p_type == TK_INTERPOLATION_SMOOTH); } ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) { - - if (p_type == TK_INTERPOLATION_FLAT) + if (p_type == TK_INTERPOLATION_FLAT) { return INTERPOLATION_FLAT; - else + } else { return INTERPOLATION_SMOOTH; + } } bool ShaderLanguage::is_token_precision(TokenType p_type) { - return ( p_type == TK_PRECISION_LOW || p_type == TK_PRECISION_MID || @@ -815,20 +799,23 @@ bool ShaderLanguage::is_token_precision(TokenType p_type) { } ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) { - - if (p_type == TK_PRECISION_LOW) + if (p_type == TK_PRECISION_LOW) { return PRECISION_LOWP; - else if (p_type == TK_PRECISION_HIGH) + } else if (p_type == TK_PRECISION_HIGH) { return PRECISION_HIGHP; - else + } else { return PRECISION_MEDIUMP; + } } String ShaderLanguage::get_precision_name(DataPrecision p_type) { switch (p_type) { - case PRECISION_LOWP: return "lowp"; - case PRECISION_MEDIUMP: return "mediump"; - case PRECISION_HIGHP: return "highp"; + case PRECISION_LOWP: + return "lowp"; + case PRECISION_MEDIUMP: + return "mediump"; + case PRECISION_HIGHP: + return "highp"; default: break; } @@ -836,53 +823,83 @@ String ShaderLanguage::get_precision_name(DataPrecision p_type) { } String ShaderLanguage::get_datatype_name(DataType p_type) { - switch (p_type) { - - case TYPE_VOID: return "void"; - case TYPE_BOOL: return "bool"; - case TYPE_BVEC2: return "bvec2"; - case TYPE_BVEC3: return "bvec3"; - case TYPE_BVEC4: return "bvec4"; - case TYPE_INT: return "int"; - case TYPE_IVEC2: return "ivec2"; - case TYPE_IVEC3: return "ivec3"; - case TYPE_IVEC4: return "ivec4"; - case TYPE_UINT: return "uint"; - case TYPE_UVEC2: return "uvec2"; - case TYPE_UVEC3: return "uvec3"; - case TYPE_UVEC4: return "uvec4"; - case TYPE_FLOAT: return "float"; - case TYPE_VEC2: return "vec2"; - case TYPE_VEC3: return "vec3"; - case TYPE_VEC4: return "vec4"; - case TYPE_MAT2: return "mat2"; - case TYPE_MAT3: return "mat3"; - case TYPE_MAT4: return "mat4"; - case TYPE_SAMPLER2D: return "sampler2D"; - case TYPE_ISAMPLER2D: return "isampler2D"; - case TYPE_USAMPLER2D: return "usampler2D"; - case TYPE_SAMPLER2DARRAY: return "sampler2DArray"; - case TYPE_ISAMPLER2DARRAY: return "isampler2DArray"; - case TYPE_USAMPLER2DARRAY: return "usampler2DArray"; - case TYPE_SAMPLER3D: return "sampler3D"; - case TYPE_ISAMPLER3D: return "isampler3D"; - case TYPE_USAMPLER3D: return "usampler3D"; - case TYPE_SAMPLERCUBE: return "samplerCube"; - case TYPE_STRUCT: return "struct"; - case TYPE_MAX: return "invalid"; + case TYPE_VOID: + return "void"; + case TYPE_BOOL: + return "bool"; + case TYPE_BVEC2: + return "bvec2"; + case TYPE_BVEC3: + return "bvec3"; + case TYPE_BVEC4: + return "bvec4"; + case TYPE_INT: + return "int"; + case TYPE_IVEC2: + return "ivec2"; + case TYPE_IVEC3: + return "ivec3"; + case TYPE_IVEC4: + return "ivec4"; + case TYPE_UINT: + return "uint"; + case TYPE_UVEC2: + return "uvec2"; + case TYPE_UVEC3: + return "uvec3"; + case TYPE_UVEC4: + return "uvec4"; + case TYPE_FLOAT: + return "float"; + case TYPE_VEC2: + return "vec2"; + case TYPE_VEC3: + return "vec3"; + case TYPE_VEC4: + return "vec4"; + case TYPE_MAT2: + return "mat2"; + case TYPE_MAT3: + return "mat3"; + case TYPE_MAT4: + return "mat4"; + case TYPE_SAMPLER2D: + return "sampler2D"; + case TYPE_ISAMPLER2D: + return "isampler2D"; + case TYPE_USAMPLER2D: + return "usampler2D"; + case TYPE_SAMPLER2DARRAY: + return "sampler2DArray"; + case TYPE_ISAMPLER2DARRAY: + return "isampler2DArray"; + case TYPE_USAMPLER2DARRAY: + return "usampler2DArray"; + case TYPE_SAMPLER3D: + return "sampler3D"; + case TYPE_ISAMPLER3D: + return "isampler3D"; + case TYPE_USAMPLER3D: + return "usampler3D"; + case TYPE_SAMPLERCUBE: + return "samplerCube"; + case TYPE_SAMPLERCUBEARRAY: + return "samplerCubeArray"; + case TYPE_STRUCT: + return "struct"; + case TYPE_MAX: + return "invalid"; } return ""; } bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { - return is_token_datatype(p_type) && p_type != TK_TYPE_VOID; } void ShaderLanguage::clear() { - current_function = StringName(); completion_type = COMPLETION_NONE; @@ -904,9 +921,7 @@ void ShaderLanguage::clear() { } bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) { - if (p_builtin_types.has(p_identifier)) { - if (r_data_type) { *r_data_type = p_builtin_types[p_identifier].type; } @@ -923,7 +938,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea FunctionNode *function = nullptr; while (p_block) { - if (p_block->variables.has(p_identifier)) { if (r_data_type) { *r_data_type = p_block->variables[p_identifier].type; @@ -1010,9 +1024,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea } for (int i = 0; i < shader->functions.size(); i++) { - - if (!shader->functions[i].callable) + if (!shader->functions[i].callable) { continue; + } if (shader->functions[i].name == p_identifier) { if (r_data_type) { @@ -1029,7 +1043,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea } bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) { - bool valid = false; DataType ret_type = TYPE_VOID; @@ -1062,7 +1075,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_NOT: { - DataType na = p_op->arguments[0]->get_datatype(); valid = na == TYPE_BOOL; ret_type = TYPE_BOOL; @@ -1201,7 +1213,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SHIFT_RIGHT: case OP_SHIFT_LEFT: case OP_SHIFT_RIGHT: { - DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1263,7 +1274,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SUB: case OP_ASSIGN_MUL: case OP_ASSIGN_DIV: { - DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1323,7 +1333,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_BIT_AND: case OP_BIT_OR: case OP_BIT_XOR: { - /* * The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type * signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If @@ -1403,8 +1412,9 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } - if (r_ret_type) + if (r_ret_type) { *r_ret_type = ret_type; + } return valid; } @@ -2011,6 +2021,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, + { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false }, { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, @@ -2032,6 +2043,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false }, { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false }, + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2062,6 +2075,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, + { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false }, { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2093,6 +2107,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true }, { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true }, { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true }, @@ -2125,7 +2140,6 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] }; bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) { - ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false); Vector<DataType> args; @@ -2151,18 +2165,15 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin int idx = 0; while (builtin_func_defs[idx].name) { - if (completion_class != builtin_func_defs[idx].tag) { idx++; continue; } if (name == builtin_func_defs[idx].name) { - failed_builtin = true; bool fail = false; for (int i = 0; i < argcount; i++) { - if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) { //all good, but needs implicit conversion later } else if (args[i] != builtin_func_defs[idx].args[i]) { @@ -2181,20 +2192,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } } - if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) + if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) { fail = true; //make sure the number of arguments matches + } 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 && p_func->arguments[arg_idx + 1]->type != Node::TYPE_MEMBER && p_func->arguments[arg_idx + 1]->type != Node::TYPE_ARRAY) { _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable, array or member."); return false; @@ -2282,7 +2291,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } //implicitly convert values if possible for (int i = 0; i < argcount; i++) { - if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) { //can't do implicit conversion here continue; @@ -2299,8 +2307,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin p_func->arguments.write[i + 1] = conversion; } - if (r_ret_type) + if (r_ret_type) { *r_ret_type = builtin_func_defs[idx].rettype; + } return true; } @@ -2311,7 +2320,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } if (unsupported_builtin) { - String arglist = ""; for (int i = 0; i < argcount; i++) { if (i > 0) { @@ -2328,8 +2336,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin if (failed_builtin) { String err = "Invalid arguments for built-in function: " + String(name) + "("; for (int i = 0; i < argcount; i++) { - if (i > 0) + if (i > 0) { err += ","; + } if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) { err += "-"; @@ -2347,7 +2356,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin BlockNode *block = p_block; while (block) { - if (block->parent_function) { exclude_function = block->parent_function->name; } @@ -2360,9 +2368,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } for (int i = 0; i < shader->functions.size(); i++) { - - if (name != shader->functions[i].name) + if (name != shader->functions[i].name) { continue; + } if (!shader->functions[i].callable) { _set_error("Function '" + String(name) + " can't be called from source code."); @@ -2371,8 +2379,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin FunctionNode *pfunc = shader->functions[i].function; - if (pfunc->arguments.size() != args.size()) + if (pfunc->arguments.size() != args.size()) { continue; + } bool fail = false; @@ -2390,10 +2399,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin } if (!fail) { - //implicitly convert values if possible for (int k = 0; k < args.size(); k++) { - if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) { //can't do implicit conversion here continue; @@ -2437,7 +2444,6 @@ bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const { } bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) { - TkPos pos = _get_tkpos(); Token tk = _get_token(); @@ -2448,16 +2454,13 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str _set_tkpos(pos); while (true) { - if (r_complete_arg) { pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_CURSOR) { - *r_complete_arg = p_func->arguments.size() - 1; } else { - _set_tkpos(pos); } } @@ -2465,7 +2468,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str Node *arg = _parse_and_reduce_expression(p_block, p_builtin_types); if (!arg) { - return false; } @@ -2474,7 +2476,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str tk = _get_token(); if (tk.type == TK_PARENTHESIS_CLOSE) { - return true; } else if (tk.type != TK_COMMA) { // something is broken @@ -2487,7 +2488,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str } bool ShaderLanguage::is_token_operator(TokenType p_type) { - return (p_type == TK_OP_EQUAL || p_type == TK_OP_NOT_EQUAL || p_type == TK_OP_LESS || @@ -2526,7 +2526,6 @@ bool ShaderLanguage::is_token_operator(TokenType p_type) { } bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) { - if (p_constant->datatype == p_to_type) { if (p_value) { for (int i = 0; i < p_constant->values.size(); i++) { @@ -2535,13 +2534,11 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty } return true; } else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_FLOAT) { - if (p_value) { p_value->real = p_constant->values[0].sint; } return true; } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_FLOAT) { - if (p_value) { p_value->real = p_constant->values[0].uint; } @@ -2555,7 +2552,6 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty } return true; } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_INT) { - if (p_constant->values[0].uint > 0x7FFFFFFF) { return false; } @@ -2563,17 +2559,16 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty p_value->sint = p_constant->values[0].uint; } return true; - } else + } else { return false; + } } bool ShaderLanguage::is_scalar_type(DataType p_type) { - return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT; } bool ShaderLanguage::is_sampler_type(DataType p_type) { - return p_type == TYPE_SAMPLER2D || p_type == TYPE_ISAMPLER2D || p_type == TYPE_USAMPLER2D || @@ -2583,7 +2578,8 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) { p_type == TYPE_SAMPLER3D || p_type == TYPE_ISAMPLER3D || p_type == TYPE_USAMPLER3D || - p_type == TYPE_SAMPLERCUBE; + p_type == TYPE_SAMPLERCUBE || + p_type == TYPE_SAMPLERCUBEARRAY; } Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) { @@ -2677,7 +2673,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C case ShaderLanguage::TYPE_USAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2D: case ShaderLanguage::TYPE_USAMPLER3D: - case ShaderLanguage::TYPE_SAMPLERCUBE: { + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { // Texture types, likely not relevant here. break; } @@ -2696,8 +2693,12 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform &p_uniform) { PropertyInfo pi; switch (p_uniform.type) { - case ShaderLanguage::TYPE_VOID: pi.type = Variant::NIL; break; - case ShaderLanguage::TYPE_BOOL: pi.type = Variant::BOOL; break; + case ShaderLanguage::TYPE_VOID: + pi.type = Variant::NIL; + break; + case ShaderLanguage::TYPE_BOOL: + pi.type = Variant::BOOL; + break; case ShaderLanguage::TYPE_BVEC2: pi.type = Variant::INT; pi.hint = PROPERTY_HINT_FLAGS; @@ -2728,7 +2729,6 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_UVEC2: case ShaderLanguage::TYPE_UVEC3: case ShaderLanguage::TYPE_UVEC4: { - pi.type = Variant::PACKED_INT32_ARRAY; } break; case ShaderLanguage::TYPE_FLOAT: { @@ -2739,8 +2739,12 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform } } break; - case ShaderLanguage::TYPE_VEC2: pi.type = Variant::VECTOR2; break; - case ShaderLanguage::TYPE_VEC3: pi.type = Variant::VECTOR3; break; + case ShaderLanguage::TYPE_VEC2: + pi.type = Variant::VECTOR2; + break; + case ShaderLanguage::TYPE_VEC3: + pi.type = Variant::VECTOR3; + break; case ShaderLanguage::TYPE_VEC4: { if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) { pi.type = Variant::COLOR; @@ -2748,13 +2752,18 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform pi.type = Variant::PLANE; } } break; - case ShaderLanguage::TYPE_MAT2: pi.type = Variant::TRANSFORM2D; break; - case ShaderLanguage::TYPE_MAT3: pi.type = Variant::BASIS; break; - case ShaderLanguage::TYPE_MAT4: pi.type = Variant::TRANSFORM; break; + case ShaderLanguage::TYPE_MAT2: + pi.type = Variant::TRANSFORM2D; + break; + case ShaderLanguage::TYPE_MAT3: + pi.type = Variant::BASIS; + break; + case ShaderLanguage::TYPE_MAT4: + pi.type = Variant::TRANSFORM; + break; case ShaderLanguage::TYPE_SAMPLER2D: case ShaderLanguage::TYPE_ISAMPLER2D: case ShaderLanguage::TYPE_USAMPLER2D: { - pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "Texture2D"; @@ -2762,10 +2771,9 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform case ShaderLanguage::TYPE_SAMPLER2DARRAY: case ShaderLanguage::TYPE_ISAMPLER2DARRAY: case ShaderLanguage::TYPE_USAMPLER2DARRAY: { - pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "TextureArray"; + pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_SAMPLER3D: case ShaderLanguage::TYPE_ISAMPLER3D: @@ -2774,11 +2782,11 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform pi.hint = PROPERTY_HINT_RESOURCE_TYPE; pi.hint_string = "Texture3D"; } break; - case ShaderLanguage::TYPE_SAMPLERCUBE: { - + case ShaderLanguage::TYPE_SAMPLERCUBE: + case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: { pi.type = Variant::OBJECT; pi.hint = PROPERTY_HINT_RESOURCE_TYPE; - pi.hint_string = "CubeMap"; + pi.hint_string = "TextureLayered"; } break; case ShaderLanguage::TYPE_STRUCT: { // FIXME: Implement this. @@ -2829,6 +2837,7 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { case TYPE_ISAMPLER3D: case TYPE_USAMPLER3D: case TYPE_SAMPLERCUBE: + case TYPE_SAMPLERCUBEARRAY: return 4; //not really, but useful for indices case TYPE_STRUCT: // FIXME: Implement. @@ -2840,13 +2849,11 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) { } void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { - Set<String> kws; int idx = 0; while (keyword_list[idx].text) { - kws.insert(keyword_list[idx].text); idx++; } @@ -2854,7 +2861,6 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { idx = 0; while (builtin_func_defs[idx].name) { - kws.insert(builtin_func_defs[idx].name); idx++; @@ -2866,13 +2872,11 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { } void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { - Set<String> kws; int idx = 0; while (builtin_func_defs[idx].name) { - kws.insert(builtin_func_defs[idx].name); idx++; @@ -2884,7 +2888,6 @@ void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { } ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) { - static const DataType scalar_types[] = { TYPE_VOID, TYPE_BOOL, @@ -2947,7 +2950,6 @@ int ShaderLanguage::get_cardinality(DataType p_type) { } bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) { - identifier = StringName(); TkPos pos = { 0, 0 }; @@ -2961,7 +2963,6 @@ bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionT } if (tk.type == TK_CURSOR) { - completion_type = p_type; completion_line = tk_line; completion_block = p_block; @@ -3004,9 +3005,7 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const { } bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) { - if (p_node->type == Node::TYPE_OPERATOR) { - OperatorNode *op = static_cast<OperatorNode *>(p_node); if (op->op == OP_INDEX) { @@ -3017,42 +3016,45 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return _validate_assign(op->arguments[1], p_builtin_types, r_message); } else if (op->op == OP_CALL) { - if (r_message) + if (r_message) { *r_message = RTR("Assignment to function."); + } return false; } } else if (p_node->type == Node::TYPE_MEMBER) { - MemberNode *member = static_cast<MemberNode *>(p_node); if (member->has_swizzling_duplicates) { - if (r_message) + if (r_message) { *r_message = RTR("Swizzling assignment contains duplicates."); + } return false; } return _validate_assign(member->owner, p_builtin_types, r_message); } else if (p_node->type == Node::TYPE_VARIABLE) { - VariableNode *var = static_cast<VariableNode *>(p_node); if (shader->uniforms.has(var->name)) { - if (r_message) + if (r_message) { *r_message = RTR("Assignment to uniform."); + } return false; } if (shader->varyings.has(var->name) && current_function != String("vertex")) { - if (r_message) + if (r_message) { *r_message = RTR("Varyings can only be assigned in vertex function."); + } return false; } if (shader->constants.has(var->name) || var->is_const) { - if (r_message) + if (r_message) { *r_message = RTR("Constants cannot be modified."); + } return false; } @@ -3060,33 +3062,34 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI return true; } } else if (p_node->type == Node::TYPE_ARRAY) { - ArrayNode *arr = static_cast<ArrayNode *>(p_node); if (arr->is_const) { - if (r_message) + if (r_message) { *r_message = RTR("Constants cannot be modified."); + } return false; } if (shader->varyings.has(arr->name) && current_function != String("vertex")) { - if (r_message) + if (r_message) { *r_message = RTR("Varyings can only be assigned in vertex function."); + } return false; } return true; } - if (r_message) + if (r_message) { *r_message = "Assignment to constant expression."; + } return false; } bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) { for (int i = 0; shader->functions.size(); i++) { if (shader->functions[i].name == p_name) { - ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false); FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument]; if (arg->tex_builtin_check) { @@ -3097,12 +3100,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) { return true; } else { - _set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using textures that differ in either filter or repeat setting."); return false; } } else { - arg->tex_argument_check = true; arg->tex_argument_filter = p_filter; arg->tex_argument_repeat = p_repeat; @@ -3119,10 +3120,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam } ERR_FAIL_V(false); //bug? function not found } + bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) { for (int i = 0; shader->functions.size(); i++) { if (shader->functions[i].name == p_name) { - ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false); FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument]; if (arg->tex_argument_check) { @@ -3137,7 +3138,6 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa return false; } } else { - arg->tex_builtin_check = true; arg->tex_builtin = p_builtin; @@ -3156,13 +3156,11 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa } ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { - Vector<Expression> expression; //Vector<TokenType> operators; while (true) { - Node *expr = nullptr; TkPos prepos = _get_tkpos(); Token tk = _get_token(); @@ -3174,19 +3172,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //handle subexpression expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return nullptr; + } tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')' in expression"); return nullptr; } } else if (tk.type == TK_REAL_CONSTANT) { - ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; v.real = tk.constant; @@ -3195,7 +3192,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_INT_CONSTANT) { - ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; v.sint = tk.constant; @@ -3204,7 +3200,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_TRUE) { - //handle true constant ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; @@ -3214,7 +3209,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_FALSE) { - //handle false constant ConstantNode *constant = alloc_node<ConstantNode>(); ConstantNode::Value v; @@ -3224,7 +3218,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = constant; } else if (tk.type == TK_TYPE_VOID) { - //make sure void is not used in expression _set_error("Void value not allowed in Expression"); return nullptr; @@ -3235,7 +3228,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons func->op = OP_CONSTRUCT; if (is_token_precision(tk.type)) { - func->return_precision_cache = get_token_precision(tk.type); tk = _get_token(); } @@ -3262,8 +3254,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons completion_argument = carg; } - if (!ok) + if (!ok) { return nullptr; + } if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); @@ -3273,7 +3266,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = _reduce_expression(p_block, func); } else if (tk.type == TK_IDENTIFIER) { - _set_tkpos(prepos); StringName identifier; @@ -3290,7 +3282,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (tk.type == TK_PARENTHESIS_OPEN) { - if (struct_init) { //a struct constructor const StringName &name = identifier; @@ -3307,7 +3298,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *nexpr; if (pstruct->members[i]->array_size != 0) { - DataType type = pstruct->members[i]->get_datatype(); String struct_name = pstruct->members[i]->struct_name; int array_size = pstruct->members[i]->array_size; @@ -3323,7 +3313,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_CURLY_BRACKET_OPEN) { auto_size = true; } else { - if (shader->structs.has(tk.text)) { type2 = TYPE_STRUCT; struct_name2 = tk.text; @@ -3406,7 +3395,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) { return nullptr; @@ -3428,10 +3416,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons an->initializer.push_back(n); break; } else { - if (auto_size) + if (auto_size) { _set_error("Expected '}' or ','"); - else + } else { _set_error("Expected ')' or ','"); + } return nullptr; } } @@ -3526,8 +3515,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons completion_argument = carg; } - if (!ok) + if (!ok) { return nullptr; + } if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) { _set_error("No matching function found for: '" + String(funcname->name) + "'"); @@ -3540,14 +3530,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons FunctionNode *call_function = shader->functions[function_index].function; if (call_function) { - //get current base function FunctionNode *base_function = nullptr; { BlockNode *b = p_block; while (b) { - if (b->parent_function) { base_function = b->parent_function; break; @@ -3669,7 +3657,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return nullptr; } } else { - if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) { _set_error("Unknown identifier in expression: " + String(identifier)); return nullptr; @@ -3697,14 +3684,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons p_block->block_tag = SubClassTag::TAG_ARRAY; call_expression = _parse_and_reduce_expression(p_block, p_builtin_types); p_block->block_tag = SubClassTag::TAG_GLOBAL; - if (!call_expression) + if (!call_expression) { return nullptr; + } data_type = call_expression->get_datatype(); } else { // indexing index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index_expression) + if (!index_expression) { return nullptr; + } if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); @@ -3741,7 +3730,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = arrname; } else { - VariableNode *varname = alloc_node<VariableNode>(); varname->name = identifier; varname->datatype_cache = data_type; @@ -3753,17 +3741,27 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } else if (tk.type == TK_OP_ADD) { continue; //this one does nothing } else if (tk.type == TK_OP_SUB || tk.type == TK_OP_NOT || tk.type == TK_OP_BIT_INVERT || tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) { - Expression e; e.is_op = true; switch (tk.type) { - case TK_OP_SUB: e.op = OP_NEGATE; break; - case TK_OP_NOT: e.op = OP_NOT; break; - case TK_OP_BIT_INVERT: e.op = OP_BIT_INVERT; break; - case TK_OP_INCREMENT: e.op = OP_INCREMENT; break; - case TK_OP_DECREMENT: e.op = OP_DECREMENT; break; - default: ERR_FAIL_V(nullptr); + case TK_OP_SUB: + e.op = OP_NEGATE; + break; + case TK_OP_NOT: + e.op = OP_NOT; + break; + case TK_OP_BIT_INVERT: + e.op = OP_BIT_INVERT; + break; + case TK_OP_INCREMENT: + e.op = OP_INCREMENT; + break; + case TK_OP_DECREMENT: + e.op = OP_DECREMENT; + break; + default: + ERR_FAIL_V(nullptr); } expression.push_back(e); @@ -3787,9 +3785,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_CURSOR) { //do nothing } else if (tk.type == TK_IDENTIFIER) { - } else if (tk.type == TK_PERIOD) { - DataType dt = expr->get_datatype(); String st = expr->get_datatype_name(); @@ -3844,7 +3840,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC2: case TYPE_UVEC2: case TYPE_VEC2: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 1); @@ -3861,7 +3856,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -3910,7 +3904,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC3: case TYPE_UVEC3: case TYPE_VEC3: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 2); @@ -3927,7 +3920,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -3979,7 +3971,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons case TYPE_IVEC4: case TYPE_UVEC4: case TYPE_VEC4: { - int l = ident.length(); if (l == 1) { member_type = DataType(dt - 3); @@ -3996,7 +3987,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons const CharType *c = ident.ptr(); for (int i = 0; i < l; i++) { - switch (c[i]) { case 'r': case 'g': @@ -4075,16 +4065,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons mn->has_swizzling_duplicates = repeated; if (array_size > 0) { - tk = _get_token(); if (tk.type == TK_PERIOD) { _set_error("Nested array length() is not yet implemented"); return nullptr; } else if (tk.type == TK_BRACKET_OPEN) { - Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index_expression) + if (!index_expression) { return nullptr; + } if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { _set_error("Only integer expressions are allowed for indexing"); @@ -4130,10 +4119,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons */ } else if (tk.type == TK_BRACKET_OPEN) { - Node *index = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!index) + if (!index) { return nullptr; + } if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) { _set_error("Only integer datatypes are allowed for indexing"); @@ -4157,12 +4146,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } switch (expr->get_datatype()) { - case TYPE_BVEC2: member_type = TYPE_BOOL; break; - case TYPE_VEC2: member_type = TYPE_FLOAT; break; - case TYPE_IVEC2: member_type = TYPE_INT; break; - case TYPE_UVEC2: member_type = TYPE_UINT; break; - case TYPE_MAT2: member_type = TYPE_VEC2; break; - default: break; + case TYPE_BVEC2: + member_type = TYPE_BOOL; + break; + case TYPE_VEC2: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC2: + member_type = TYPE_INT; + break; + case TYPE_UVEC2: + member_type = TYPE_UINT; + break; + case TYPE_MAT2: + member_type = TYPE_VEC2; + break; + default: + break; } break; @@ -4180,12 +4180,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } switch (expr->get_datatype()) { - case TYPE_BVEC3: member_type = TYPE_BOOL; break; - case TYPE_VEC3: member_type = TYPE_FLOAT; break; - case TYPE_IVEC3: member_type = TYPE_INT; break; - case TYPE_UVEC3: member_type = TYPE_UINT; break; - case TYPE_MAT3: member_type = TYPE_VEC3; break; - default: break; + case TYPE_BVEC3: + member_type = TYPE_BOOL; + break; + case TYPE_VEC3: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC3: + member_type = TYPE_INT; + break; + case TYPE_UVEC3: + member_type = TYPE_UINT; + break; + case TYPE_MAT3: + member_type = TYPE_VEC3; + break; + default: + break; } break; case TYPE_BVEC4: @@ -4202,12 +4213,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } switch (expr->get_datatype()) { - case TYPE_BVEC4: member_type = TYPE_BOOL; break; - case TYPE_VEC4: member_type = TYPE_FLOAT; break; - case TYPE_IVEC4: member_type = TYPE_INT; break; - case TYPE_UVEC4: member_type = TYPE_UINT; break; - case TYPE_MAT4: member_type = TYPE_VEC4; break; - default: break; + case TYPE_BVEC4: + member_type = TYPE_BOOL; + break; + case TYPE_VEC4: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC4: + member_type = TYPE_INT; + break; + case TYPE_UVEC4: + member_type = TYPE_UINT; + break; + case TYPE_MAT4: + member_type = TYPE_VEC4; + break; + default: + break; } break; default: { @@ -4230,7 +4252,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) { - OperatorNode *op = alloc_node<OperatorNode>(); op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT; op->arguments.push_back(expr); @@ -4246,7 +4267,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } expr = op; } else { - _set_tkpos(pos2); break; } @@ -4261,43 +4281,103 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons tk = _get_token(); if (is_token_operator(tk.type)) { - Expression o; o.is_op = true; switch (tk.type) { - - case TK_OP_EQUAL: o.op = OP_EQUAL; break; - case TK_OP_NOT_EQUAL: o.op = OP_NOT_EQUAL; break; - case TK_OP_LESS: o.op = OP_LESS; break; - case TK_OP_LESS_EQUAL: o.op = OP_LESS_EQUAL; break; - case TK_OP_GREATER: o.op = OP_GREATER; break; - case TK_OP_GREATER_EQUAL: o.op = OP_GREATER_EQUAL; break; - case TK_OP_AND: o.op = OP_AND; break; - case TK_OP_OR: o.op = OP_OR; break; - case TK_OP_ADD: o.op = OP_ADD; break; - case TK_OP_SUB: o.op = OP_SUB; break; - case TK_OP_MUL: o.op = OP_MUL; break; - case TK_OP_DIV: o.op = OP_DIV; break; - case TK_OP_MOD: o.op = OP_MOD; break; - case TK_OP_SHIFT_LEFT: o.op = OP_SHIFT_LEFT; break; - case TK_OP_SHIFT_RIGHT: o.op = OP_SHIFT_RIGHT; break; - case TK_OP_ASSIGN: o.op = OP_ASSIGN; break; - case TK_OP_ASSIGN_ADD: o.op = OP_ASSIGN_ADD; break; - case TK_OP_ASSIGN_SUB: o.op = OP_ASSIGN_SUB; break; - case TK_OP_ASSIGN_MUL: o.op = OP_ASSIGN_MUL; break; - case TK_OP_ASSIGN_DIV: o.op = OP_ASSIGN_DIV; break; - case TK_OP_ASSIGN_MOD: o.op = OP_ASSIGN_MOD; break; - case TK_OP_ASSIGN_SHIFT_LEFT: o.op = OP_ASSIGN_SHIFT_LEFT; break; - case TK_OP_ASSIGN_SHIFT_RIGHT: o.op = OP_ASSIGN_SHIFT_RIGHT; break; - case TK_OP_ASSIGN_BIT_AND: o.op = OP_ASSIGN_BIT_AND; break; - case TK_OP_ASSIGN_BIT_OR: o.op = OP_ASSIGN_BIT_OR; break; - case TK_OP_ASSIGN_BIT_XOR: o.op = OP_ASSIGN_BIT_XOR; break; - case TK_OP_BIT_AND: o.op = OP_BIT_AND; break; - case TK_OP_BIT_OR: o.op = OP_BIT_OR; break; - case TK_OP_BIT_XOR: o.op = OP_BIT_XOR; break; - case TK_QUESTION: o.op = OP_SELECT_IF; break; - case TK_COLON: o.op = OP_SELECT_ELSE; break; + case TK_OP_EQUAL: + o.op = OP_EQUAL; + break; + case TK_OP_NOT_EQUAL: + o.op = OP_NOT_EQUAL; + break; + case TK_OP_LESS: + o.op = OP_LESS; + break; + case TK_OP_LESS_EQUAL: + o.op = OP_LESS_EQUAL; + break; + case TK_OP_GREATER: + o.op = OP_GREATER; + break; + case TK_OP_GREATER_EQUAL: + o.op = OP_GREATER_EQUAL; + break; + case TK_OP_AND: + o.op = OP_AND; + break; + case TK_OP_OR: + o.op = OP_OR; + break; + case TK_OP_ADD: + o.op = OP_ADD; + break; + case TK_OP_SUB: + o.op = OP_SUB; + break; + case TK_OP_MUL: + o.op = OP_MUL; + break; + case TK_OP_DIV: + o.op = OP_DIV; + break; + case TK_OP_MOD: + o.op = OP_MOD; + break; + case TK_OP_SHIFT_LEFT: + o.op = OP_SHIFT_LEFT; + break; + case TK_OP_SHIFT_RIGHT: + o.op = OP_SHIFT_RIGHT; + break; + case TK_OP_ASSIGN: + o.op = OP_ASSIGN; + break; + case TK_OP_ASSIGN_ADD: + o.op = OP_ASSIGN_ADD; + break; + case TK_OP_ASSIGN_SUB: + o.op = OP_ASSIGN_SUB; + break; + case TK_OP_ASSIGN_MUL: + o.op = OP_ASSIGN_MUL; + break; + case TK_OP_ASSIGN_DIV: + o.op = OP_ASSIGN_DIV; + break; + case TK_OP_ASSIGN_MOD: + o.op = OP_ASSIGN_MOD; + break; + case TK_OP_ASSIGN_SHIFT_LEFT: + o.op = OP_ASSIGN_SHIFT_LEFT; + break; + case TK_OP_ASSIGN_SHIFT_RIGHT: + o.op = OP_ASSIGN_SHIFT_RIGHT; + break; + case TK_OP_ASSIGN_BIT_AND: + o.op = OP_ASSIGN_BIT_AND; + break; + case TK_OP_ASSIGN_BIT_OR: + o.op = OP_ASSIGN_BIT_OR; + break; + case TK_OP_ASSIGN_BIT_XOR: + o.op = OP_ASSIGN_BIT_XOR; + break; + case TK_OP_BIT_AND: + o.op = OP_BIT_AND; + break; + case TK_OP_BIT_OR: + o.op = OP_BIT_OR; + break; + case TK_OP_BIT_XOR: + o.op = OP_BIT_XOR; + break; + case TK_QUESTION: + o.op = OP_SELECT_IF; + break; + case TK_COLON: + o.op = OP_SELECT_ELSE; + break; default: { _set_error("Invalid token for operator: " + get_token_text(tk)); return nullptr; @@ -4315,16 +4395,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */ while (expression.size() > 1) { - int next_op = -1; int min_priority = 0xFFFFF; bool is_unary = false; bool is_ternary = false; for (int i = 0; i < expression.size(); i++) { - if (!expression[i].is_op) { - continue; } @@ -4333,14 +4410,30 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int priority; switch (expression[i].op) { - case OP_EQUAL: priority = 8; break; - case OP_NOT_EQUAL: priority = 8; break; - case OP_LESS: priority = 7; break; - case OP_LESS_EQUAL: priority = 7; break; - case OP_GREATER: priority = 7; break; - case OP_GREATER_EQUAL: priority = 7; break; - case OP_AND: priority = 12; break; - case OP_OR: priority = 14; break; + case OP_EQUAL: + priority = 8; + break; + case OP_NOT_EQUAL: + priority = 8; + break; + case OP_LESS: + priority = 7; + break; + case OP_LESS_EQUAL: + priority = 7; + break; + case OP_GREATER: + priority = 7; + break; + case OP_GREATER_EQUAL: + priority = 7; + break; + case OP_AND: + priority = 12; + break; + case OP_OR: + priority = 14; + break; case OP_NOT: priority = 3; unary = true; @@ -4349,27 +4442,69 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons priority = 3; unary = true; break; - case OP_ADD: priority = 5; break; - case OP_SUB: priority = 5; break; - case OP_MUL: priority = 4; break; - case OP_DIV: priority = 4; break; - case OP_MOD: priority = 4; break; - case OP_SHIFT_LEFT: priority = 6; break; - case OP_SHIFT_RIGHT: priority = 6; break; - case OP_ASSIGN: priority = 16; break; - case OP_ASSIGN_ADD: priority = 16; break; - case OP_ASSIGN_SUB: priority = 16; break; - case OP_ASSIGN_MUL: priority = 16; break; - case OP_ASSIGN_DIV: priority = 16; break; - case OP_ASSIGN_MOD: priority = 16; break; - case OP_ASSIGN_SHIFT_LEFT: priority = 16; break; - case OP_ASSIGN_SHIFT_RIGHT: priority = 16; break; - case OP_ASSIGN_BIT_AND: priority = 16; break; - case OP_ASSIGN_BIT_OR: priority = 16; break; - case OP_ASSIGN_BIT_XOR: priority = 16; break; - case OP_BIT_AND: priority = 9; break; - case OP_BIT_OR: priority = 11; break; - case OP_BIT_XOR: priority = 10; break; + case OP_ADD: + priority = 5; + break; + case OP_SUB: + priority = 5; + break; + case OP_MUL: + priority = 4; + break; + case OP_DIV: + priority = 4; + break; + case OP_MOD: + priority = 4; + break; + case OP_SHIFT_LEFT: + priority = 6; + break; + case OP_SHIFT_RIGHT: + priority = 6; + break; + case OP_ASSIGN: + priority = 16; + break; + case OP_ASSIGN_ADD: + priority = 16; + break; + case OP_ASSIGN_SUB: + priority = 16; + break; + case OP_ASSIGN_MUL: + priority = 16; + break; + case OP_ASSIGN_DIV: + priority = 16; + break; + case OP_ASSIGN_MOD: + priority = 16; + break; + case OP_ASSIGN_SHIFT_LEFT: + priority = 16; + break; + case OP_ASSIGN_SHIFT_RIGHT: + priority = 16; + break; + case OP_ASSIGN_BIT_AND: + priority = 16; + break; + case OP_ASSIGN_BIT_OR: + priority = 16; + break; + case OP_ASSIGN_BIT_XOR: + priority = 16; + break; + case OP_BIT_AND: + priority = 9; + break; + case OP_BIT_OR: + priority = 11; + break; + case OP_BIT_XOR: + priority = 10; + break; case OP_BIT_INVERT: priority = 3; unary = true; @@ -4410,10 +4545,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons // OK! create operator.. // OK! create operator.. if (is_unary) { - int expr_pos = next_op; while (expression[expr_pos].is_op) { - expr_pos++; if (expr_pos == expression.size()) { //can happen.. @@ -4424,11 +4557,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //consecutively do unary operators for (int i = expr_pos - 1; i >= next_op; i--) { - OperatorNode *op = alloc_node<OperatorNode>(); op->op = expression[i].op; if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) { - _set_error("Can't use increment/decrement operator in constant expression."); return nullptr; } @@ -4438,11 +4569,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[i].node = op; if (!_validate_operator(op, &op->return_cache)) { - String at; for (int j = 0; j < op->arguments.size(); j++) { - if (j > 0) + if (j > 0) { at += " and "; + } at += get_datatype_name(op->arguments[j]->get_datatype()); } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); @@ -4452,7 +4583,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else if (is_ternary) { - if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); @@ -4472,11 +4602,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[next_op - 1].is_op = false; expression.write[next_op - 1].node = op; if (!_validate_operator(op, &op->return_cache)) { - String at; for (int i = 0; i < op->arguments.size(); i++) { - if (i > 0) + if (i > 0) { at += " and "; + } at += get_datatype_name(op->arguments[i]->get_datatype()); } _set_error("Invalid argument to ternary ?: operator: " + at); @@ -4488,7 +4618,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } } else { - if (next_op < 1 || next_op >= (expression.size() - 1)) { _set_error("Parser bug..."); ERR_FAIL_V(nullptr); @@ -4498,16 +4627,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons op->op = expression[next_op].op; if (expression[next_op - 1].is_op) { - _set_error("Parser bug..."); ERR_FAIL_V(nullptr); } if (_is_operator_assign(op->op)) { - String assign_message; if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) { - _set_error(assign_message); return nullptr; } @@ -4529,11 +4655,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //replace all 3 nodes by this operator and make it an expression if (!_validate_operator(op, &op->return_cache)) { - String at; for (int i = 0; i < op->arguments.size(); i++) { - if (i > 0) + if (i > 0) { at += " and "; + } if (op->arguments[i]->get_datatype() == TYPE_STRUCT) { at += op->arguments[i]->get_datatype_name(); } else { @@ -4553,15 +4679,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) { - - if (p_node->type != Node::TYPE_OPERATOR) + if (p_node->type != Node::TYPE_OPERATOR) { return p_node; + } //for now only reduce simple constructors OperatorNode *op = static_cast<OperatorNode *>(p_node); if (op->op == OP_CONSTRUCT) { - ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node); DataType type = op->get_datatype(); @@ -4571,7 +4696,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha Vector<ConstantNode::Value> values; for (int i = 1; i < op->arguments.size(); i++) { - op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]); if (op->arguments[i]->type == Node::TYPE_CONSTANT) { ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]); @@ -4581,7 +4705,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha values.push_back(cn->values[j]); } } else if (get_scalar_type(cn->datatype) == cn->datatype) { - ConstantNode::Value v; if (!convert_constant(cn, base, &v)) { return p_node; @@ -4625,10 +4748,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha cn->values = values; return cn; } else if (op->op == OP_NEGATE) { - op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]); if (op->arguments[0]->type == Node::TYPE_CONSTANT) { - ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]); DataType base = get_scalar_type(cn->datatype); @@ -4636,7 +4757,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha Vector<ConstantNode::Value> values; for (int i = 0; i < cn->values.size(); i++) { - ConstantNode::Value nv; switch (base) { case TYPE_BOOL: { @@ -4668,10 +4788,10 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha } ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { - ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types); - if (!expr) //errored + if (!expr) { //errored return nullptr; + } expr = _reduce_expression(p_block, expr); @@ -4679,9 +4799,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_ } Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) { - while (true) { - TkPos pos = _get_tkpos(); Token tk = _get_token(); @@ -4757,7 +4875,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui Node *vardecl = nullptr; while (true) { - if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier after type"); return ERR_PARSE_ERROR; @@ -4810,7 +4927,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui if (tk.type == TK_BRACKET_CLOSE) { unknown_size = true; } else { - if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) { _set_error("Expected integer constant > 0 or ']'"); return ERR_PARSE_ERROR; @@ -4830,7 +4946,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { - if (RenderingServer::get_singleton()->is_low_end()) { _set_error("Array initialization is supported only on high-end platform!"); return ERR_PARSE_ERROR; @@ -4839,7 +4954,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); if (tk.type != TK_CURLY_BRACKET_OPEN) { - if (unknown_size) { _set_error("Expected '{'"); return ERR_PARSE_ERROR; @@ -4968,7 +5082,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) { return ERR_PARSE_ERROR; @@ -4995,10 +5108,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui decl.initializer.push_back(n); break; } else { - if (curly) + if (curly) { _set_error("Expected '}' or ','"); - else + } else { _set_error("Expected ')' or ','"); + } return ERR_PARSE_ERROR; } } @@ -5024,7 +5138,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui node->declarations.push_back(decl); } else if (tk.type == TK_OP_ASSIGN) { - VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); if (is_struct) { node->struct_name = struct_name; @@ -5042,8 +5155,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui //variable created with assignment! must parse an expression Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -5115,8 +5229,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui ControlFlowNode *cf = alloc_node<ControlFlowNode>(); cf->flow_op = FLOW_OP_IF; Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_BOOL) { _set_error("Expected boolean expression"); @@ -5136,13 +5251,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue); - if (err) + if (err) { return err; + } pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_CF_ELSE) { - block = alloc_node<BlockNode>(); block->parent_block = p_block; cf->blocks.push_back(block); @@ -5152,7 +5267,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui _set_tkpos(pos); //rollback } } else if (tk.type == TK_CF_SWITCH) { - if (RenderingServer::get_singleton()->is_low_end()) { _set_error("\"switch\" operator is supported only on high-end platform!"); return ERR_PARSE_ERROR; @@ -5167,8 +5281,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui ControlFlowNode *cf = alloc_node<ControlFlowNode>(); cf->flow_op = FLOW_OP_SWITCH; Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_INT) { _set_error("Expected integer expression"); return ERR_PARSE_ERROR; @@ -5295,13 +5410,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(case_block, p_builtin_types, false, true, false); - if (err) + if (err) { return err; + } return OK; } else if (tk.type == TK_CF_DEFAULT) { - if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) { _set_tkpos(pos); return OK; @@ -5329,8 +5444,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(default_block, p_builtin_types, false, true, false); - if (err) + if (err) { return err; + } return OK; @@ -5341,13 +5457,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui BlockNode *do_block = nullptr; if (is_do) { - do_block = alloc_node<BlockNode>(); do_block->parent_block = p_block; Error err = _parse_block(do_block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } tk = _get_token(); if (tk.type != TK_CF_WHILE) { @@ -5369,8 +5485,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui cf->flow_op = FLOW_OP_WHILE; } Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } tk = _get_token(); if (tk.type != TK_PARENTHESIS_CLOSE) { @@ -5385,10 +5502,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } } else { - cf->expressions.push_back(n); cf->blocks.push_back(do_block); p_block->statements.push_back(cf); @@ -5420,8 +5537,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } Node *n = _parse_and_reduce_expression(init_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } if (n->get_datatype() != TYPE_BOOL) { _set_error("Middle expression is expected to be boolean."); @@ -5437,8 +5555,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui cf->expressions.push_back(n); n = _parse_and_reduce_expression(init_block, p_builtin_types); - if (!n) + if (!n) { return ERR_PARSE_ERROR; + } cf->expressions.push_back(n); @@ -5454,11 +5573,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(cf); Error err = _parse_block(block, p_builtin_types, true, true, true); - if (err) + if (err) { return err; + } } else if (tk.type == TK_CF_RETURN) { - //check return type BlockNode *b = p_block; while (b && !b->parent_function) { @@ -5484,8 +5603,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } else { _set_tkpos(pos); //rollback, wants expression Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (b->parent_function->return_type != expr->get_datatype()) { _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'"); @@ -5511,7 +5631,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui block = block->parent_block; } } else if (tk.type == TK_CF_DISCARD) { - //check return type BlockNode *b = p_block; while (b && !b->parent_function) { @@ -5539,7 +5658,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(flow); } else if (tk.type == TK_CF_BREAK) { - if (!p_can_break) { //all is good _set_error("Breaking is not allowed here"); @@ -5566,7 +5684,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } } else if (tk.type == TK_CF_CONTINUE) { - if (!p_can_continue) { //all is good _set_error("Continuing is not allowed here"); @@ -5585,12 +5702,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui p_block->statements.push_back(flow); } else { - //nothing else, so expression _set_tkpos(pos); //rollback Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } p_block->statements.push_back(expr); tk = _get_token(); @@ -5600,15 +5717,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui } } - if (p_just_one) + if (p_just_one) { break; + } } return OK; } String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types) const { - // Return a list of shader types as an human-readable string String valid_types; for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) { @@ -5664,7 +5781,6 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) { } Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) { - Token tk = _get_token(); if (tk.type != TK_SHADER_TYPE) { @@ -5702,12 +5818,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL; while (tk.type != TK_EOF) { - switch (tk.type) { case TK_RENDER_MODE: { - while (true) { - StringName mode; _get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode); @@ -5869,7 +5982,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } break; case TK_GLOBAL: { - tk = _get_token(); if (tk.type != TK_UNIFORM) { _set_error("Expected 'uniform' after 'global'"); @@ -5891,7 +6003,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct [[fallthrough]]; case TK_UNIFORM: case TK_VARYING: { - bool uniform = tk.type == TK_UNIFORM; DataPrecision precision = PRECISION_DEFAULT; DataInterpolation interpolation = INTERPOLATION_SMOOTH; @@ -5945,7 +6056,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } if (uniform) { - if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) { //validate global uniform DataType gvtype = global_var_get_type_func(name); @@ -5972,7 +6082,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else { - if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) { + if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) { _set_error("Uniforms with 'instance' qualifiers can't be of matrix type."); return ERR_PARSE_ERROR; } @@ -6025,7 +6135,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } uniform2.hint = ShaderNode::Uniform::HINT_COLOR; } else if (tk.type == TK_HINT_RANGE) { - uniform2.hint = ShaderNode::Uniform::HINT_RANGE; if (type != TYPE_FLOAT && type != TYPE_INT) { _set_error("Range hint is for float and int only"); @@ -6104,7 +6213,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else if (tk.type == TK_HINT_INSTANCE_INDEX) { - if (custom_instance_index != -1) { _set_error("Can only specify 'instance_index' once."); return ERR_PARSE_ERROR; @@ -6186,10 +6294,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct //reset scope for next uniform if (tk.type == TK_OP_ASSIGN) { - Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (expr->type != Node::TYPE_CONSTANT) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -6215,7 +6323,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } } else { - ShaderNode::Varying varying; varying.type = type; varying.precision = precision; @@ -6281,7 +6388,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct is_struct = true; struct_name = tk.text; } else { - if (!is_token_datatype(tk.type)) { _set_error("Expected constant, function, uniform or varying"); return ERR_PARSE_ERROR; @@ -6334,13 +6440,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct while (true) { ShaderNode::Constant constant; + constant.name = name; constant.type = is_struct ? TYPE_STRUCT : type; constant.type_str = struct_name; constant.precision = precision; constant.initializer = nullptr; if (tk.type == TK_OP_ASSIGN) { - if (!is_constant) { _set_error("Expected 'const' keyword before constant definition"); return ERR_PARSE_ERROR; @@ -6348,8 +6454,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct //variable created with assignment! must parse an expression Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>()); - if (!expr) + if (!expr) { return ERR_PARSE_ERROR; + } if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) { _set_error("Expected constant expression after '='"); return ERR_PARSE_ERROR; @@ -6373,6 +6480,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } shader->constants[name] = constant; + shader->vconstants.push_back(constant); + if (tk.type == TK_COMMA) { tk = _get_token(); if (tk.type != TK_IDENTIFIER) { @@ -6582,11 +6691,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct current_function = name; Error err = _parse_block(func_node->body, builtin_types); - if (err) + if (err) { return err; + } if (func_node->return_type != DataType::TYPE_VOID) { - BlockNode *block = func_node->body; if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) { _set_error("Expected at least one return statement in a non-void function."); @@ -6604,7 +6713,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { - if (p_functions.has("vertex")) { if (p_functions["vertex"].built_ins.has(p_name)) { return true; @@ -6624,7 +6732,6 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI } Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) { - bool found = false; for (int i = p_flow->blocks.size() - 1; i >= 0; i--) { @@ -6643,11 +6750,9 @@ Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOper } Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) { - bool found = false; for (int i = p_block->statements.size() - 1; i >= 0; i--) { - if (p_block->statements[i]->type == Node::TYPE_CONTROL_FLOW) { ControlFlowNode *flow = (ControlFlowNode *)p_block->statements[i]; if (flow->flow_op == p_op) { @@ -6676,7 +6781,6 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat // skips over whitespace and /* */ and // comments static int _get_first_ident_pos(const String &p_code) { - int idx = 0; #define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0)) @@ -6685,7 +6789,9 @@ static int _get_first_ident_pos(const String &p_code) { if (GETCHAR(0) == '/' && GETCHAR(1) == '/') { idx += 2; while (true) { - if (GETCHAR(0) == 0) return 0; + if (GETCHAR(0) == 0) { + return 0; + } if (GETCHAR(0) == '\n') { idx++; break; // loop @@ -6695,7 +6801,9 @@ static int _get_first_ident_pos(const String &p_code) { } else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') { idx += 2; while (true) { - if (GETCHAR(0) == 0) return 0; + if (GETCHAR(0) == 0) { + return 0; + } if (GETCHAR(0) == '*' && GETCHAR(1) == '/') { idx += 2; break; // loop @@ -6720,13 +6828,11 @@ static int _get_first_ident_pos(const String &p_code) { } String ShaderLanguage::get_shader_type(const String &p_code) { - bool reading_type = false; String cur_identifier; for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) { - if (p_code[i] == ';') { break; @@ -6748,14 +6854,14 @@ String ShaderLanguage::get_shader_type(const String &p_code) { } } - if (reading_type) + if (reading_type) { return cur_identifier; + } return String(); } Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) { - clear(); code = p_code; @@ -6773,7 +6879,6 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi } Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { - clear(); code = p_code; @@ -6785,7 +6890,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct _parse_shader(p_functions, p_render_modes, p_shader_types); switch (completion_type) { - case COMPLETION_NONE: { //do nothing return OK; @@ -6799,7 +6903,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_STRUCT: { - if (shader->structs.has(completion_struct)) { StructNode *node = shader->structs[completion_struct].shader_struct; for (int i = 0; i < node->members.size(); i++) { @@ -6811,7 +6914,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_MAIN_FUNCTION: { - for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_FUNCTION); r_options->push_back(option); @@ -6821,7 +6923,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } break; case COMPLETION_IDENTIFIER: case COMPLETION_FUNCTION_CALL: { - bool comp_ident = completion_type == COMPLETION_IDENTIFIER; Map<String, ScriptCodeCompletionOption::Kind> matches; StringName skip_function; @@ -6831,7 +6932,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct while (block) { if (comp_ident) { for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) { - if (E->get().line < completion_line) { matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); } @@ -6879,8 +6979,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } for (int i = 0; i < shader->functions.size(); i++) { - if (!shader->functions[i].callable || shader->functions[i].name == skip_function) + if (!shader->functions[i].callable || shader->functions[i].name == skip_function) { continue; + } matches.insert(String(shader->functions[i].name), ScriptCodeCompletionOption::KIND_FUNCTION); } @@ -6923,12 +7024,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct return OK; } break; case COMPLETION_CALL_ARGUMENTS: { - for (int i = 0; i < shader->functions.size(); i++) { - if (!shader->functions[i].callable) + if (!shader->functions[i].callable) { continue; + } if (shader->functions[i].name == completion_function) { - String calltip; calltip += get_datatype_name(shader->functions[i].function->return_type); @@ -6937,11 +7037,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += "("; for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) { - - if (j > 0) + if (j > 0) { calltip += ", "; - else + } else { calltip += " "; + } if (j == completion_argument) { calltip += CharType(0xFFFF); @@ -6964,8 +7064,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } } - if (shader->functions[i].function->arguments.size()) + if (shader->functions[i].function->arguments.size()) { calltip += " "; + } calltip += ")"; r_call_hint = calltip; @@ -6979,7 +7080,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool low_end = RenderingServer::get_singleton()->is_low_end(); while (builtin_func_defs[idx].name) { - if (low_end && builtin_func_defs[idx].high_end) { idx++; continue; @@ -6996,14 +7096,14 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } if (completion_function == builtin_func_defs[idx].name) { - if (builtin_func_defs[idx].tag != completion_class) { idx++; continue; } - if (calltip.length()) + if (calltip.length()) { calltip += "\n"; + } calltip += get_datatype_name(builtin_func_defs[idx].rettype); calltip += " "; @@ -7012,14 +7112,15 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct bool found_arg = false; for (int i = 0; i < 4; i++) { - - if (builtin_func_defs[idx].args[i] == TYPE_VOID) + if (builtin_func_defs[idx].args[i] == TYPE_VOID) { break; + } - if (i > 0) + if (i > 0) { calltip += ", "; - else + } else { calltip += " "; + } if (i == completion_argument) { calltip += CharType(0xFFFF); @@ -7038,8 +7139,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct found_arg = true; } - if (found_arg) + if (found_arg) { calltip += " "; + } calltip += ")"; } idx++; @@ -7051,7 +7153,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } break; case COMPLETION_INDEX: { - const char colv[4] = { 'r', 'g', 'b', 'a' }; const char coordv[4] = { 'x', 'y', 'z', 'w' }; const char coordt[4] = { 's', 't', 'p', 'q' }; @@ -7070,7 +7171,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_IVEC3: case TYPE_UVEC3: case TYPE_VEC3: { - limit = 3; } break; @@ -7078,13 +7178,18 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case TYPE_IVEC4: case TYPE_UVEC4: case TYPE_VEC4: { - limit = 4; } break; - case TYPE_MAT2: limit = 2; break; - case TYPE_MAT3: limit = 3; break; - case TYPE_MAT4: limit = 4; break; + case TYPE_MAT2: + limit = 2; + break; + case TYPE_MAT3: + limit = 3; + break; + case TYPE_MAT4: + limit = 4; + break; default: { } } @@ -7102,27 +7207,22 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } String ShaderLanguage::get_error_text() { - return error_str; } int ShaderLanguage::get_error_line() { - return error_line; } ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() { - return shader; } ShaderLanguage::ShaderLanguage() { - nodes = nullptr; completion_class = TAG_GLOBAL; } ShaderLanguage::~ShaderLanguage() { - clear(); } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 48f1d1440f..020a5e3e6f 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -40,7 +40,6 @@ #include "core/variant.h" class ShaderLanguage { - public: enum TokenType { TK_EMPTY, @@ -79,6 +78,7 @@ public: TK_TYPE_ISAMPLER3D, TK_TYPE_USAMPLER3D, TK_TYPE_SAMPLERCUBE, + TK_TYPE_SAMPLERCUBEARRAY, TK_INTERPOLATION_FLAT, TK_INTERPOLATION_SMOOTH, TK_CONST, @@ -218,6 +218,7 @@ public: TYPE_ISAMPLER3D, TYPE_USAMPLER3D, TYPE_SAMPLERCUBE, + TYPE_SAMPLERCUBEARRAY, TYPE_STRUCT, TYPE_MAX }; @@ -326,7 +327,7 @@ public: }; struct Node { - Node *next; + Node *next = nullptr; enum Type { TYPE_SHADER, @@ -350,7 +351,6 @@ public: virtual String get_datatype_name() const { return ""; } Node(Type t) : - next(nullptr), type(t) {} virtual ~Node() {} }; @@ -366,41 +366,35 @@ public: Node *nodes; struct OperatorNode : public Node { - DataType return_cache; - DataPrecision return_precision_cache; - Operator op; + DataType return_cache = TYPE_VOID; + DataPrecision return_precision_cache = PRECISION_DEFAULT; + Operator op = OP_EQUAL; StringName struct_name; Vector<Node *> arguments; virtual DataType get_datatype() const { return return_cache; } virtual String get_datatype_name() const { return String(struct_name); } OperatorNode() : - Node(TYPE_OPERATOR), - return_cache(TYPE_VOID), - return_precision_cache(PRECISION_DEFAULT), - op(OP_EQUAL), - struct_name("") {} + Node(TYPE_OPERATOR) {} }; struct VariableNode : public Node { - DataType datatype_cache; + DataType datatype_cache = TYPE_VOID; StringName name; StringName struct_name; virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } - bool is_const; + bool is_const = false; VariableNode() : - Node(TYPE_VARIABLE), - datatype_cache(TYPE_VOID), - is_const(false) {} + Node(TYPE_VARIABLE) {} }; struct VariableDeclarationNode : public Node { - DataPrecision precision; - DataType datatype; + DataPrecision precision = PRECISION_DEFAULT; + DataType datatype = TYPE_VOID; String struct_name; - bool is_const; + bool is_const = false; struct Declaration { StringName name; @@ -411,47 +405,38 @@ public: virtual DataType get_datatype() const { return datatype; } VariableDeclarationNode() : - Node(TYPE_VARIABLE_DECLARATION), - precision(PRECISION_DEFAULT), - datatype(TYPE_VOID), - is_const(false) {} + Node(TYPE_VARIABLE_DECLARATION) {} }; struct ArrayNode : public Node { - DataType datatype_cache; + DataType datatype_cache = TYPE_VOID; StringName struct_name; StringName name; - Node *index_expression; - Node *call_expression; - bool is_const; + Node *index_expression = nullptr; + Node *call_expression = nullptr; + bool is_const = false; virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } ArrayNode() : - Node(TYPE_ARRAY), - datatype_cache(TYPE_VOID), - index_expression(nullptr), - call_expression(nullptr), - is_const(false) {} + Node(TYPE_ARRAY) {} }; struct ArrayConstructNode : public Node { - DataType datatype; + DataType datatype = TYPE_VOID; String struct_name; Vector<Node *> initializer; ArrayConstructNode() : - Node(TYPE_ARRAY_CONSTRUCT), - datatype(TYPE_VOID) { - } + Node(TYPE_ARRAY_CONSTRUCT) {} }; struct ArrayDeclarationNode : public Node { - DataPrecision precision; - DataType datatype; + DataPrecision precision = PRECISION_DEFAULT; + DataType datatype = TYPE_VOID; String struct_name; - bool is_const; + bool is_const = false; struct Declaration { StringName name; @@ -463,14 +448,11 @@ public: virtual DataType get_datatype() const { return datatype; } ArrayDeclarationNode() : - Node(TYPE_ARRAY_DECLARATION), - precision(PRECISION_DEFAULT), - datatype(TYPE_VOID), - is_const(false) {} + Node(TYPE_ARRAY_DECLARATION) {} }; struct ConstantNode : public Node { - DataType datatype; + DataType datatype = TYPE_VOID; union Value { bool boolean; @@ -483,15 +465,14 @@ public: virtual DataType get_datatype() const { return datatype; } ConstantNode() : - Node(TYPE_CONSTANT), - datatype(TYPE_VOID) {} + Node(TYPE_CONSTANT) {} }; struct FunctionNode; struct BlockNode : public Node { - FunctionNode *parent_function; - BlockNode *parent_block; + FunctionNode *parent_function = nullptr; + BlockNode *parent_block = nullptr; enum BlockType { BLOCK_TYPE_STANDART, @@ -501,8 +482,8 @@ public: BLOCK_TYPE_DEFAULT, }; - int block_type; - SubClassTag block_tag; + int block_type = BLOCK_TYPE_STANDART; + SubClassTag block_tag = SubClassTag::TAG_GLOBAL; struct Variable { DataType type; @@ -515,63 +496,48 @@ public: Map<StringName, Variable> variables; List<Node *> statements; - bool single_statement; + bool single_statement = false; BlockNode() : - Node(TYPE_BLOCK), - parent_function(nullptr), - parent_block(nullptr), - block_type(BLOCK_TYPE_STANDART), - block_tag(SubClassTag::TAG_GLOBAL), - single_statement(false) {} + Node(TYPE_BLOCK) {} }; struct ControlFlowNode : public Node { - FlowOperation flow_op; + FlowOperation flow_op = FLOW_OP_IF; Vector<Node *> expressions; Vector<BlockNode *> blocks; ControlFlowNode() : - Node(TYPE_CONTROL_FLOW), - flow_op(FLOW_OP_IF) {} + Node(TYPE_CONTROL_FLOW) {} }; struct MemberNode : public Node { - DataType basetype; - bool basetype_const; + DataType basetype = TYPE_VOID; + bool basetype_const = false; StringName base_struct_name; DataPrecision precision; - DataType datatype; - int array_size; + DataType datatype = TYPE_VOID; + int array_size = 0; StringName struct_name; StringName name; - Node *owner; - Node *index_expression; - bool has_swizzling_duplicates; + Node *owner = nullptr; + Node *index_expression = nullptr; + bool has_swizzling_duplicates = false; virtual DataType get_datatype() const { return datatype; } virtual String get_datatype_name() const { return String(struct_name); } MemberNode() : - Node(TYPE_MEMBER), - basetype(TYPE_VOID), - basetype_const(false), - datatype(TYPE_VOID), - array_size(0), - owner(nullptr), - index_expression(nullptr), - has_swizzling_duplicates(false) {} + Node(TYPE_MEMBER) {} }; struct StructNode : public Node { - List<MemberNode *> members; StructNode() : Node(TYPE_STRUCT) {} }; struct FunctionNode : public Node { - struct Argument { ArgumentQualifier qualifier; StringName name; @@ -589,24 +555,20 @@ public: }; StringName name; - DataType return_type; + DataType return_type = TYPE_VOID; StringName return_struct_name; - DataPrecision return_precision; + DataPrecision return_precision = PRECISION_DEFAULT; Vector<Argument> arguments; - BlockNode *body; - bool can_discard; + BlockNode *body = nullptr; + bool can_discard = false; FunctionNode() : - Node(TYPE_FUNCTION), - return_type(TYPE_VOID), - return_precision(PRECISION_DEFAULT), - body(nullptr), - can_discard(false) {} + Node(TYPE_FUNCTION) {} }; struct ShaderNode : public Node { - struct Constant { + StringName name; DataType type; StringName type_str; DataPrecision precision; @@ -626,16 +588,12 @@ public: }; struct Varying { - DataType type; - DataInterpolation interpolation; - DataPrecision precision; - int array_size; + DataType type = TYPE_VOID; + DataInterpolation interpolation = INTERPOLATION_FLAT; + DataPrecision precision = PRECISION_DEFAULT; + int array_size = 0; - Varying() : - type(TYPE_VOID), - interpolation(INTERPOLATION_FLAT), - precision(PRECISION_DEFAULT), - array_size(0) {} + Varying() {} }; struct Uniform { @@ -664,27 +622,19 @@ public: SCOPE_GLOBAL, }; - int order; - int texture_order; - DataType type; - DataPrecision precision; + int order = 0; + int texture_order = 0; + DataType type = TYPE_VOID; + DataPrecision precision = PRECISION_DEFAULT; Vector<ConstantNode::Value> default_value; - Scope scope; - Hint hint; - TextureFilter filter; - TextureRepeat repeat; + Scope scope = SCOPE_LOCAL; + Hint hint = HINT_NONE; + TextureFilter filter = FILTER_DEFAULT; + TextureRepeat repeat = REPEAT_DEFAULT; float hint_range[3]; - int instance_index; - - Uniform() : - order(0), - texture_order(0), - type(TYPE_VOID), - precision(PRECISION_DEFAULT), - hint(HINT_NONE), - filter(FILTER_DEFAULT), - repeat(REPEAT_DEFAULT), - instance_index(0) { + int instance_index = 0; + + Uniform() { hint_range[0] = 0.0f; hint_range[1] = 1.0f; hint_range[2] = 0.001f; @@ -698,6 +648,7 @@ public: Vector<StringName> render_modes; Vector<Function> functions; + Vector<Constant> vconstants; Vector<Struct> vstructs; ShaderNode() : @@ -763,12 +714,10 @@ public: static void get_builtin_funcs(List<String> *r_keywords); struct BuiltInInfo { - DataType type; - bool constant; + DataType type = TYPE_VOID; + bool constant = false; - BuiltInInfo() : - type(TYPE_VOID), - constant(false) {} + BuiltInInfo() {} BuiltInInfo(DataType p_type, bool p_constant = false) : type(p_type), @@ -821,8 +770,9 @@ private: } void _set_error(const String &p_str) { - if (error_set) + if (error_set) { return; + } error_line = tk_line; error_set = true; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 78bbd73db4..2601efa9e2 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -31,12 +31,10 @@ #include "shader_types.h" const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) { - return shader_modes[p_mode].functions; } const Vector<StringName> &ShaderTypes::get_modes(RS::ShaderMode p_mode) { - return shader_modes[p_mode].modes; } @@ -47,7 +45,6 @@ const Set<String> &ShaderTypes::get_types() { ShaderTypes *ShaderTypes::singleton = nullptr; static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) { - return ShaderLanguage::BuiltInInfo(p_type, true); } diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h index 499a761265..7d8057a5c6 100644 --- a/servers/rendering/shader_types.h +++ b/servers/rendering/shader_types.h @@ -36,9 +36,7 @@ #include "shader_language.h" class ShaderTypes { - struct Type { - Map<StringName, ShaderLanguage::FunctionInfo> functions; Vector<StringName> modes; }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 0d3b44c0dc..7edab1418d 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -37,27 +37,24 @@ RenderingServer *RenderingServer::singleton = nullptr; RenderingServer *(*RenderingServer::create_func)() = nullptr; RenderingServer *RenderingServer::get_singleton() { - return singleton; } RenderingServer *RenderingServer::create() { - ERR_FAIL_COND_V(singleton, nullptr); - if (create_func) + if (create_func) { return create_func(); + } return nullptr; } Array RenderingServer::_texture_debug_usage_bind() { - List<TextureInfo> list; texture_debug_usage(&list); Array arr; for (const List<TextureInfo>::Element *E = list.front(); E; E = E->next()) { - Dictionary dict; dict["texture"] = E->get().texture; dict["width"] = E->get().width; @@ -72,7 +69,6 @@ Array RenderingServer::_texture_debug_usage_bind() { } Array RenderingServer::_shader_get_param_list_bind(RID p_shader) const { - List<PropertyInfo> l; shader_get_param_list(p_shader, &l); return convert_property_list(&l); @@ -88,19 +84,16 @@ static Array to_array(const Vector<ObjectID> &ids) { } Array RenderingServer::_instances_cull_aabb_bind(const AABB &p_aabb, RID p_scenario) const { - Vector<ObjectID> ids = instances_cull_aabb(p_aabb, p_scenario); return to_array(ids); } Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { - Vector<ObjectID> ids = instances_cull_ray(p_from, p_to, p_scenario); return to_array(ids); } Array RenderingServer::_instances_cull_convex_bind(const Array &p_convex, RID p_scenario) const { - Vector<Plane> planes; for (int i = 0; i < p_convex.size(); ++i) { Variant v = p_convex[i]; @@ -113,7 +106,6 @@ Array RenderingServer::_instances_cull_convex_bind(const Array &p_convex, RID p_ } RID RenderingServer::get_test_texture() { - if (test_texture.is_valid()) { return test_texture; }; @@ -127,20 +119,16 @@ RID RenderingServer::get_test_texture() { uint8_t *w = test_data.ptrw(); for (int x = 0; x < TEST_TEXTURE_SIZE; x++) { - for (int y = 0; y < TEST_TEXTURE_SIZE; y++) { - Color c; int r = 255 - (x + y) / 2; if ((x % (TEST_TEXTURE_SIZE / 8)) < 2 || (y % (TEST_TEXTURE_SIZE / 8)) < 2) { - c.r = y; c.g = r; c.b = x; } else { - c.r = r; c.g = x; c.b = y; @@ -161,17 +149,18 @@ RID RenderingServer::get_test_texture() { } void RenderingServer::_free_internal_rids() { - - if (test_texture.is_valid()) + if (test_texture.is_valid()) { free(test_texture); - if (white_texture.is_valid()) + } + if (white_texture.is_valid()) { free(white_texture); - if (test_material.is_valid()) + } + if (test_material.is_valid()) { free(test_material); + } } RID RenderingServer::_make_test_cube() { - Vector<Vector3> vertices; Vector<Vector3> normals; Vector<float> tangents; @@ -187,24 +176,22 @@ RID RenderingServer::_make_test_cube() { uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); for (int i = 0; i < 6; i++) { - Vector3 face_points[4]; Vector3 normal_points[4]; float uv_points[8] = { 0, 0, 0, 1, 1, 1, 1, 0 }; for (int j = 0; j < 4; j++) { - float v[3]; v[0] = 1.0; v[1] = 1 - 2 * ((j >> 1) & 1); v[2] = v[1] * (1 - 2 * (j & 1)); for (int k = 0; k < 3; k++) { - - if (i < 3) + if (i < 3) { face_points[j][(i + k) % 3] = v[k]; - else + } else { face_points[3 - j][(i + k) % 3] = -v[k]; + } } normal_points[j] = Vector3(); normal_points[j][i % 3] = (i >= 3 ? -1 : 1); @@ -231,8 +218,9 @@ RID RenderingServer::_make_test_cube() { Vector<int> indices; indices.resize(vertices.size()); - for (int i = 0; i < vertices.size(); i++) + for (int i = 0; i < vertices.size(); i++) { indices.set(i, i); + } d[RenderingServer::ARRAY_INDEX] = indices; mesh_add_surface_from_arrays(test_cube, PRIMITIVE_TRIANGLES, d); @@ -253,7 +241,6 @@ RID RenderingServer::_make_test_cube() { } RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { - Vector<Vector3> vertices; Vector<Vector3> normals; @@ -267,7 +254,6 @@ RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { double zr1 = Math::cos(lat1); for (int j = p_lons; j >= 1; j--) { - double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons; double x0 = Math::cos(lng0); double y0 = Math::sin(lng0); @@ -310,16 +296,17 @@ RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) { } RID RenderingServer::get_white_texture() { - - if (white_texture.is_valid()) + if (white_texture.is_valid()) { return white_texture; + } Vector<uint8_t> wt; wt.resize(16 * 3); { uint8_t *w = wt.ptrw(); - for (int i = 0; i < 16 * 3; i++) + for (int i = 0; i < 16 * 3; i++) { w[i] = 255; + } } Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt)); white_texture = texture_2d_create(white); @@ -330,7 +317,6 @@ RID RenderingServer::get_white_texture() { #define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001) Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) { - uint8_t *vw = r_vertex_array.ptrw(); uint8_t *iw = nullptr; @@ -341,16 +327,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint int max_bone = 0; for (int ai = 0; ai < RS::ARRAY_MAX; ai++) { - - if (!(p_format & (1 << ai))) // no array + if (!(p_format & (1 << ai))) { // no array continue; + } switch (ai) { - case RS::ARRAY_VERTEX: { - if (p_format & RS::ARRAY_FLAG_USE_2D_VERTICES) { - Vector<Vector2> array = p_arrays[ai]; ERR_FAIL_COND_V(array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER); @@ -361,16 +344,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint { for (int i = 0; i < p_vertex_array_len; i++) { - float vector[2] = { src[i].x, src[i].y }; copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 2); if (i == 0) { - aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size } else { - aabb.expand_to(src[i]); } } @@ -389,16 +369,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint { for (int i = 0; i < p_vertex_array_len; i++) { - float vector[3] = { src[i].x, src[i].y, src[i].z }; copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 3); if (i == 0) { - aabb = AABB(src[i], SMALL_VEC3); } else { - aabb.expand_to(src[i]); } } @@ -409,7 +386,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_NORMAL: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY, ERR_INVALID_PARAMETER); Vector<Vector3> array = p_arrays[ai]; @@ -420,9 +396,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint // setting vertices means regenerating the AABB if (p_format & ARRAY_COMPRESS_NORMAL) { - for (int i = 0; i < p_vertex_array_len; i++) { - int8_t vector[4] = { (int8_t)CLAMP(src[i].x * 127, -128, 127), (int8_t)CLAMP(src[i].y * 127, -128, 127), @@ -435,7 +409,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } else { for (int i = 0; i < p_vertex_array_len; i++) { - float vector[3] = { src[i].x, src[i].y, src[i].z }; copymem(&vw[p_offsets[ai] + i * p_stride], vector, 3 * 4); } @@ -444,7 +417,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_TANGENT: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER); Vector<real_t> array = p_arrays[ai]; @@ -454,7 +426,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const real_t *src = array.ptr(); if (p_format & ARRAY_COMPRESS_TANGENT) { - for (int i = 0; i < p_vertex_array_len; i++) { int8_t xyzw[4] = { (int8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127), @@ -468,7 +439,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } else { for (int i = 0; i < p_vertex_array_len; i++) { - float xyzw[4] = { src[i * 4 + 0], src[i * 4 + 1], @@ -482,7 +452,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_COLOR: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_COLOR_ARRAY, ERR_INVALID_PARAMETER); Vector<Color> array = p_arrays[ai]; @@ -492,29 +461,23 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const Color *src = array.ptr(); if (p_format & ARRAY_COMPRESS_COLOR) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint8_t colors[4]; for (int j = 0; j < 4; j++) { - colors[j] = CLAMP(int((src[i][j]) * 255.0), 0, 255); } copymem(&vw[p_offsets[ai] + i * p_stride], colors, 4); } } else { - for (int i = 0; i < p_vertex_array_len; i++) { - copymem(&vw[p_offsets[ai] + i * p_stride], &src[i], 4 * 4); } } } break; case RS::ARRAY_TEX_UV: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_VECTOR2_ARRAY, ERR_INVALID_PARAMETER); Vector<Vector2> array = p_arrays[ai]; @@ -524,16 +487,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const Vector2 *src = array.ptr(); if (p_format & ARRAY_COMPRESS_TEX_UV) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) }; copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2); } } else { for (int i = 0; i < p_vertex_array_len; i++) { - float uv[2] = { src[i].x, src[i].y }; copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4); @@ -543,7 +503,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_TEX_UV2: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_VECTOR2_ARRAY, ERR_INVALID_PARAMETER); Vector<Vector2> array = p_arrays[ai]; @@ -553,16 +512,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const Vector2 *src = array.ptr(); if (p_format & ARRAY_COMPRESS_TEX_UV2) { - for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) }; copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2); } } else { for (int i = 0; i < p_vertex_array_len; i++) { - float uv[2] = { src[i].x, src[i].y }; copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4); @@ -570,7 +526,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } } break; case RS::ARRAY_WEIGHTS: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER); Vector<real_t> array = p_arrays[ai]; @@ -580,9 +535,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const real_t *src = array.ptr(); { - for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t data[RS::ARRAY_WEIGHTS_SIZE]; for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) { data[j] = CLAMP(src[i * RS::ARRAY_WEIGHTS_SIZE + j] * 65535, 0, 65535); @@ -594,7 +547,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_BONES: { - ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_INT32_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER); Vector<int> array = p_arrays[ai]; @@ -604,7 +556,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const int *src = array.ptr(); for (int i = 0; i < p_vertex_array_len; i++) { - uint16_t data[RS::ARRAY_WEIGHTS_SIZE]; for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) { data[j] = src[i * RS::ARRAY_WEIGHTS_SIZE + j]; @@ -616,7 +567,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } break; case RS::ARRAY_INDEX: { - ERR_FAIL_NULL_V(iw, ERR_INVALID_DATA); ERR_FAIL_COND_V(p_index_array_len <= 0, ERR_INVALID_DATA); ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_INT32_ARRAY, ERR_INVALID_PARAMETER); @@ -630,7 +580,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint const int *src = indices.ptr(); for (int i = 0; i < p_index_array_len; i++) { - if (p_vertex_array_len < (1 << 16)) { uint16_t v = src[i]; @@ -669,7 +618,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint bool any_valid = false; if (vertices.size() && bones.size() == vertices.size() * 4 && weights.size() == bones.size()) { - int vs = vertices.size(); const Vector3 *rv = vertices.ptr(); const int *rb = bones.ptr(); @@ -678,14 +626,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint AABB *bptr = r_bone_aabb.ptrw(); for (int i = 0; i < vs; i++) { - Vector3 v = rv[i]; for (int j = 0; j < 4; j++) { - int idx = rb[i * 4 + j]; float w = rw[i * 4 + j]; - if (w == 0) + if (w == 0) { continue; //break; + } ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA); if (bptr[idx].size.x < 0) { @@ -700,7 +647,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint } if (!any_valid && first) { - r_bone_aabb.clear(); } } @@ -719,22 +665,19 @@ uint32_t RenderingServer::mesh_surface_get_format_stride(uint32_t p_format, int } uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const { - int total_elem_size = 0; for (int i = 0; i < RS::ARRAY_MAX; i++) { - r_offsets[i] = 0; //reset - if (!(p_format & (1 << i))) // no array + if (!(p_format & (1 << i))) { // no array continue; + } int elem_size = 0; switch (i) { - case RS::ARRAY_VERTEX: { - if (p_format & ARRAY_FLAG_USE_2D_VERTICES) { elem_size = 2; } else { @@ -751,7 +694,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma } break; case RS::ARRAY_NORMAL: { - if (p_format & ARRAY_COMPRESS_NORMAL) { elem_size = sizeof(uint32_t); } else { @@ -769,7 +711,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma } break; case RS::ARRAY_COLOR: { - if (p_format & ARRAY_COMPRESS_COLOR) { elem_size = sizeof(uint32_t); } else { @@ -794,24 +735,20 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma } break; case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_INDEX: { - if (p_index_len <= 0) { ERR_PRINT("index_array_len==NO_INDEX_ARRAY"); break; } /* determine whether using 16 or 32 bits indices */ if (p_vertex_len >= (1 << 16)) { - elem_size = 4; } else { @@ -832,7 +769,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma } Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_compress_format) { - ERR_FAIL_INDEX_V(p_primitive, RS::PRIMITIVE_MAX, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_arrays.size() != RS::ARRAY_MAX, ERR_INVALID_PARAMETER); @@ -843,14 +779,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa int array_len = 0; for (int i = 0; i < p_arrays.size(); i++) { - - if (p_arrays[i].get_type() == Variant::NIL) + if (p_arrays[i].get_type() == Variant::NIL) { continue; + } format |= (1 << i); if (i == RS::ARRAY_VERTEX) { - Variant var = p_arrays[i]; switch (var.get_type()) { case Variant::PACKED_VECTOR2_ARRAY: { @@ -867,7 +802,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa array_len = PackedVector3Array(p_arrays[i]).size(); ERR_FAIL_COND_V(array_len == 0, ERR_INVALID_DATA); } else if (i == RS::ARRAY_INDEX) { - index_array_len = PackedInt32Array(p_arrays[i]).size(); } } @@ -877,13 +811,12 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa if (p_blend_shapes.size()) { //validate format for morphs for (int i = 0; i < p_blend_shapes.size(); i++) { - uint32_t bsformat = 0; Array arr = p_blend_shapes[i]; for (int j = 0; j < arr.size(); j++) { - - if (arr[j].get_type() != Variant::NIL) + if (arr[j].get_type() != Variant::NIL) { bsformat |= (1 << j); + } } ERR_FAIL_COND_V((bsformat) != (format & (RS::ARRAY_FORMAT_INDEX - 1)), ERR_INVALID_PARAMETER); @@ -895,18 +828,16 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa int total_elem_size = 0; for (int i = 0; i < RS::ARRAY_MAX; i++) { - offsets[i] = 0; //reset - if (!(format & (1 << i))) // no array + if (!(format & (1 << i))) { // no array continue; + } int elem_size = 0; switch (i) { - case RS::ARRAY_VERTEX: { - Variant arr = p_arrays[0]; if (arr.get_type() == Variant::PACKED_VECTOR2_ARRAY) { elem_size = 2; @@ -924,7 +855,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } break; case RS::ARRAY_NORMAL: { - if (p_compress_format & ARRAY_COMPRESS_NORMAL) { elem_size = sizeof(uint32_t); } else { @@ -942,7 +872,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } break; case RS::ARRAY_COLOR: { - if (p_compress_format & ARRAY_COMPRESS_COLOR) { elem_size = sizeof(uint32_t); } else { @@ -967,24 +896,20 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } break; case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_INDEX: { - if (index_array_len <= 0) { ERR_PRINT("index_array_len==NO_INDEX_ARRAY"); break; } /* determine whether using 16 or 32 bits indices */ if (array_len >= (1 << 16)) { - elem_size = 4; } else { @@ -1024,7 +949,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa Vector<Vector<uint8_t>> blend_shape_data; for (int i = 0; i < p_blend_shapes.size(); i++) { - Vector<uint8_t> vertex_array_shape; vertex_array_shape.resize(array_size); Vector<uint8_t> noindex; @@ -1038,7 +962,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } Vector<SurfaceData::LOD> lods; if (index_array_len) { - List<Variant> keys; p_lods.get_key_list(&keys); for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { @@ -1093,7 +1016,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_compress_format) { - SurfaceData sd; Error err = mesh_create_surface_data_from_arrays(&sd, p_primitive, p_arrays, p_blend_shapes, p_lods, p_compress_format); if (err != OK) { @@ -1103,24 +1025,21 @@ void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_p } Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const { - uint32_t offsets[ARRAY_MAX]; int total_elem_size = 0; for (int i = 0; i < RS::ARRAY_MAX; i++) { - offsets[i] = 0; //reset - if (!(p_format & (1 << i))) // no array + if (!(p_format & (1 << i))) { // no array continue; + } int elem_size = 0; switch (i) { - case RS::ARRAY_VERTEX: { - if (p_format & ARRAY_FLAG_USE_2D_VERTICES) { elem_size = 2; } else { @@ -1133,7 +1052,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_NORMAL: { - if (p_format & ARRAY_COMPRESS_NORMAL) { elem_size = sizeof(uint32_t); } else { @@ -1151,7 +1069,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_COLOR: { - if (p_format & ARRAY_COMPRESS_COLOR) { elem_size = sizeof(uint32_t); } else { @@ -1176,24 +1093,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_WEIGHTS: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_BONES: { - elem_size = sizeof(uint16_t) * 4; } break; case RS::ARRAY_INDEX: { - if (p_index_len <= 0) { ERR_PRINT("index_array_len==NO_INDEX_ARRAY"); break; } /* determine whether using 16 or 32 bits indices */ if (p_vertex_len >= (1 << 16)) { - elem_size = 4; } else { @@ -1217,25 +1130,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t const uint8_t *r = p_vertex_data.ptr(); for (int i = 0; i < RS::ARRAY_MAX; i++) { - - if (!(p_format & (1 << i))) + if (!(p_format & (1 << i))) { continue; + } switch (i) { - case RS::ARRAY_VERTEX: { - if (p_format & ARRAY_FLAG_USE_2D_VERTICES) { - Vector<Vector2> arr_2d; arr_2d.resize(p_vertex_len); { - Vector2 *w = arr_2d.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector2(v[0], v[1]); } @@ -1243,16 +1151,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t ret[i] = arr_2d; } else { - Vector<Vector3> arr_3d; arr_3d.resize(p_vertex_len); { - Vector3 *w = arr_3d.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector3(v[0], v[1], v[2]); } @@ -1267,12 +1172,10 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t arr.resize(p_vertex_len); if (p_format & ARRAY_COMPRESS_NORMAL) { - Vector3 *w = arr.ptrw(); const float multiplier = 1.f / 127.f; for (int j = 0; j < p_vertex_len; j++) { - const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier); } @@ -1280,7 +1183,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector3 *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector3(v[0], v[1], v[2]); } @@ -1297,14 +1199,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t float *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = float(v[k] / 127.0); } } } else { - float *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { @@ -1319,16 +1219,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_COLOR: { - Vector<Color> arr; arr.resize(p_vertex_len); if (p_format & ARRAY_COMPRESS_COLOR) { - Color *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]]; w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0)); } @@ -1336,7 +1233,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Color *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Color(v[0], v[1], v[2], v[3]); } @@ -1345,25 +1241,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t ret[i] = arr; } break; case RS::ARRAY_TEX_UV: { - Vector<Vector2> arr; arr.resize(p_vertex_len); if (p_format & ARRAY_COMPRESS_TEX_UV) { - Vector2 *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); } } else { - Vector2 *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector2(v[0], v[1]); } @@ -1377,20 +1268,16 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t arr.resize(p_vertex_len); if (p_format & ARRAY_COMPRESS_TEX_UV2) { - Vector2 *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1])); } } else { - Vector2 *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const float *v = (const float *)&r[j * total_elem_size + offsets[i]]; w[j] = Vector2(v[0], v[1]); } @@ -1400,14 +1287,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_WEIGHTS: { - Vector<float> arr; arr.resize(p_vertex_len * 4); { float *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = float(v[k] / 65535.0); @@ -1419,14 +1304,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } break; case RS::ARRAY_BONES: { - Vector<int> arr; arr.resize(p_vertex_len * 4); int *w = arr.ptrw(); for (int j = 0; j < p_vertex_len; j++) { - const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]]; for (int k = 0; k < 4; k++) { w[j * 4 + k] = v[k]; @@ -1444,16 +1327,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t Vector<int> arr; arr.resize(p_index_len); if (p_vertex_len < (1 << 16)) { - int *w = arr.ptrw(); for (int j = 0; j < p_index_len; j++) { - const uint16_t *v = (const uint16_t *)&ir[j * 2]; w[j] = *v; } } else { - int *w = arr.ptrw(); for (int j = 0; j < p_index_len; j++) { @@ -1473,13 +1353,11 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t } Array RenderingServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) const { - SurfaceData sd = mesh_get_surface(p_mesh, p_surface); return mesh_create_arrays_from_surface_data(sd); } Dictionary RenderingServer::mesh_surface_get_lods(RID p_mesh, int p_surface) const { - SurfaceData sd = mesh_get_surface(p_mesh, p_surface); ERR_FAIL_COND_V(sd.vertex_count == 0, Dictionary()); @@ -1514,7 +1392,6 @@ Dictionary RenderingServer::mesh_surface_get_lods(RID p_mesh, int p_surface) con } Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const { - SurfaceData sd = mesh_get_surface(p_mesh, p_surface); ERR_FAIL_COND_V(sd.vertex_count == 0, Array()); @@ -1541,7 +1418,6 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur } Array RenderingServer::mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const { - Vector<uint8_t> vertex_data = p_data.vertex_data; ERR_FAIL_COND_V(vertex_data.size() == 0, Array()); @@ -1567,42 +1443,69 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su #endif ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { - switch (p_type) { - case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; - case RS::GLOBAL_VAR_TYPE_BVEC2: return ShaderLanguage::TYPE_BVEC2; - case RS::GLOBAL_VAR_TYPE_BVEC3: return ShaderLanguage::TYPE_BVEC3; - case RS::GLOBAL_VAR_TYPE_BVEC4: return ShaderLanguage::TYPE_BVEC4; - case RS::GLOBAL_VAR_TYPE_INT: return ShaderLanguage::TYPE_INT; - case RS::GLOBAL_VAR_TYPE_IVEC2: return ShaderLanguage::TYPE_IVEC2; - case RS::GLOBAL_VAR_TYPE_IVEC3: return ShaderLanguage::TYPE_IVEC3; - case RS::GLOBAL_VAR_TYPE_IVEC4: return ShaderLanguage::TYPE_IVEC4; - case RS::GLOBAL_VAR_TYPE_RECT2I: return ShaderLanguage::TYPE_IVEC4; - case RS::GLOBAL_VAR_TYPE_UINT: return ShaderLanguage::TYPE_UINT; - case RS::GLOBAL_VAR_TYPE_UVEC2: return ShaderLanguage::TYPE_UVEC2; - case RS::GLOBAL_VAR_TYPE_UVEC3: return ShaderLanguage::TYPE_UVEC3; - case RS::GLOBAL_VAR_TYPE_UVEC4: return ShaderLanguage::TYPE_UVEC4; - case RS::GLOBAL_VAR_TYPE_FLOAT: return ShaderLanguage::TYPE_FLOAT; - case RS::GLOBAL_VAR_TYPE_VEC2: return ShaderLanguage::TYPE_VEC2; - case RS::GLOBAL_VAR_TYPE_VEC3: return ShaderLanguage::TYPE_VEC3; - case RS::GLOBAL_VAR_TYPE_VEC4: return ShaderLanguage::TYPE_VEC4; - case RS::GLOBAL_VAR_TYPE_COLOR: return ShaderLanguage::TYPE_VEC4; - case RS::GLOBAL_VAR_TYPE_RECT2: return ShaderLanguage::TYPE_VEC4; - case RS::GLOBAL_VAR_TYPE_MAT2: return ShaderLanguage::TYPE_MAT2; - case RS::GLOBAL_VAR_TYPE_MAT3: return ShaderLanguage::TYPE_MAT3; - case RS::GLOBAL_VAR_TYPE_MAT4: return ShaderLanguage::TYPE_MAT4; - case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: return ShaderLanguage::TYPE_MAT3; - case RS::GLOBAL_VAR_TYPE_TRANSFORM: return ShaderLanguage::TYPE_MAT4; - case RS::GLOBAL_VAR_TYPE_SAMPLER2D: return ShaderLanguage::TYPE_SAMPLER2D; - case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: return ShaderLanguage::TYPE_SAMPLER2DARRAY; - case RS::GLOBAL_VAR_TYPE_SAMPLER3D: return ShaderLanguage::TYPE_SAMPLER3D; - case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: return ShaderLanguage::TYPE_SAMPLERCUBE; - default: return ShaderLanguage::TYPE_MAX; //invalid or not found + case RS::GLOBAL_VAR_TYPE_BOOL: + return ShaderLanguage::TYPE_BOOL; + case RS::GLOBAL_VAR_TYPE_BVEC2: + return ShaderLanguage::TYPE_BVEC2; + case RS::GLOBAL_VAR_TYPE_BVEC3: + return ShaderLanguage::TYPE_BVEC3; + case RS::GLOBAL_VAR_TYPE_BVEC4: + return ShaderLanguage::TYPE_BVEC4; + case RS::GLOBAL_VAR_TYPE_INT: + return ShaderLanguage::TYPE_INT; + case RS::GLOBAL_VAR_TYPE_IVEC2: + return ShaderLanguage::TYPE_IVEC2; + case RS::GLOBAL_VAR_TYPE_IVEC3: + return ShaderLanguage::TYPE_IVEC3; + case RS::GLOBAL_VAR_TYPE_IVEC4: + return ShaderLanguage::TYPE_IVEC4; + case RS::GLOBAL_VAR_TYPE_RECT2I: + return ShaderLanguage::TYPE_IVEC4; + case RS::GLOBAL_VAR_TYPE_UINT: + return ShaderLanguage::TYPE_UINT; + case RS::GLOBAL_VAR_TYPE_UVEC2: + return ShaderLanguage::TYPE_UVEC2; + case RS::GLOBAL_VAR_TYPE_UVEC3: + return ShaderLanguage::TYPE_UVEC3; + case RS::GLOBAL_VAR_TYPE_UVEC4: + return ShaderLanguage::TYPE_UVEC4; + case RS::GLOBAL_VAR_TYPE_FLOAT: + return ShaderLanguage::TYPE_FLOAT; + case RS::GLOBAL_VAR_TYPE_VEC2: + return ShaderLanguage::TYPE_VEC2; + case RS::GLOBAL_VAR_TYPE_VEC3: + return ShaderLanguage::TYPE_VEC3; + case RS::GLOBAL_VAR_TYPE_VEC4: + return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_COLOR: + return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_RECT2: + return ShaderLanguage::TYPE_VEC4; + case RS::GLOBAL_VAR_TYPE_MAT2: + return ShaderLanguage::TYPE_MAT2; + case RS::GLOBAL_VAR_TYPE_MAT3: + return ShaderLanguage::TYPE_MAT3; + case RS::GLOBAL_VAR_TYPE_MAT4: + return ShaderLanguage::TYPE_MAT4; + case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: + return ShaderLanguage::TYPE_MAT3; + case RS::GLOBAL_VAR_TYPE_TRANSFORM: + return ShaderLanguage::TYPE_MAT4; + case RS::GLOBAL_VAR_TYPE_SAMPLER2D: + return ShaderLanguage::TYPE_SAMPLER2D; + case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: + return ShaderLanguage::TYPE_SAMPLER2DARRAY; + case RS::GLOBAL_VAR_TYPE_SAMPLER3D: + return ShaderLanguage::TYPE_SAMPLER3D; + case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: + return ShaderLanguage::TYPE_SAMPLERCUBE; + default: + return ShaderLanguage::TYPE_MAX; //invalid or not found } } void RenderingServer::_bind_methods() { - ClassDB::bind_method(D_METHOD("force_sync"), &RenderingServer::sync); ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers", "frame_step"), &RenderingServer::draw, DEFVAL(true), DEFVAL(0.0)); @@ -1755,8 +1658,8 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("gi_probe_set_compress", "probe", "enable"), &RenderingServer::gi_probe_set_compress); ClassDB::bind_method(D_METHOD("gi_probe_is_compressed", "probe"), &RenderingServer::gi_probe_is_compressed); #endif - - ClassDB::bind_method(D_METHOD("lightmap_capture_create"), &RenderingServer::lightmap_capture_create); +/* + ClassDB::bind_method(D_METHOD("lightmap_create()"), &RenderingServer::lightmap_capture_create); ClassDB::bind_method(D_METHOD("lightmap_capture_set_bounds", "capture", "bounds"), &RenderingServer::lightmap_capture_set_bounds); ClassDB::bind_method(D_METHOD("lightmap_capture_get_bounds", "capture"), &RenderingServer::lightmap_capture_get_bounds); ClassDB::bind_method(D_METHOD("lightmap_capture_set_octree", "capture", "octree"), &RenderingServer::lightmap_capture_set_octree); @@ -1767,6 +1670,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("lightmap_capture_get_octree", "capture"), &RenderingServer::lightmap_capture_get_octree); ClassDB::bind_method(D_METHOD("lightmap_capture_set_energy", "capture", "energy"), &RenderingServer::lightmap_capture_set_energy); ClassDB::bind_method(D_METHOD("lightmap_capture_get_energy", "capture"), &RenderingServer::lightmap_capture_get_energy); +*/ #endif ClassDB::bind_method(D_METHOD("particles_create"), &RenderingServer::particles_create); ClassDB::bind_method(D_METHOD("particles_set_emitting", "particles", "emitting"), &RenderingServer::particles_set_emitting); @@ -1866,7 +1770,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("instance_set_blend_shape_weight", "instance", "shape", "weight"), &RenderingServer::instance_set_blend_shape_weight); ClassDB::bind_method(D_METHOD("instance_set_surface_material", "instance", "surface", "material"), &RenderingServer::instance_set_surface_material); ClassDB::bind_method(D_METHOD("instance_set_visible", "instance", "visible"), &RenderingServer::instance_set_visible); - ClassDB::bind_method(D_METHOD("instance_set_use_lightmap", "instance", "lightmap_instance", "lightmap"), &RenderingServer::instance_set_use_lightmap); + // ClassDB::bind_method(D_METHOD("instance_set_use_lightmap", "instance", "lightmap_instance", "lightmap"), &RenderingServer::instance_set_use_lightmap); ClassDB::bind_method(D_METHOD("instance_set_custom_aabb", "instance", "aabb"), &RenderingServer::instance_set_custom_aabb); ClassDB::bind_method(D_METHOD("instance_attach_skeleton", "instance", "skeleton"), &RenderingServer::instance_attach_skeleton); ClassDB::bind_method(D_METHOD("instance_set_exterior", "instance", "enabled"), &RenderingServer::instance_set_exterior); @@ -1991,6 +1895,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("has_os_feature", "feature"), &RenderingServer::has_os_feature); ClassDB::bind_method(D_METHOD("set_debug_generate_wireframes", "generate"), &RenderingServer::set_debug_generate_wireframes); + ClassDB::bind_method(D_METHOD("is_render_loop_enabled"), &RenderingServer::is_render_loop_enabled); + ClassDB::bind_method(D_METHOD("set_render_loop_enabled", "enabled"), &RenderingServer::set_render_loop_enabled); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_loop_enabled"), "set_render_loop_enabled", "is_render_loop_enabled"); + BIND_CONSTANT(NO_INDEX_ARRAY); BIND_CONSTANT(ARRAY_WEIGHTS_SIZE); BIND_CONSTANT(CANVAS_ITEM_Z_MIN); @@ -1998,9 +1906,6 @@ void RenderingServer::_bind_methods() { BIND_CONSTANT(MAX_GLOW_LEVELS); BIND_CONSTANT(MAX_CURSORS); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); - BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); - BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP); BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY); @@ -2018,6 +1923,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(SHADER_SKY); BIND_ENUM_CONSTANT(SHADER_MAX); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN); + BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); BIND_ENUM_CONSTANT(ARRAY_NORMAL); BIND_ENUM_CONSTANT(ARRAY_TANGENT); @@ -2045,9 +1953,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); @@ -2070,6 +1979,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR); BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE); BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE); BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION); @@ -2080,6 +1990,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE); + BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR); + BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS); BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX); BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID); @@ -2095,6 +2008,12 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE); BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_EMISSION); + BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX); + BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_LIFETIME); BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_VIEW_DEPTH); @@ -2114,6 +2033,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X); BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X); + BIND_ENUM_CONSTANT(VIEWPORT_MSAA_MAX); + + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_DISABLED); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_FXAA); + BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_MAX); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME); BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME); @@ -2138,6 +2062,7 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER); BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS); + BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS); BIND_ENUM_CONSTANT(SKY_MODE_QUALITY); BIND_ENUM_CONSTANT(SKY_MODE_REALTIME); @@ -2170,6 +2095,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2); @@ -2180,6 +2110,11 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_LOW); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_HIGH); + BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_VERY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); @@ -2189,6 +2124,13 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(DOF_BOKEH_HEXAGON); BIND_ENUM_CONSTANT(DOF_BOKEH_CIRCLE); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_ULTRA); + BIND_ENUM_CONSTANT(SHADOW_QUALITY_MAX); + BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME); BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW); @@ -2201,8 +2143,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(INSTANCE_PARTICLES); BIND_ENUM_CONSTANT(INSTANCE_LIGHT); BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE); + BIND_ENUM_CONSTANT(INSTANCE_DECAL); BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE); - BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE); + BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP); BIND_ENUM_CONSTANT(INSTANCE_MAX); BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK); @@ -2298,27 +2241,22 @@ void RenderingServer::_bind_methods() { } void RenderingServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate) { - ERR_FAIL_COND(p_margins.size() != 4); //canvas_item_add_style_box(p_item,p_rect,p_source,p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate); } void RenderingServer::_camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) { - camera_set_orthogonal(p_camera, p_size, p_z_near, p_z_far); } -void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data) { - +void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry3D::MeshData &p_mesh_data) { Vector<Vector3> vertices; Vector<Vector3> normals; for (int i = 0; i < p_mesh_data.faces.size(); i++) { - - const Geometry::MeshData::Face &f = p_mesh_data.faces[i]; + const Geometry3D::MeshData::Face &f = p_mesh_data.faces[i]; for (int j = 2; j < f.indices.size(); j++) { - #define _ADD_VERTEX(m_idx) \ vertices.push_back(p_mesh_data.vertices[f.indices[m_idx]]); \ normals.push_back(f.plane.normal); @@ -2337,8 +2275,7 @@ void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry } void RenderingServer::mesh_add_surface_from_planes(RID p_mesh, const Vector<Plane> &p_planes) { - - Geometry::MeshData mdata = Geometry::build_convex_mesh(p_planes); + Geometry3D::MeshData mdata = Geometry3D::build_convex_mesh(p_planes); mesh_add_surface_from_mesh_data(p_mesh, mdata); } @@ -2347,15 +2284,21 @@ void RenderingServer::immediate_vertex_2d(RID p_immediate, const Vector2 &p_vert } RID RenderingServer::instance_create2(RID p_base, RID p_scenario) { - RID instance = instance_create(); instance_set_base(instance, p_base); instance_set_scenario(instance, p_scenario); return instance; } -RenderingServer::RenderingServer() { +bool RenderingServer::is_render_loop_enabled() const { + return render_loop_enabled; +} +void RenderingServer::set_render_loop_enabled(bool p_enabled) { + render_loop_enabled = p_enabled; +} + +RenderingServer::RenderingServer() { //ERR_FAIL_COND(singleton); singleton = this; @@ -2365,6 +2308,9 @@ RenderingServer::RenderingServer() { GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true); GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false); + GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); + 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")); @@ -2413,7 +2359,8 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false); - GLOBAL_DEF("rendering/quality/texture_filters/max_anisotropy", 4); + GLOBAL_DEF("rendering/quality/texture_filters/anisotropic_filtering_level", 2); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/texture_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/quality/texture_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)")); GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)")); @@ -2445,9 +2392,11 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001")); GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536); + + GLOBAL_DEF("rendering/lightmapper/probe_capture_update_speed", 15); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapper/probe_capture_update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapper/probe_capture_update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001")); } RenderingServer::~RenderingServer() { - singleton = nullptr; } diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 3bc182a16b..56a8325630 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -32,21 +32,22 @@ #define RENDERING_SERVER_H #include "core/image.h" -#include "core/math/geometry.h" +#include "core/math/geometry_3d.h" #include "core/math/transform_2d.h" #include "core/object.h" #include "core/rid.h" +#include "core/typed_array.h" #include "core/variant.h" #include "servers/display_server.h" #include "servers/rendering/shader_language.h" class RenderingServer : public Object { - GDCLASS(RenderingServer, Object); static RenderingServer *singleton; int mm_policy; + bool render_loop_enabled = true; void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far); void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1)); @@ -86,7 +87,6 @@ public: }; enum CubeMapLayer { - CUBEMAP_LAYER_LEFT, CUBEMAP_LAYER_RIGHT, CUBEMAP_LAYER_BOTTOM, @@ -107,7 +107,7 @@ public: //these two APIs can be used together or in combination with the others. virtual RID texture_2d_placeholder_create() = 0; - virtual RID texture_2d_layered_placeholder_create() = 0; + virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_layered_type) = 0; virtual RID texture_3d_placeholder_create() = 0; virtual Ref<Image> texture_2d_get(RID p_texture) const = 0; @@ -158,7 +158,6 @@ public: /* SHADER API */ enum ShaderMode { - SHADER_SPATIAL, SHADER_CANVAS_ITEM, SHADER_PARTICLES, @@ -182,8 +181,8 @@ public: enum { MATERIAL_RENDER_PRIORITY_MIN = -128, MATERIAL_RENDER_PRIORITY_MAX = 127, - }; + virtual RID material_create() = 0; virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0; @@ -198,7 +197,6 @@ public: /* MESH API */ enum ArrayType { - ARRAY_VERTEX = 0, ARRAY_NORMAL = 1, ARRAY_TANGENT = 2, @@ -230,12 +228,10 @@ public: ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), + ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2, ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 - }; enum PrimitiveType { @@ -248,7 +244,6 @@ public: }; struct SurfaceData { - PrimitiveType primitive = PRIMITIVE_MAX; uint32_t format = 0; @@ -378,7 +373,6 @@ public: }; enum LightParam { - LIGHT_PARAM_ENERGY, LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, @@ -528,19 +522,20 @@ public: virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0; virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0; - /* LIGHTMAP CAPTURE */ + /* LIGHTMAP */ + + virtual RID lightmap_create() = 0; - virtual RID lightmap_capture_create() = 0; - virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) = 0; - virtual AABB lightmap_capture_get_bounds(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) = 0; - virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) = 0; - virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const = 0; - virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) = 0; - virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const = 0; - virtual Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const = 0; - virtual void lightmap_capture_set_energy(RID p_capture, float p_energy) = 0; - virtual float lightmap_capture_get_energy(RID p_capture) const = 0; + virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0; + virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0; + virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0; + virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0; + virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0; + virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0; + virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0; + + virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0; /* PARTICLES API */ @@ -599,7 +594,8 @@ public: }; virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0; -*/ + */ + /* VIEWPORT TARGET API */ virtual RID viewport_create() = 0; @@ -623,7 +619,6 @@ public: virtual void viewport_set_update_mode(RID p_viewport, ViewportUpdateMode p_mode) = 0; enum ViewportClearMode { - VIEWPORT_CLEAR_ALWAYS, VIEWPORT_CLEAR_NEVER, VIEWPORT_CLEAR_ONLY_NEXT_FRAME @@ -664,18 +659,19 @@ public: enum ViewportScreenSpaceAA { VIEWPORT_SCREEN_SPACE_AA_DISABLED, VIEWPORT_SCREEN_SPACE_AA_FXAA, + VIEWPORT_SCREEN_SPACE_AA_MAX, }; + virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0; enum ViewportRenderInfo { - VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME, VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME, VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME, VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME, - VIEWPORT_RENDER_INFO_MAX + VIEWPORT_RENDER_INFO_MAX, }; virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0; @@ -697,7 +693,6 @@ public: VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER, VIEWPORT_DEBUG_DRAW_PSSM_SPLITS, VIEWPORT_DEBUG_DRAW_DECAL_ATLAS, - }; virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0; @@ -719,13 +714,13 @@ public: virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0; virtual void sky_set_mode(RID p_sky, SkyMode p_mode) = 0; virtual void sky_set_material(RID p_sky, RID p_material) = 0; + virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0; /* ENVIRONMENT API */ virtual RID environment_create() = 0; enum EnvironmentBG { - ENV_BG_CLEAR_COLOR, ENV_BG_COLOR, ENV_BG_SKY, @@ -768,6 +763,7 @@ public: ENV_GLOW_BLEND_MODE_REPLACE, ENV_GLOW_BLEND_MODE_MIX, }; + virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; @@ -815,6 +811,8 @@ public: 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 Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; + virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0; enum SubSurfaceScatteringQuality { @@ -872,7 +870,6 @@ public: SCENARIO_DEBUG_WIREFRAME, SCENARIO_DEBUG_OVERDRAW, SCENARIO_DEBUG_SHADELESS, - }; virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0; @@ -883,7 +880,6 @@ public: /* INSTANCING API */ enum InstanceType { - INSTANCE_NONE, INSTANCE_MESH, INSTANCE_MULTIMESH, @@ -893,7 +889,7 @@ public: INSTANCE_REFLECTION_PROBE, INSTANCE_DECAL, INSTANCE_GI_PROBE, - INSTANCE_LIGHTMAP_CAPTURE, + INSTANCE_LIGHTMAP, INSTANCE_MAX, INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES) @@ -912,8 +908,6 @@ public: virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0; virtual void instance_set_visible(RID p_instance, bool p_visible) = 0; - virtual void instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap) = 0; - virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0; virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0; @@ -950,12 +944,24 @@ public: virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0; virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0; + virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice) = 0; virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0; virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0; virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0; virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0; + /* Bake 3D objects */ + + enum BakeChannels { + BAKE_CHANNEL_ALBEDO_ALPHA, + BAKE_CHANNEL_NORMAL, + BAKE_CHANNEL_ORM, + BAKE_CHANNEL_EMISSION + }; + + virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0; + /* CANVAS (2D) */ virtual RID canvas_create() = 0; @@ -1094,6 +1100,7 @@ public: CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0; /* GLOBAL VARIABLES */ @@ -1167,7 +1174,6 @@ public: /* STATUS INFORMATION */ enum RenderInfo { - INFO_OBJECTS_IN_FRAME, INFO_VERTICES_IN_FRAME, INFO_MATERIAL_CHANGES_IN_FRAME, @@ -1194,8 +1200,6 @@ public: virtual Vector<FrameProfileArea> get_frame_profile() = 0; virtual uint64_t get_frame_profile_frame() = 0; - /* Materials for 2D on 3D */ - /* TESTING */ virtual RID get_test_cube() = 0; @@ -1205,7 +1209,7 @@ public: virtual RID make_sphere_mesh(int p_lats, int p_lons, float p_radius); - virtual void mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data); + virtual void mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry3D::MeshData &p_mesh_data); virtual void mesh_add_surface_from_planes(RID p_mesh, const Vector<Plane> &p_planes); virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) = 0; @@ -1226,6 +1230,9 @@ public: virtual bool is_low_end() const = 0; + bool is_render_loop_enabled() const; + void set_render_loop_enabled(bool p_enabled); + RenderingServer(); virtual ~RenderingServer(); }; @@ -1250,6 +1257,7 @@ VARIANT_ENUM_CAST(RenderingServer::ParticlesDrawOrder); VARIANT_ENUM_CAST(RenderingServer::ViewportUpdateMode); VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode); VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA); +VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA); VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo); VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw); VARIANT_ENUM_CAST(RenderingServer::SkyMode); @@ -1258,10 +1266,13 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource); VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode); VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper); -VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality); VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOBlur); +VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality); +VARIANT_ENUM_CAST(RenderingServer::SubSurfaceScatteringQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBlurQuality); VARIANT_ENUM_CAST(RenderingServer::DOFBokehShape); +VARIANT_ENUM_CAST(RenderingServer::ShadowQuality); VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode); VARIANT_ENUM_CAST(RenderingServer::InstanceType); VARIANT_ENUM_CAST(RenderingServer::InstanceFlags); @@ -1276,7 +1287,7 @@ VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); VARIANT_ENUM_CAST(RenderingServer::RenderInfo); VARIANT_ENUM_CAST(RenderingServer::Features); -//typedef RenderingServer VS; // makes it easier to use +// Alias to make it easier to use. #define RS RenderingServer -#endif +#endif // RENDERING_SERVER_H diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index c1233ae810..e9858416ec 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -122,7 +122,7 @@ XRInterface::XRInterface() { tracking_state = XR_UNKNOWN_TRACKING; }; -XRInterface::~XRInterface(){}; +XRInterface::~XRInterface() {} // optional render to external texture which enhances performance on those platforms that require us to submit our end result into special textures. unsigned int XRInterface::get_external_texture_for_eye(XRInterface::Eyes p_eye) { @@ -134,9 +134,9 @@ bool XRInterface::get_anchor_detection_is_enabled() const { return false; }; -void XRInterface::set_anchor_detection_is_enabled(bool p_enable){ +void XRInterface::set_anchor_detection_is_enabled(bool p_enable) { // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. -}; +} int XRInterface::get_camera_feed_id() { // don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc. diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index 808b0a608f..ad5cee92ea 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -29,7 +29,8 @@ /*************************************************************************/ #include "xr_positional_tracker.h" -#include "core/input/input_filter.h" + +#include "core/input/input.h" void XRPositionalTracker::_bind_methods() { BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN); @@ -231,7 +232,3 @@ XRPositionalTracker::XRPositionalTracker() { hand = TRACKER_HAND_UNKNOWN; rumble = 0.0; }; - -XRPositionalTracker::~XRPositionalTracker(){ - -}; diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index d9d1f909e9..515359e9b1 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -96,7 +96,7 @@ public: Transform get_transform(bool p_adjust_by_reference_frame) const; XRPositionalTracker(); - ~XRPositionalTracker(); + ~XRPositionalTracker() {} }; VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand); diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index a93b99025f..09800443b7 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -152,7 +152,6 @@ void XRServer::add_interface(const Ref<XRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); for (int i = 0; i < interfaces.size(); i++) { - if (interfaces[i] == p_interface) { ERR_PRINT("Interface was already added"); return; @@ -168,9 +167,7 @@ void XRServer::remove_interface(const Ref<XRInterface> &p_interface) { int idx = -1; for (int i = 0; i < interfaces.size(); i++) { - if (interfaces[i] == p_interface) { - idx = i; break; }; @@ -197,9 +194,7 @@ Ref<XRInterface> XRServer::get_interface(int p_index) const { Ref<XRInterface> XRServer::find_interface(const String &p_name) const { int idx = -1; for (int i = 0; i < interfaces.size(); i++) { - if (interfaces[i]->get_name() == p_name) { - idx = i; break; }; @@ -277,9 +272,7 @@ void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { int idx = -1; for (int i = 0; i < trackers.size(); i++) { - if (trackers[i] == p_tracker) { - idx = i; break; }; |