diff options
Diffstat (limited to 'scene/resources')
89 files changed, 2127 insertions, 697 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 7183accc66..69b30b72b0 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1563,33 +1563,35 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const { return -1; } -void Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) { - ERR_FAIL_INDEX(p_track, tracks.size()); +int Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) { + ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; + int ret = -1; + switch (t->type) { case TYPE_POSITION_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I)); - int idx = position_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1); + ret = position_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_ROTATION_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::QUATERNION) && (p_key.get_type() != Variant::BASIS)); - int idx = rotation_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::QUATERNION) && (p_key.get_type() != Variant::BASIS), -1); + ret = rotation_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_SCALE_3D: { - ERR_FAIL_COND((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I)); - int idx = scale_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1); + ret = scale_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_BLEND_SHAPE: { - ERR_FAIL_COND((p_key.get_type() != Variant::FLOAT) && (p_key.get_type() != Variant::INT)); - int idx = blend_shape_track_insert_key(p_track, p_time, p_key); - track_set_key_transition(p_track, idx, p_transition); + ERR_FAIL_COND_V((p_key.get_type() != Variant::FLOAT) && (p_key.get_type() != Variant::INT), -1); + ret = blend_shape_track_insert_key(p_track, p_time, p_key); + track_set_key_transition(p_track, ret, p_transition); } break; case TYPE_VALUE: { @@ -1599,17 +1601,17 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.time = p_time; k.transition = p_transition; k.value = p_key; - _insert(p_time, vt->values, k); + ret = _insert(p_time, vt->values, k); } break; case TYPE_METHOD: { MethodTrack *mt = static_cast<MethodTrack *>(t); - ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY); + ERR_FAIL_COND_V(p_key.get_type() != Variant::DICTIONARY, -1); Dictionary d = p_key; - ERR_FAIL_COND(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING)); - ERR_FAIL_COND(!d.has("args") || !d["args"].is_array()); + ERR_FAIL_COND_V(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING), -1); + ERR_FAIL_COND_V(!d.has("args") || !d["args"].is_array(), -1); MethodKey k; @@ -1618,14 +1620,14 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.method = d["method"]; k.params = d["args"]; - _insert(p_time, mt->methods, k); + ret = _insert(p_time, mt->methods, k); } break; case TYPE_BEZIER: { BezierTrack *bt = static_cast<BezierTrack *>(t); Array arr = p_key; - ERR_FAIL_COND(arr.size() != 6); + ERR_FAIL_COND_V(arr.size() != 6, -1); TKey<BezierKey> k; k.time = p_time; @@ -1635,23 +1637,23 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.value.out_handle.x = arr[3]; k.value.out_handle.y = arr[4]; k.value.handle_mode = static_cast<HandleMode>((int)arr[5]); - _insert(p_time, bt->values, k); + ret = _insert(p_time, bt->values, k); } break; case TYPE_AUDIO: { AudioTrack *at = static_cast<AudioTrack *>(t); Dictionary k = p_key; - ERR_FAIL_COND(!k.has("start_offset")); - ERR_FAIL_COND(!k.has("end_offset")); - ERR_FAIL_COND(!k.has("stream")); + ERR_FAIL_COND_V(!k.has("start_offset"), -1); + ERR_FAIL_COND_V(!k.has("end_offset"), -1); + ERR_FAIL_COND_V(!k.has("stream"), -1); TKey<AudioKey> ak; ak.time = p_time; ak.value.start_offset = k["start_offset"]; ak.value.end_offset = k["end_offset"]; ak.value.stream = k["stream"]; - _insert(p_time, at->values, ak); + ret = _insert(p_time, at->values, ak); } break; case TYPE_ANIMATION: { @@ -1661,12 +1663,14 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke ak.time = p_time; ak.value = p_key; - _insert(p_time, at->values, ak); + ret = _insert(p_time, at->values, ak); } break; } emit_changed(); + + return ret; } int Animation::track_get_key_count(int p_track) const { @@ -2302,7 +2306,7 @@ Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a } Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const { - return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c); + return p_a.spherical_cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const { @@ -2363,7 +2367,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Quaternion pa = p_pre_a; Quaternion pb = p_post_b; - return a.cubic_slerp(b, pa, pb, p_c); + return a.spherical_cubic_interpolate(b, pa, pb, p_c); } case Variant::AABB: { AABB a = p_a; diff --git a/scene/resources/animation.h b/scene/resources/animation.h index b4528ccd3a..bf9f786a0d 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -392,7 +392,7 @@ public: void track_set_enabled(int p_track, bool p_enabled); bool track_is_enabled(int p_track) const; - void track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition = 1); + int track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition = 1); void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition); void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value); void track_set_key_time(int p_track, int p_key_idx, double p_time); @@ -488,4 +488,4 @@ VARIANT_ENUM_CAST(Animation::UpdateMode); VARIANT_ENUM_CAST(Animation::HandleMode); VARIANT_ENUM_CAST(Animation::LoopMode); -#endif +#endif // ANIMATION_H diff --git a/scene/resources/animation_library.h b/scene/resources/animation_library.h index 7a69cd140a..d63807b6d7 100644 --- a/scene/resources/animation_library.h +++ b/scene/resources/animation_library.h @@ -63,4 +63,4 @@ public: AnimationLibrary(); }; -#endif // ANIMATIONLIBRARY_H +#endif // ANIMATION_LIBRARY_H diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_wav.cpp index 30c222bdff..a87c8272ea 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.cpp */ +/* audio_stream_wav.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "audio_stream_sample.h" +#include "audio_stream_wav.h" #include "core/io/file_access.h" #include "core/io/marshalls.h" -void AudioStreamPlaybackSample::start(float p_from_pos) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::start(float p_from_pos) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { //no seeking in IMA_ADPCM for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = 0; @@ -55,24 +55,24 @@ void AudioStreamPlaybackSample::start(float p_from_pos) { active = true; } -void AudioStreamPlaybackSample::stop() { +void AudioStreamPlaybackWAV::stop() { active = false; } -bool AudioStreamPlaybackSample::is_playing() const { +bool AudioStreamPlaybackWAV::is_playing() const { return active; } -int AudioStreamPlaybackSample::get_loop_count() const { +int AudioStreamPlaybackWAV::get_loop_count() const { return 0; } -float AudioStreamPlaybackSample::get_playback_position() const { +float AudioStreamPlaybackWAV::get_playback_position() const { return float(offset >> MIX_FRAC_BITS) / base->mix_rate; } -void AudioStreamPlaybackSample::seek(float p_time) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::seek(float p_time) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { return; //no seeking in ima-adpcm } @@ -87,7 +87,7 @@ void AudioStreamPlaybackSample::seek(float p_time) { } template <class Depth, bool is_stereo, bool is_ima_adpcm> -void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { +void AudioStreamPlaybackWAV::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { // this function will be compiled branchless by any decent compiler int32_t final, final_r, next, next_r; @@ -124,7 +124,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds ima_adpcm[i].last_nibble++; const uint8_t *src_ptr = (const uint8_t *)base->data; - src_ptr += AudioStreamSample::DATA_PAD; + src_ptr += AudioStreamWAV::DATA_PAD; uint8_t nbb = src_ptr[(ima_adpcm[i].last_nibble >> 1) * (is_stereo ? 2 : 1) + i]; nibble = (ima_adpcm[i].last_nibble & 1) ? (nbb >> 4) : (nbb & 0xF); @@ -221,7 +221,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds } } -int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { +int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { if (!base->data || !active) { for (int i = 0; i < p_frames; i++) { p_buffer[i] = AudioFrame(0, 0); @@ -231,13 +231,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int len = base->data_bytes; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -251,13 +251,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int64_t loop_begin_fp = ((int64_t)base->loop_begin << MIX_FRAC_BITS); int64_t loop_end_fp = ((int64_t)base->loop_end << MIX_FRAC_BITS); int64_t length_fp = ((int64_t)len << MIX_FRAC_BITS); - int64_t begin_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_begin_fp : 0; - int64_t end_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_end_fp : length_fp; + int64_t begin_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_begin_fp : 0; + int64_t end_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_end_fp : length_fp; bool is_stereo = base->stereo; int32_t todo = p_frames; - if (base->loop_mode == AudioStreamSample::LOOP_BACKWARD) { + if (base->loop_mode == AudioStreamWAV::LOOP_BACKWARD) { sign = -1; } @@ -271,20 +271,20 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int //looping - AudioStreamSample::LoopMode loop_format = base->loop_mode; - AudioStreamSample::Format format = base->format; + AudioStreamWAV::LoopMode loop_format = base->loop_mode; + AudioStreamWAV::Format format = base->format; /* audio data */ uint8_t *dataptr = (uint8_t *)base->data; - const void *data = dataptr + AudioStreamSample::DATA_PAD; + const void *data = dataptr + AudioStreamWAV::DATA_PAD; AudioFrame *dst_buff = p_buffer; - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { - if (loop_format != AudioStreamSample::LOOP_DISABLED) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED) { ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; - loop_format = AudioStreamSample::LOOP_FORWARD; + loop_format = AudioStreamWAV::LOOP_FORWARD; } } @@ -297,9 +297,9 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int if (increment < 0) { /* going backwards */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset < loop_begin_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset < loop_begin_fp) { /* loopstart reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_begin_fp + (loop_begin_fp - offset); increment = -increment; @@ -317,10 +317,10 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } else { /* going forward */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset >= loop_end_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset >= loop_end_fp) { /* loopend reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_end_fp - (offset - loop_end_fp); increment = -increment; @@ -328,7 +328,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } else { /* go to loop-begin */ - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = ima_adpcm[i].loop_step_index; ima_adpcm[i].predictor = ima_adpcm[i].loop_predictor; @@ -366,14 +366,14 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int todo -= target; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: { + case AudioStreamWAV::FORMAT_8_BITS: { if (is_stereo) { do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } } break; - case AudioStreamSample::FORMAT_16_BITS: { + case AudioStreamWAV::FORMAT_16_BITS: { if (is_stereo) { do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -381,7 +381,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: { + case AudioStreamWAV::FORMAT_IMA_ADPCM: { if (is_stereo) { do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -406,69 +406,73 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int return p_frames; } -AudioStreamPlaybackSample::AudioStreamPlaybackSample() {} +void AudioStreamPlaybackWAV::tag_used_streams() { + base->tag_used(get_playback_position()); +} + +AudioStreamPlaybackWAV::AudioStreamPlaybackWAV() {} ///////////////////// -void AudioStreamSample::set_format(Format p_format) { +void AudioStreamWAV::set_format(Format p_format) { format = p_format; } -AudioStreamSample::Format AudioStreamSample::get_format() const { +AudioStreamWAV::Format AudioStreamWAV::get_format() const { return format; } -void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) { +void AudioStreamWAV::set_loop_mode(LoopMode p_loop_mode) { loop_mode = p_loop_mode; } -AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const { +AudioStreamWAV::LoopMode AudioStreamWAV::get_loop_mode() const { return loop_mode; } -void AudioStreamSample::set_loop_begin(int p_frame) { +void AudioStreamWAV::set_loop_begin(int p_frame) { loop_begin = p_frame; } -int AudioStreamSample::get_loop_begin() const { +int AudioStreamWAV::get_loop_begin() const { return loop_begin; } -void AudioStreamSample::set_loop_end(int p_frame) { +void AudioStreamWAV::set_loop_end(int p_frame) { loop_end = p_frame; } -int AudioStreamSample::get_loop_end() const { +int AudioStreamWAV::get_loop_end() const { return loop_end; } -void AudioStreamSample::set_mix_rate(int p_hz) { +void AudioStreamWAV::set_mix_rate(int p_hz) { ERR_FAIL_COND(p_hz == 0); mix_rate = p_hz; } -int AudioStreamSample::get_mix_rate() const { +int AudioStreamWAV::get_mix_rate() const { return mix_rate; } -void AudioStreamSample::set_stereo(bool p_enable) { +void AudioStreamWAV::set_stereo(bool p_enable) { stereo = p_enable; } -bool AudioStreamSample::is_stereo() const { +bool AudioStreamWAV::is_stereo() const { return stereo; } -float AudioStreamSample::get_length() const { +float AudioStreamWAV::get_length() const { int len = data_bytes; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -480,11 +484,11 @@ float AudioStreamSample::get_length() const { return float(len) / mix_rate; } -bool AudioStreamSample::is_monophonic() const { +bool AudioStreamWAV::is_monophonic() const { return false; } -void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { +void AudioStreamWAV::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->lock(); if (data) { memfree(data); @@ -506,7 +510,7 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->unlock(); } -Vector<uint8_t> AudioStreamSample::get_data() const { +Vector<uint8_t> AudioStreamWAV::get_data() const { Vector<uint8_t> pv; if (data) { @@ -521,8 +525,8 @@ Vector<uint8_t> AudioStreamSample::get_data() const { return pv; } -Error AudioStreamSample::save_to_wav(const String &p_path) { - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { +Error AudioStreamWAV::save_to_wav(const String &p_path) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { WARN_PRINT("Saving IMA_ADPC samples are not supported yet"); return ERR_UNAVAILABLE; } @@ -540,13 +544,13 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { int byte_pr_sample = 0; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: byte_pr_sample = 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: byte_pr_sample = 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break; } @@ -579,19 +583,19 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { Vector<uint8_t> data = get_data(); const uint8_t *read_data = data.ptr(); switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { uint8_t data_point = (read_data[i] + 128); file->store_8(data_point); } break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: for (unsigned int i = 0; i < data_bytes / 2; i++) { uint16_t data_point = decode_uint16(&read_data[i * 2]); file->store_16(data_point); } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: //Unimplemented break; } @@ -599,40 +603,40 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { return OK; } -Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() { - Ref<AudioStreamPlaybackSample> sample; +Ref<AudioStreamPlayback> AudioStreamWAV::instantiate_playback() { + Ref<AudioStreamPlaybackWAV> sample; sample.instantiate(); - sample->base = Ref<AudioStreamSample>(this); + sample->base = Ref<AudioStreamWAV>(this); return sample; } -String AudioStreamSample::get_stream_name() const { +String AudioStreamWAV::get_stream_name() const { return ""; } -void AudioStreamSample::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data); - ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data); +void AudioStreamWAV::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamWAV::set_data); + ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamWAV::get_data); - ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamSample::set_format); - ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamSample::get_format); + ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamWAV::set_format); + ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamWAV::get_format); - ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamSample::set_loop_mode); - ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamSample::get_loop_mode); + ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamWAV::set_loop_mode); + ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamWAV::get_loop_mode); - ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamSample::set_loop_begin); - ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamSample::get_loop_begin); + ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamWAV::set_loop_begin); + ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamWAV::get_loop_begin); - ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamSample::set_loop_end); - ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamSample::get_loop_end); + ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamWAV::set_loop_end); + ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamWAV::get_loop_end); - ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamSample::set_mix_rate); - ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamSample::get_mix_rate); + ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamWAV::set_mix_rate); + ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamWAV::get_mix_rate); - ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamSample::set_stereo); - ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamSample::is_stereo); + ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamWAV::set_stereo); + ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamWAV::is_stereo); - ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav); + ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamWAV::save_to_wav); ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format"); @@ -652,9 +656,9 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_BACKWARD); } -AudioStreamSample::AudioStreamSample() {} +AudioStreamWAV::AudioStreamWAV() {} -AudioStreamSample::~AudioStreamSample() { +AudioStreamWAV::~AudioStreamWAV() { if (data) { memfree(data); data = nullptr; diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_wav.h index 357febc27a..d800388d96 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_wav.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.h */ +/* audio_stream_wav.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIO_STREAM_SAMPLE_H -#define AUDIO_STREAM_SAMPLE_H +#ifndef AUDIO_STREAM_WAV_H +#define AUDIO_STREAM_WAV_H #include "servers/audio/audio_stream.h" -class AudioStreamSample; +class AudioStreamWAV; -class AudioStreamPlaybackSample : public AudioStreamPlayback { - GDCLASS(AudioStreamPlaybackSample, AudioStreamPlayback); +class AudioStreamPlaybackWAV : public AudioStreamPlayback { + GDCLASS(AudioStreamPlaybackWAV, AudioStreamPlayback); enum { MIX_FRAC_BITS = 13, MIX_FRAC_LEN = (1 << MIX_FRAC_BITS), @@ -57,8 +57,8 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback { int64_t offset = 0; int sign = 1; bool active = false; - friend class AudioStreamSample; - Ref<AudioStreamSample> base; + friend class AudioStreamWAV; + Ref<AudioStreamWAV> base; template <class Depth, bool is_stereo, bool is_ima_adpcm> void do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm); @@ -75,11 +75,13 @@ public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; - AudioStreamPlaybackSample(); + virtual void tag_used_streams() override; + + AudioStreamPlaybackWAV(); }; -class AudioStreamSample : public AudioStream { - GDCLASS(AudioStreamSample, AudioStream); +class AudioStreamWAV : public AudioStream { + GDCLASS(AudioStreamWAV, AudioStream); RES_BASE_EXTENSION("sample") public: @@ -98,7 +100,7 @@ public: }; private: - friend class AudioStreamPlaybackSample; + friend class AudioStreamPlaybackWAV; enum { DATA_PAD = 16 //padding for interpolation @@ -144,14 +146,14 @@ public: Error save_to_wav(const String &p_path); - virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; - AudioStreamSample(); - ~AudioStreamSample(); + AudioStreamWAV(); + ~AudioStreamWAV(); }; -VARIANT_ENUM_CAST(AudioStreamSample::Format) -VARIANT_ENUM_CAST(AudioStreamSample::LoopMode) +VARIANT_ENUM_CAST(AudioStreamWAV::Format) +VARIANT_ENUM_CAST(AudioStreamWAV::LoopMode) -#endif // AUDIO_STREAM_SAMPLE_H +#endif // AUDIO_STREAM_WAV_H diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 1ff72825ac..bef431e980 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -669,7 +669,7 @@ void BitMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_size"), &BitMap::get_size); ClassDB::bind_method(D_METHOD("resize", "new_size"), &BitMap::resize); - ClassDB::bind_method(D_METHOD("_set_data"), &BitMap::_set_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &BitMap::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &BitMap::_get_data); ClassDB::bind_method(D_METHOD("grow_mask", "pixels", "rect"), &BitMap::grow_mask); diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h index 4e6db893af..3dd0bb6cb7 100644 --- a/scene/resources/box_shape_3d.h +++ b/scene/resources/box_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BOX_SHAPE_H -#define BOX_SHAPE_H +#ifndef BOX_SHAPE_3D_H +#define BOX_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -56,4 +56,4 @@ public: BoxShape3D(); }; -#endif // BOX_SHAPE_H +#endif // BOX_SHAPE_3D_H diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index 4c039ab326..ad7f2e5b74 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAPSULE_SHAPE_H -#define CAPSULE_SHAPE_H +#ifndef CAPSULE_SHAPE_3D_H +#define CAPSULE_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -55,4 +55,4 @@ public: CapsuleShape3D(); }; -#endif // CAPSULE_SHAPE_H +#endif // CAPSULE_SHAPE_3D_H diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h index 0f49a0d80f..d350d753b0 100644 --- a/scene/resources/concave_polygon_shape_2d.h +++ b/scene/resources/concave_polygon_shape_2d.h @@ -52,4 +52,4 @@ public: ConcavePolygonShape2D(); }; -#endif +#endif // CONCAVE_POLYGON_SHAPE_2D_H diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h index a265590edd..68feacfa25 100644 --- a/scene/resources/concave_polygon_shape_3d.h +++ b/scene/resources/concave_polygon_shape_3d.h @@ -77,4 +77,4 @@ public: ConcavePolygonShape3D(); }; -#endif // CONCAVE_POLYGON_SHAPE_H +#endif // CONCAVE_POLYGON_SHAPE_3D_H diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h index 930edb015d..5ca4d2a713 100644 --- a/scene/resources/convex_polygon_shape_3d.h +++ b/scene/resources/convex_polygon_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CONVEX_POLYGON_SHAPE_H -#define CONVEX_POLYGON_SHAPE_H +#ifndef CONVEX_POLYGON_SHAPE_3D_H +#define CONVEX_POLYGON_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -52,4 +52,4 @@ public: ConvexPolygonShape3D(); }; -#endif // CONVEX_POLYGON_SHAPE_H +#endif // CONVEX_POLYGON_SHAPE_3D_H diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index da26a0261f..5de92acb75 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -1190,7 +1190,7 @@ void Curve2D::_bind_methods() { ClassDB::bind_method(D_METHOD("tessellate", "max_stages", "tolerance_degrees"), &Curve2D::tessellate, DEFVAL(5), DEFVAL(4)); ClassDB::bind_method(D_METHOD("_get_data"), &Curve2D::_get_data); - ClassDB::bind_method(D_METHOD("_set_data"), &Curve2D::_set_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &Curve2D::_set_data); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval"); ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); @@ -2002,7 +2002,7 @@ void Curve3D::_bind_methods() { ClassDB::bind_method(D_METHOD("tessellate", "max_stages", "tolerance_degrees"), &Curve3D::tessellate, DEFVAL(5), DEFVAL(4)); ClassDB::bind_method(D_METHOD("_get_data"), &Curve3D::_get_data); - ClassDB::bind_method(D_METHOD("_set_data"), &Curve3D::_set_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &Curve3D::_set_data); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval"); ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index 65427423c8..f554358044 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -54,4 +54,4 @@ public: CylinderShape3D(); }; -#endif // CYLINDER_SHAPE_H +#endif // CYLINDER_SHAPE_3D_H diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 520a0a04ed..fa375795c1 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -741,7 +741,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_selected_color", "Tree", control_font_pressed_color); theme->set_color("font_outline_color", "Tree", Color(1, 1, 1)); theme->set_color("guide_color", "Tree", Color(0.7, 0.7, 0.7, 0.25)); - theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); + theme->set_color("drop_position_color", "Tree", Color(1, 1, 1)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("parent_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); @@ -776,7 +776,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color", "ItemList", control_font_lower_color); theme->set_color("font_selected_color", "ItemList", control_font_pressed_color); theme->set_color("font_outline_color", "ItemList", Color(1, 1, 1)); - theme->set_color("guide_color", "ItemList", Color(0, 0, 0, 0.1)); + theme->set_color("guide_color", "ItemList", Color(0.7, 0.7, 0.7, 0.25)); theme->set_stylebox("selected", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("selected_focus", "ItemList", make_flat_stylebox(style_selected_color)); theme->set_stylebox("cursor", "ItemList", focus); diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index f777330a07..9b070a90cc 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -39,4 +39,4 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, bool p_font_antialiased = true, bool p_font_msdf = false, bool p_font_generate_mipmaps = false); void clear_default_theme(); -#endif +#endif // DEFAULT_THEME_H diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 854bd34d6a..d361b34da8 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1249,8 +1249,8 @@ void Environment::_bind_methods() { ADD_GROUP("SSR", "ssr_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssr_enabled"), "set_ssr_enabled", "is_ssr_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ssr_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_in", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_in", "get_ssr_fade_in"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_fade_out", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssr_fade_out", "get_ssr_fade_out"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssr_depth_tolerance", PROPERTY_HINT_RANGE, "0.01,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); // SSAO @@ -1277,7 +1277,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.01,16,0.01,or_greater"), "set_ssao_radius", "get_ssao_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_ssao_intensity", "get_ssao_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING), "set_ssao_power", "get_ssao_power"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_power", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_ssao_power", "get_ssao_power"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_detail", PROPERTY_HINT_RANGE, "0,5,0.01"), "set_ssao_detail", "get_ssao_detail"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_horizon", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_horizon", "get_ssao_horizon"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_sharpness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ssao_sharpness", "get_ssao_sharpness"); @@ -1337,8 +1337,10 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_bounce_feedback", PROPERTY_HINT_RANGE, "0,1.99,0.01"), "set_sdfgi_bounce_feedback", "get_sdfgi_bounce_feedback"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_cascades", PROPERTY_HINT_RANGE, "1,8,1"), "set_sdfgi_cascades", "get_sdfgi_cascades"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_min_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_sdfgi_min_cell_size", "get_sdfgi_min_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater"), "set_sdfgi_max_distance", "get_sdfgi_max_distance"); + // Don't store the values of `sdfgi_cascade0_distance` and `sdfgi_max_distance` + // as they're derived from `sdfgi_min_cell_size`. + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_cascade0_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater", PROPERTY_USAGE_EDITOR), "set_sdfgi_cascade0_distance", "get_sdfgi_cascade0_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_max_distance", PROPERTY_HINT_RANGE, "0.1,16384,0.1,or_greater", PROPERTY_USAGE_EDITOR), "set_sdfgi_max_distance", "get_sdfgi_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sdfgi_y_scale", PROPERTY_HINT_ENUM, "50% (Compact),75% (Balanced),100% (Sparse)"), "set_sdfgi_y_scale", "get_sdfgi_y_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_energy"), "set_sdfgi_energy", "get_sdfgi_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sdfgi_normal_bias"), "set_sdfgi_normal_bias", "get_sdfgi_normal_bias"); @@ -1423,7 +1425,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_fog_density", "get_fog_density"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density"); @@ -1462,7 +1464,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_anisotropy", PROPERTY_HINT_RANGE, "-0.9,0.9,0.01"), "set_volumetric_fog_anisotropy", "get_volumetric_fog_anisotropy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "positive_only"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_ambient_inject", PROPERTY_HINT_RANGE, "0.0,16,0.01,exp"), "set_volumetric_fog_ambient_inject", "get_volumetric_fog_ambient_inject"); ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled"); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index b71fe8904a..385d815230 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -175,10 +175,10 @@ private: // Fog bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); + Color fog_light_color = Color(0.518, 0.553, 0.608); float fog_light_energy = 1.0; float fog_sun_scatter = 0.0; - float fog_density = 0.001; + float fog_density = 0.01; float fog_height = 0.0; float fog_height_density = 0.0; //can be negative to invert effect float fog_aerial_perspective = 0.0; @@ -194,8 +194,8 @@ private: float volumetric_fog_anisotropy = 0.2; float volumetric_fog_length = 64.0; float volumetric_fog_detail_spread = 2.0; - float volumetric_fog_gi_inject = 0.0; - float volumetric_fog_ambient_inject = false; + float volumetric_fog_gi_inject = 1.0; + float volumetric_fog_ambient_inject = 0.0; bool volumetric_fog_temporal_reproject = true; float volumetric_fog_temporal_reproject_amount = 0.9; void _update_volumetric_fog(); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index f61ac7fcaa..619036d296 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -79,9 +79,9 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL)); // Drawing char. - ClassDB::bind_method(D_METHOD("get_char_size", "char"), &Font::get_char_size); - ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0))); - ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("get_char_size", "char", "font_size"), &Font::get_char_size); + ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0))); // Helper functions. ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char); @@ -157,7 +157,7 @@ void Font::set_fallbacks(const TypedArray<Font> &p_fallbacks) { for (int i = 0; i < fallbacks.size(); i++) { Ref<Font> f = fallbacks[i]; if (f.is_valid()) { - f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + f->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } } _invalidate_rids(); @@ -2534,7 +2534,7 @@ void FontVariation::set_base_font(const Ref<Font> &p_font) { } base_font = p_font; if (base_font.is_valid()) { - base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } _invalidate_rids(); notify_property_list_changed(); @@ -2565,7 +2565,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2582,7 +2582,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2592,7 +2592,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); if (f.is_valid()) { theme_font = f; - theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); } return f; } @@ -2693,3 +2693,374 @@ FontVariation::FontVariation() { FontVariation::~FontVariation() { reset_state(); } + +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +void SystemFont::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &SystemFont::set_antialiased); + ClassDB::bind_method(D_METHOD("is_antialiased"), &SystemFont::is_antialiased); + + ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &SystemFont::set_generate_mipmaps); + ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &SystemFont::get_generate_mipmaps); + + ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &SystemFont::set_force_autohinter); + ClassDB::bind_method(D_METHOD("is_force_autohinter"), &SystemFont::is_force_autohinter); + + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &SystemFont::set_hinting); + ClassDB::bind_method(D_METHOD("get_hinting"), &SystemFont::get_hinting); + + ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &SystemFont::set_subpixel_positioning); + ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &SystemFont::get_subpixel_positioning); + + ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling); + ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling); + + ClassDB::bind_method(D_METHOD("get_font_names"), &SystemFont::get_font_names); + ClassDB::bind_method(D_METHOD("set_font_names", "names"), &SystemFont::set_font_names); + + ClassDB::bind_method(D_METHOD("set_font_style", "style"), &SystemFont::set_font_style); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "font_names"), "set_font_names", "get_font_names"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic"), "set_font_style", "get_font_style"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "get_generate_mipmaps"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), "set_subpixel_positioning", "get_subpixel_positioning"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks"); +} + +void SystemFont::_update_rids() const { + Ref<Font> f = _get_base_font_or_default(); + + rids.clear(); + if (fallbacks.is_empty() && f.is_valid()) { + RID rid = _get_rid(); + if (rid.is_valid()) { + rids.push_back(rid); + } + + const TypedArray<Font> &base_fallbacks = f->get_fallbacks(); + for (int i = 0; i < base_fallbacks.size(); i++) { + _update_rids_fb(base_fallbacks[i], 0); + } + } else { + _update_rids_fb(const_cast<SystemFont *>(this), 0); + } + dirty_rids = false; +} + +void SystemFont::_update_base_font() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + for (const String &E : names) { + if (E.is_empty()) { + continue; + } + + String path = OS::get_singleton()->get_system_font_path(E, style & TextServer::FONT_BOLD, style & TextServer::FONT_ITALIC); + if (path.is_empty()) { + continue; + } + Ref<FontFile> file; + file.instantiate(); + Error err = file->load_dynamic_font(path); + if (err != OK) { + continue; + } + + // If it's a font collection check all faces to match requested style. + for (int i = 0; i < file->get_face_count(); i++) { + file->set_face_index(0, i); + if (((file->get_font_style() & TextServer::FONT_BOLD) == (style & TextServer::FONT_BOLD)) && ((file->get_font_style() & TextServer::FONT_ITALIC) == (style & TextServer::FONT_ITALIC))) { + face_indeces.push_back(i); + } + } + if (face_indeces.is_empty()) { + face_indeces.push_back(0); + } + file->set_face_index(0, face_indeces[0]); + + // If it's a variable font, apply weight and italic coordinates to match requested style. + Dictionary ftr = file->get_supported_variation_list(); + if ((style & TextServer::FONT_BOLD) && ftr.has(TS->name_to_tag("weight"))) { + ftr_weight = 700; + } + if ((style & TextServer::FONT_ITALIC) && ftr.has(TS->name_to_tag("italic"))) { + ftr_italic = 1; + } + + // Apply font rendering settings. + file->set_antialiased(antialiased); + file->set_generate_mipmaps(mipmaps); + file->set_force_autohinter(force_autohinter); + file->set_hinting(hinting); + file->set_subpixel_positioning(subpixel_positioning); + file->set_oversampling(oversampling); + + base_font = file; + } + + if (base_font.is_valid()) { + base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + + _invalidate_rids(); + notify_property_list_changed(); +} + +void SystemFont::reset_state() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + theme_font.unref(); + } + + names.clear(); + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + style = 0; + antialiased = true; + mipmaps = false; + force_autohinter = false; + hinting = TextServer::HINTING_LIGHT; + subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; + oversampling = 0.f; + + Font::reset_state(); +} + +Ref<Font> SystemFont::_get_base_font_or_default() const { + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids)); + theme_font.unref(); + } + + if (base_font.is_valid()) { + return base_font; + } + + // Check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + List<StringName> theme_types; + Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + if (Theme::get_default().is_valid()) { + List<StringName> theme_types; + Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + + // If they don't exist, use any type to return the default/empty value. + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); + } + return f; + } + + return Ref<Font>(); +} + +void SystemFont::set_antialiased(bool p_antialiased) { + if (antialiased != p_antialiased) { + antialiased = p_antialiased; + if (base_font.is_valid()) { + base_font->set_antialiased(antialiased); + } + emit_changed(); + } +} + +bool SystemFont::is_antialiased() const { + return antialiased; +} + +void SystemFont::set_generate_mipmaps(bool p_generate_mipmaps) { + if (mipmaps != p_generate_mipmaps) { + mipmaps = p_generate_mipmaps; + if (base_font.is_valid()) { + base_font->set_generate_mipmaps(mipmaps); + } + emit_changed(); + } +} + +bool SystemFont::get_generate_mipmaps() const { + return mipmaps; +} + +void SystemFont::set_force_autohinter(bool p_force_autohinter) { + if (force_autohinter != p_force_autohinter) { + force_autohinter = p_force_autohinter; + if (base_font.is_valid()) { + base_font->set_force_autohinter(force_autohinter); + } + emit_changed(); + } +} + +bool SystemFont::is_force_autohinter() const { + return force_autohinter; +} + +void SystemFont::set_hinting(TextServer::Hinting p_hinting) { + if (hinting != p_hinting) { + hinting = p_hinting; + if (base_font.is_valid()) { + base_font->set_hinting(hinting); + } + emit_changed(); + } +} + +TextServer::Hinting SystemFont::get_hinting() const { + return hinting; +} + +void SystemFont::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) { + if (subpixel_positioning != p_subpixel) { + subpixel_positioning = p_subpixel; + if (base_font.is_valid()) { + base_font->set_subpixel_positioning(subpixel_positioning); + } + emit_changed(); + } +} + +TextServer::SubpixelPositioning SystemFont::get_subpixel_positioning() const { + return subpixel_positioning; +} + +void SystemFont::set_oversampling(real_t p_oversampling) { + if (oversampling != p_oversampling) { + oversampling = p_oversampling; + if (base_font.is_valid()) { + base_font->set_oversampling(oversampling); + } + emit_changed(); + } +} + +real_t SystemFont::get_oversampling() const { + return oversampling; +} + +void SystemFont::set_font_names(const PackedStringArray &p_names) { + if (names != p_names) { + names = p_names; + _update_base_font(); + } +} + +PackedStringArray SystemFont::get_font_names() const { + return names; +} + +void SystemFont::set_font_style(BitField<TextServer::FontStyle> p_style) { + if (style != p_style) { + style = p_style; + _update_base_font(); + } +} + +BitField<TextServer::FontStyle> SystemFont::get_font_style() const { + return style; +} + +int SystemFont::get_spacing(TextServer::SpacingType p_spacing) const { + if (base_font.is_valid()) { + return base_font->get_spacing(p_spacing); + } else { + return 0; + } +} + +RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + Dictionary var = p_variation_coordinates; + if (ftr_weight > 0 && !var.has(TS->name_to_tag("weight"))) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0 && !var.has(TS->name_to_tag("italic"))) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + + if (!face_indeces.is_empty()) { + int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1); + return f->find_variation(var, face_indeces[face_index], p_strength, p_transform); + } else { + return f->find_variation(var, 0, p_strength, p_transform); + } + } + return RID(); +} + +RID SystemFont::_get_rid() const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + if (!face_indeces.is_empty()) { + Dictionary var; + if (ftr_weight > 0) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + return f->find_variation(var, face_indeces[0]); + } else { + return f->_get_rid(); + } + } + return RID(); +} + +int64_t SystemFont::get_face_count() const { + return face_indeces.size(); +} + +SystemFont::SystemFont() { + /* NOP */ +} + +SystemFont::~SystemFont() { + reset_state(); +} diff --git a/scene/resources/font.h b/scene/resources/font.h index 7a42a4dfea..260b4e521f 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -41,7 +41,7 @@ class TextLine; class TextParagraph; /*************************************************************************/ -/* Font */ +/* Font */ /*************************************************************************/ class Font : public Resource { @@ -381,4 +381,74 @@ public: ~FontVariation(); }; -#endif /* FONT_H */ +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +class SystemFont : public Font { + GDCLASS(SystemFont, Font); + + PackedStringArray names; + BitField<TextServer::FontStyle> style = 0; + + mutable Ref<Font> theme_font; + + Ref<FontFile> base_font; + Vector<int> face_indeces; + int ftr_weight = 0; + int ftr_italic = 0; + + bool antialiased = true; + bool mipmaps = false; + bool force_autohinter = false; + TextServer::Hinting hinting = TextServer::HINTING_LIGHT; + TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; + real_t oversampling = 0.f; + +protected: + static void _bind_methods(); + + virtual void _update_base_font(); + virtual void _update_rids() const override; + + virtual void reset_state() override; + +public: + virtual Ref<Font> _get_base_font_or_default() const; + + virtual void set_antialiased(bool p_antialiased); + virtual bool is_antialiased() const; + + virtual void set_generate_mipmaps(bool p_generate_mipmaps); + virtual bool get_generate_mipmaps() const; + + virtual void set_force_autohinter(bool p_force_autohinter); + virtual bool is_force_autohinter() const; + + virtual void set_hinting(TextServer::Hinting p_hinting); + virtual TextServer::Hinting get_hinting() const; + + virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel); + virtual TextServer::SubpixelPositioning get_subpixel_positioning() const; + + virtual void set_oversampling(real_t p_oversampling); + virtual real_t get_oversampling() const; + + virtual void set_font_names(const PackedStringArray &p_names); + virtual PackedStringArray get_font_names() const; + + virtual void set_font_style(BitField<TextServer::FontStyle> p_style); + virtual BitField<TextServer::FontStyle> get_font_style() const override; + + virtual int get_spacing(TextServer::SpacingType p_spacing) const override; + + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID _get_rid() const override; + + int64_t get_face_count() const override; + + SystemFont(); + ~SystemFont(); +}; + +#endif // FONT_H diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index 79d1b15674..633238030b 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef HEIGHT_MAP_SHAPE_H -#define HEIGHT_MAP_SHAPE_H +#ifndef HEIGHT_MAP_SHAPE_3D_H +#define HEIGHT_MAP_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -60,4 +60,4 @@ public: HeightMapShape3D(); }; -#endif /* !HEIGHT_MAP_SHAPE_H */ +#endif // HEIGHT_MAP_SHAPE_3D_H diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h index e5f627ae8e..de10fdbfbe 100644 --- a/scene/resources/immediate_mesh.h +++ b/scene/resources/immediate_mesh.h @@ -115,4 +115,4 @@ public: ~ImmediateMesh(); }; -#endif // IMMEDIATEMESH_H +#endif // IMMEDIATE_MESH_H diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index 8f77597a58..bf1d0301d1 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_IMPORTER_MESH_H -#define SCENE_IMPORTER_MESH_H +#ifndef IMPORTER_MESH_H +#define IMPORTER_MESH_H #include "core/io/resource.h" #include "core/templates/local_vector.h" @@ -130,4 +130,5 @@ public: Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>()); void clear(); }; -#endif // SCENE_IMPORTER_MESH_H + +#endif // IMPORTER_MESH_H diff --git a/scene/resources/label_settings.cpp b/scene/resources/label_settings.cpp index e8b986b431..ef380a68f9 100644 --- a/scene/resources/label_settings.cpp +++ b/scene/resources/label_settings.cpp @@ -99,7 +99,7 @@ void LabelSettings::set_font(const Ref<Font> &p_font) { } font = p_font; if (font.is_valid()) { - font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), varray(), CONNECT_REFERENCE_COUNTED); + font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), CONNECT_REFERENCE_COUNTED); } emit_changed(); } diff --git a/scene/resources/label_settings.h b/scene/resources/label_settings.h index d2644a7484..062d499d50 100644 --- a/scene/resources/label_settings.h +++ b/scene/resources/label_settings.h @@ -39,17 +39,17 @@ class LabelSettings : public Resource { GDCLASS(LabelSettings, Resource); - real_t line_spacing = 0; + real_t line_spacing = 3; Ref<Font> font; int font_size = Font::DEFAULT_FONT_SIZE; - Color font_color = Color(0.875, 0.875, 0.875); + Color font_color = Color(1, 1, 1); int outline_size = 0; Color outline_color = Color(1, 1, 1); - int shadow_size = 0; - Color shadow_color = Color(1, 1, 1); + int shadow_size = 1; + Color shadow_color = Color(0, 0, 0, 0); Vector2 shadow_offset = Vector2(1, 1); void _font_changed(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b7a3b677f5..88bc01fb25 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -154,18 +154,18 @@ Material::~Material() { bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } - if (n.find("shader_param/") == 0) { //backwards compatibility - pr = n.replace_first("shader_param/", ""); + if (n.find("shader_uniform/") == 0) { //backwards compatibility + pr = n.replace_first("shader_uniform/", ""); } } if (pr) { - set_shader_param(pr, p_value); + set_shader_uniform(pr, p_value); return true; } } @@ -175,14 +175,14 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (!pr) { String n = p_name; if (n.find("param/") == 0) { //backwards compatibility pr = n.substr(6, n.length()); } - if (n.find("shader_param/") == 0) { //backwards compatibility - pr = n.replace_first("shader_param/", ""); + if (n.find("shader_uniform/") == 0) { //backwards compatibility + pr = n.replace_first("shader_uniform/", ""); } } @@ -202,13 +202,104 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!shader.is_null()) { - shader->get_param_list(p_list); + List<PropertyInfo> list; + shader->get_shader_uniform_list(&list, true); + + HashMap<String, HashMap<String, List<PropertyInfo>>> groups; + { + HashMap<String, List<PropertyInfo>> none_subgroup; + none_subgroup.insert("<None>", List<PropertyInfo>()); + groups.insert("<None>", none_subgroup); + } + + String last_group = "<None>"; + String last_subgroup = "<None>"; + + bool is_none_group_undefined = true; + bool is_none_group = true; + + for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { + if (E->get().usage == PROPERTY_USAGE_GROUP) { + if (!E->get().name.is_empty()) { + Vector<String> vgroup = E->get().name.split("::"); + last_group = vgroup[0]; + if (vgroup.size() > 1) { + last_subgroup = vgroup[1]; + } else { + last_subgroup = "<None>"; + } + is_none_group = false; + + if (!groups.has(last_group)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = last_group.capitalize(); + + List<PropertyInfo> none_subgroup; + none_subgroup.push_back(info); + + HashMap<String, List<PropertyInfo>> subgroup_map; + subgroup_map.insert("<None>", none_subgroup); + + groups.insert(last_group, subgroup_map); + } + + if (!groups[last_group].has(last_subgroup)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_SUBGROUP; + info.name = last_subgroup.capitalize(); + + List<PropertyInfo> subgroup; + subgroup.push_back(info); + + groups[last_group].insert(last_subgroup, subgroup); + } + } else { + last_group = "<None>"; + last_subgroup = "<None>"; + is_none_group = true; + } + continue; // Pass group. + } + + if (is_none_group_undefined && is_none_group) { + is_none_group_undefined = false; + + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = "Shader Param"; + groups["<None>"]["<None>"].push_back(info); + } + + PropertyInfo info = E->get(); + info.name = info.name; + groups[last_group][last_subgroup].push_back(info); + } + + // Sort groups alphabetically. + List<UniformProp> props; + for (HashMap<String, HashMap<String, List<PropertyInfo>>>::Iterator group = groups.begin(); group; ++group) { + for (HashMap<String, List<PropertyInfo>>::Iterator subgroup = group->value.begin(); subgroup; ++subgroup) { + for (List<PropertyInfo>::Element *item = subgroup->value.front(); item; item = item->next()) { + if (subgroup->key == "<None>") { + props.push_back({ group->key, item->get() }); + } else { + props.push_back({ group->key + "::" + subgroup->key, item->get() }); + } + } + } + } + props.sort_custom<UniformPropComparator>(); + + for (List<UniformProp>::Element *E = props.front(); E; E = E->next()) { + p_list->push_back(E->get().info); + } } } bool ShaderMaterial::property_can_revert(const String &p_name) { if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (pr) { Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); Variant current_value; @@ -222,7 +313,7 @@ bool ShaderMaterial::property_can_revert(const String &p_name) { Variant ShaderMaterial::property_get_revert(const String &p_name) { Variant r_ret; if (shader.is_valid()) { - StringName pr = shader->remap_param(p_name); + StringName pr = shader->remap_uniform(p_name); if (pr) { r_ret = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); } @@ -258,7 +349,7 @@ Ref<Shader> ShaderMaterial::get_shader() const { return shader; } -void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) { +void ShaderMaterial::set_shader_uniform(const StringName &p_param, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { param_cache.erase(p_param); RS::get_singleton()->material_set_param(_get_material(), p_param, Variant()); @@ -278,7 +369,7 @@ void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant & } } -Variant ShaderMaterial::get_shader_param(const StringName &p_param) const { +Variant ShaderMaterial::get_shader_uniform(const StringName &p_param) const { if (param_cache.has(p_param)) { return param_cache[p_param]; } else { @@ -293,8 +384,8 @@ void ShaderMaterial::_shader_changed() { void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader); ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader); - ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param); - ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param); + ClassDB::bind_method(D_METHOD("set_shader_uniform", "param", "value"), &ShaderMaterial::set_shader_uniform); + ClassDB::bind_method(D_METHOD("get_shader_uniform", "param"), &ShaderMaterial::get_shader_uniform); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ShaderMaterial::property_can_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ShaderMaterial::property_get_revert); @@ -303,12 +394,12 @@ void ShaderMaterial::_bind_methods() { void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { String f = p_function.operator String(); - if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) { + if ((f == "get_shader_uniform" || f == "set_shader_uniform") && p_idx == 0) { if (shader.is_valid()) { List<PropertyInfo> pl; - shader->get_param_list(&pl); + shader->get_shader_uniform_list(&pl); for (const PropertyInfo &E : pl) { - r_options->push_back(E.name.replace_first("shader_param/", "").quote()); + r_options->push_back(E.name.replace_first("shader_uniform/", "").quote()); } } } @@ -976,7 +1067,8 @@ void BaseMaterial3D::_update_shader() { code += " float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; code += " float layer_depth = 1.0 / num_layers;\n"; code += " float current_layer_depth = 0.0;\n"; - code += " vec2 P = view_dir.xy * heightmap_scale;\n"; + // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. + code += " vec2 P = view_dir.xy * heightmap_scale * 0.01;\n"; code += " vec2 delta = P / num_layers;\n"; code += " vec2 ofs = base_uv;\n"; if (flags[FLAG_INVERT_HEIGHTMAP]) { @@ -1012,7 +1104,8 @@ void BaseMaterial3D::_update_shader() { } // Use offset limiting to improve the appearance of non-deep parallax. // This reduces the impression of depth, but avoids visible warping in the distance. - code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale;\n"; + // Multiply the heightmap scale by 0.01 to improve heightmap scale usability. + code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale * 0.01;\n"; } code += " base_uv=ofs;\n"; @@ -1185,38 +1278,21 @@ void BaseMaterial3D::_update_shader() { if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { if (!RenderingServer::get_singleton()->is_low_end()) { code += " {\n"; + if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { code += " float fade_distance = abs((VIEW_MATRIX * MODEL_MATRIX[3]).z);\n"; } else { - code += " float fade_distance=-VERTEX.z;\n"; + code += " float fade_distance = -VERTEX.z;\n"; } + // Use interleaved gradient noise, which is fast but still looks good. + code += " const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);"; + code += " float fade = clamp(smoothstep(distance_fade_min, distance_fade_max, fade_distance), 0.0, 1.0);\n"; + // Use a hard cap to prevent a few stray pixels from remaining when past the fade-out distance. + code += " if (fade < 0.001 || fade < fract(magic.z * fract(dot(FRAGCOORD.xy, magic.xy)))) {\n"; + code += " discard;\n"; + code += " }\n"; - code += " float fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n"; - code += " int x = int(FRAGCOORD.x) % 4;\n"; - code += " int y = int(FRAGCOORD.y) % 4;\n"; - code += " int index = x + y * 4;\n"; - code += " float limit = 0.0;\n\n"; - code += " if (x < 8) {\n"; - code += " if (index == 0) limit = 0.0625;\n"; - code += " if (index == 1) limit = 0.5625;\n"; - code += " if (index == 2) limit = 0.1875;\n"; - code += " if (index == 3) limit = 0.6875;\n"; - code += " if (index == 4) limit = 0.8125;\n"; - code += " if (index == 5) limit = 0.3125;\n"; - code += " if (index == 6) limit = 0.9375;\n"; - code += " if (index == 7) limit = 0.4375;\n"; - code += " if (index == 8) limit = 0.25;\n"; - code += " if (index == 9) limit = 0.75;\n"; - code += " if (index == 10) limit = 0.125;\n"; - code += " if (index == 11) limit = 0.625;\n"; - code += " if (index == 12) limit = 1.0;\n"; - code += " if (index == 13) limit = 0.5;\n"; - code += " if (index == 14) limit = 0.875;\n"; - code += " if (index == 15) limit = 0.375;\n"; - code += " }\n\n"; - code += " if (fade < limit)\n"; - code += " discard;\n"; code += " }\n\n"; } @@ -1702,12 +1778,21 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { } flags[p_flag] = p_enabled; - if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN || p_flag == FLAG_USE_POINT_SIZE) { + + if ( + p_flag == FLAG_USE_SHADOW_TO_OPACITY || + p_flag == FLAG_USE_TEXTURE_REPEAT || + p_flag == FLAG_SUBSURFACE_MODE_SKIN || + p_flag == FLAG_USE_POINT_SIZE || + p_flag == FLAG_UV1_USE_TRIPLANAR || + p_flag == FLAG_UV2_USE_TRIPLANAR) { notify_property_list_changed(); } + if (p_flag == FLAG_PARTICLE_TRAILS_MODE) { update_configuration_warning(); } + _queue_shader_change(); } @@ -1833,6 +1918,14 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NO_EDITOR; } + if ((property.name == "uv1_triplanar_sharpness" || property.name == "uv1_world_triplanar") && !flags[FLAG_UV1_USE_TRIPLANAR]) { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + + if ((property.name == "uv2_triplanar_sharpness" || property.name == "uv2_world_triplanar") && !flags[FLAG_UV2_USE_TRIPLANAR]) { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + // you can only enable anti-aliasing (in materials) on alpha scissor and alpha hash const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH); // alpha anti aliasiasing is only enabled when you can select aa @@ -2546,7 +2639,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Transparency", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); @@ -2593,7 +2686,7 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_on_uv2"), "set_flag", "get_flag", FLAG_EMISSION_ON_UV2); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION); - ADD_GROUP("NormalMap", "normal_"); + ADD_GROUP("Normal Map", "normal_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled"), "set_feature", "get_feature", FEATURE_NORMAL_MAPPING); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_normal_scale", "get_normal_scale"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_NORMAL); @@ -2633,7 +2726,7 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_flip_texture"), "set_flag", "get_flag", FLAG_INVERT_HEIGHTMAP); - ADD_GROUP("Subsurf Scatter", "subsurf_scatter_"); + ADD_GROUP("Subsurface Scattering", "subsurf_scatter_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURFACE_SCATTERING); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_skin_mode"), "set_flag", "get_flag", FLAG_SUBSURFACE_MODE_SKIN); @@ -2857,7 +2950,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_clearcoat(1); set_clearcoat_roughness(0.5); set_anisotropy(0); - set_heightmap_scale(0.05); + set_heightmap_scale(5.0); set_subsurface_scattering_strength(0); set_backlight(Color(0, 0, 0)); set_transmittance_color(Color(1, 1, 1, 1)); @@ -2878,7 +2971,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_transparency(TRANSPARENCY_DISABLED); set_alpha_antialiasing(ALPHA_ANTIALIASING_OFF); - set_alpha_scissor_threshold(0.05); + set_alpha_scissor_threshold(0.5); set_alpha_hash_scale(1.0); set_alpha_antialiasing_edge(0.3); diff --git a/scene/resources/material.h b/scene/resources/material.h index b845fd68c8..ca5b17dd07 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -84,6 +84,17 @@ class ShaderMaterial : public Material { HashMap<StringName, Variant> param_cache; + struct UniformProp { + String str; + PropertyInfo info; + }; + + struct UniformPropComparator { + bool operator()(const UniformProp &p_a, const UniformProp &p_b) const { + return p_a.str.naturalnocasecmp_to(p_b.str) < 0; + } + }; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -104,8 +115,8 @@ public: void set_shader(const Ref<Shader> &p_shader); Ref<Shader> get_shader() const; - void set_shader_param(const StringName &p_param, const Variant &p_value); - Variant get_shader_param(const StringName &p_param) const; + void set_shader_uniform(const StringName &p_param, const Variant &p_value); + Variant get_shader_uniform(const StringName &p_param) const; virtual Shader::Mode get_shader_mode() const override; @@ -809,4 +820,4 @@ public: ////////////////////// -#endif +#endif // MATERIAL_H diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 3e7b0a2808..ec9db89794 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -260,6 +260,64 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { return triangle_mesh; } +Ref<TriangleMesh> Mesh::generate_surface_triangle_mesh(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref<TriangleMesh>()); + + if (surface_triangle_meshes.size() != get_surface_count()) { + surface_triangle_meshes.resize(get_surface_count()); + } + + if (surface_triangle_meshes[p_surface].is_valid()) { + return surface_triangle_meshes[p_surface]; + } + + int facecount = 0; + + if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) { + return Ref<TriangleMesh>(); + } + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + facecount += surface_get_array_index_len(p_surface); + } else { + facecount += surface_get_array_len(p_surface); + } + + Vector<Vector3> faces; + faces.resize(facecount); + Vector3 *facesw = faces.ptrw(); + + Array a = surface_get_arrays(p_surface); + ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>()); + + int vc = surface_get_array_len(p_surface); + Vector<Vector3> vertices = a[ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); + int widx = 0; + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + int ic = surface_get_array_index_len(p_surface); + Vector<int> indices = a[ARRAY_INDEX]; + const int *ir = indices.ptr(); + + for (int j = 0; j < ic; j++) { + int index = ir[j]; + facesw[widx++] = vr[index]; + } + + } else { + for (int j = 0; j < vc; j++) { + facesw[widx++] = vr[j]; + } + } + + Ref<TriangleMesh> triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh->create(faces); + surface_triangle_meshes.set(p_surface, triangle_mesh); + + return triangle_mesh; +} + void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { if (debug_lines.size() > 0) { r_lines = debug_lines; @@ -320,6 +378,14 @@ Vector<Face3> Mesh::get_faces() const { return Vector<Face3>(); } +Vector<Face3> Mesh::get_surface_faces(int p_surface) const { + Ref<TriangleMesh> tm = generate_surface_triangle_mesh(p_surface); + if (tm.is_valid()) { + return tm->get_faces(); + } + return Vector<Face3>(); +} + Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { ConvexDecompositionSettings settings; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b166d12ead..142373ce7f 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -42,6 +42,7 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + mutable Vector<Ref<TriangleMesh>> surface_triangle_meshes; //cached mutable Vector<Vector3> debug_lines; Size2i lightmap_size_hint; @@ -161,7 +162,9 @@ public: virtual AABB get_aabb() const; Vector<Face3> get_faces() const; + Vector<Face3> get_surface_faces(int p_surface) const; Ref<TriangleMesh> generate_triangle_mesh() const; + Ref<TriangleMesh> generate_surface_triangle_mesh(int p_surface) const; void generate_debug_mesh_lines(Vector<Vector3> &r_lines); void generate_debug_mesh_indices(Vector<Vector3> &r_points); @@ -362,4 +365,4 @@ public: ~PlaceholderMesh(); }; -#endif +#endif // MESH_H diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index e5fc61ade5..ff4a7a4560 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -340,13 +340,13 @@ void MultiMesh::_bind_methods() { #ifndef DISABLE_DEPRECATED // Kept for compatibility from 3.x to 4.0. - ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array); + ClassDB::bind_method(D_METHOD("_set_transform_array", "array"), &MultiMesh::_set_transform_array); ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array); - ClassDB::bind_method(D_METHOD("_set_transform_2d_array"), &MultiMesh::_set_transform_2d_array); + ClassDB::bind_method(D_METHOD("_set_transform_2d_array", "array"), &MultiMesh::_set_transform_2d_array); ClassDB::bind_method(D_METHOD("_get_transform_2d_array"), &MultiMesh::_get_transform_2d_array); - ClassDB::bind_method(D_METHOD("_set_color_array"), &MultiMesh::_set_color_array); + ClassDB::bind_method(D_METHOD("_set_color_array", "array"), &MultiMesh::_set_color_array); ClassDB::bind_method(D_METHOD("_get_color_array"), &MultiMesh::_get_color_array); - ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array); + ClassDB::bind_method(D_METHOD("_set_custom_data_array", "array"), &MultiMesh::_set_custom_data_array); ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "_set_transform_array", "_get_transform_array"); diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 30ada5365f..0f8cc76173 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -113,4 +113,4 @@ public: VARIANT_ENUM_CAST(MultiMesh::TransformFormat); -#endif // MULTI_MESH_H +#endif // MULTIMESH_H diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index a808ead66b..ac5493efdc 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -30,6 +30,10 @@ #include "navigation_mesh.h" +#ifdef DEBUG_ENABLED +#include "servers/navigation_server_3d.h" +#endif + void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { ERR_FAIL_COND(p_mesh.is_null()); @@ -337,6 +341,7 @@ void NavigationMesh::clear_polygons() { polygons.clear(); } +#ifndef DISABLE_DEPRECATED Ref<Mesh> NavigationMesh::get_debug_mesh() { if (debug_mesh.is_valid()) { return debug_mesh; @@ -420,6 +425,102 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { return debug_mesh; } +#endif // DISABLE_DEPRECATED + +#ifdef DEBUG_ENABLED +Ref<ArrayMesh> NavigationMesh::_get_debug_mesh() { + if (debug_mesh.is_valid()) { + // Blocks further updates for now, code below is intended for dynamic updates e.g. when settings change. + return debug_mesh; + } + + if (!debug_mesh.is_valid()) { + debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + } else { + debug_mesh->clear_surfaces(); + } + + if (vertices.size() == 0) { + return debug_mesh; + } + + int polygon_count = get_polygon_count(); + + if (polygon_count < 1) { + // no face, no play + return debug_mesh; + } + + // build geometry face surface + Vector<Vector3> face_vertex_array; + face_vertex_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = get_polygon(i); + + face_vertex_array.push_back(vertices[polygon[0]]); + face_vertex_array.push_back(vertices[polygon[1]]); + face_vertex_array.push_back(vertices[polygon[2]]); + } + + Array face_mesh_array; + face_mesh_array.resize(Mesh::ARRAY_MAX); + face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; + + // if enabled add vertex colors to colorize each face individually + bool enabled_geometry_face_random_color = NavigationServer3D::get_singleton()->get_debug_navigation_enable_geometry_face_random_color(); + if (enabled_geometry_face_random_color) { + Color debug_navigation_geometry_face_color = NavigationServer3D::get_singleton()->get_debug_navigation_geometry_face_color(); + Color polygon_color = debug_navigation_geometry_face_color; + + Vector<Color> face_color_array; + face_color_array.resize(polygon_count * 3); + + for (int i = 0; i < polygon_count; i++) { + polygon_color = debug_navigation_geometry_face_color * (Color(Math::randf(), Math::randf(), Math::randf())); + + Vector<int> polygon = get_polygon(i); + + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + face_color_array.push_back(polygon_color); + } + face_mesh_array[Mesh::ARRAY_COLOR] = face_color_array; + } + + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); + Ref<StandardMaterial3D> debug_geometry_face_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_face_material(); + debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_face_material); + + // if enabled build geometry edge line surface + bool enabled_edge_lines = NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_lines(); + + if (enabled_edge_lines) { + Vector<Vector3> line_vertex_array; + line_vertex_array.resize(polygon_count * 6); + + for (int i = 0; i < polygon_count; i++) { + Vector<int> polygon = get_polygon(i); + + line_vertex_array.push_back(vertices[polygon[0]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[1]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[2]]); + line_vertex_array.push_back(vertices[polygon[0]]); + } + + Array line_mesh_array; + line_mesh_array.resize(Mesh::ARRAY_MAX); + line_mesh_array[Mesh::ARRAY_VERTEX] = line_vertex_array; + debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, line_mesh_array); + Ref<StandardMaterial3D> debug_geometry_edge_material = NavigationServer3D::get_singleton_mut()->get_debug_navigation_geometry_edge_material(); + debug_mesh->surface_set_material(debug_mesh->get_surface_count(), debug_geometry_edge_material); + } + + return debug_mesh; +} +#endif void NavigationMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sample_partition_type", "sample_partition_type"), &NavigationMesh::set_sample_partition_type); diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 40b275c792..79d8962d24 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -204,7 +204,11 @@ public: Vector<int> get_polygon(int p_idx); void clear_polygons(); +#ifndef DISABLE_DEPRECATED Ref<Mesh> get_debug_mesh(); +#endif // DISABLE_DEPRECATED + + Ref<ArrayMesh> _get_debug_mesh(); NavigationMesh(); }; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 2c58aa83a9..0e1b18d584 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -434,10 +434,10 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { for (int j = 0; j < binds.size(); j++) { argptrs[j] = &binds[j]; } - callable = callable.bind(argptrs, binds.size()); + callable = callable.bindp(argptrs, binds.size()); } - cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags); + cfrom->connect(snames[c.signal], callable, CONNECT_PERSIST | c.flags); } //Node *s = ret_nodes[0]; @@ -892,9 +892,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, HashMap<String cd.signal = _nm_get_string(c.signal.get_name(), name_map); cd.flags = c.flags; cd.unbinds = unbinds; - for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now. - cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map)); - } + for (int i = 0; i < binds.size(); i++) { cd.binds.push_back(_vm_get_variant(binds[i], variant_map)); } @@ -1781,7 +1779,7 @@ void PackedScene::_bind_methods() { ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack); ClassDB::bind_method(D_METHOD("instantiate", "edit_state"), &PackedScene::instantiate, DEFVAL(GEN_EDIT_STATE_DISABLED)); ClassDB::bind_method(D_METHOD("can_instantiate"), &PackedScene::can_instantiate); - ClassDB::bind_method(D_METHOD("_set_bundled_scene"), &PackedScene::_set_bundled_scene); + ClassDB::bind_method(D_METHOD("_set_bundled_scene", "scene"), &PackedScene::_set_bundled_scene); ClassDB::bind_method(D_METHOD("_get_bundled_scene"), &PackedScene::_get_bundled_scene); ClassDB::bind_method(D_METHOD("get_state"), &PackedScene::get_state); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 5f8001c871..8e1a1d29b6 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -249,4 +249,4 @@ public: VARIANT_ENUM_CAST(PackedScene::GenEditState) -#endif // SCENE_PRELOADER_H +#endif // PACKED_SCENE_H diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 7a49b9b515..4b2e029f47 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -98,6 +98,17 @@ void ParticlesMaterial::init_shaders() { shader_names->emission_ring_radius = "emission_ring_radius"; shader_names->emission_ring_inner_radius = "emission_ring_inner_radius"; + shader_names->turbulence_enabled = "turbulence_enabled"; + shader_names->turbulence_noise_strength = "turbulence_noise_strength"; + shader_names->turbulence_noise_scale = "turbulence_noise_scale"; + shader_names->turbulence_noise_speed = "turbulence_noise_speed"; + shader_names->turbulence_noise_speed_random = "turbulence_noise_speed_random"; + shader_names->turbulence_influence_over_life = "turbulence_influence_over_life"; + shader_names->turbulence_influence_min = "turbulence_influence_min"; + shader_names->turbulence_influence_max = "turbulence_influence_max"; + shader_names->turbulence_initial_displacement_min = "turbulence_initial_displacement_min"; + shader_names->turbulence_initial_displacement_max = "turbulence_initial_displacement_max"; + shader_names->gravity = "gravity"; shader_names->lifetime_randomness = "lifetime_randomness"; @@ -141,7 +152,6 @@ void ParticlesMaterial::_update_shader() { shader_map[mk].users++; return; } - //must create a shader! // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). @@ -282,6 +292,77 @@ void ParticlesMaterial::_update_shader() { code += "uniform float collision_bounce;\n"; } + if (turbulence_enabled) { + code += "uniform float turbulence_noise_strength;\n"; + code += "uniform float turbulence_noise_scale;\n"; + code += "uniform float turbulence_influence_min;\n"; + code += "uniform float turbulence_influence_max;\n"; + code += "uniform float turbulence_initial_displacement_min;\n"; + code += "uniform float turbulence_initial_displacement_max;\n"; + code += "uniform float turbulence_noise_speed_random;\n"; + code += "uniform vec3 turbulence_noise_speed = vec3(1.0, 1.0, 1.0);\n"; + if (tex_parameters[PARAM_TURB_INFLUENCE_OVER_LIFE].is_valid()) { + code += "uniform sampler2D turbulence_influence_over_life;\n"; + } + if (turbulence_color_ramp.is_valid()) { + code += "uniform sampler2D turbulence_color_ramp;\n"; + } + code += "\n"; + + //functions for 3D noise / turbulence + code += "\n\n"; + code += "// 3D Noise with friendly permission by Inigo Quilez\n"; + code += "vec3 hash_noise( vec3 p ) {\n"; + code += " p *= mat3(vec3(127.1, 311.7, -53.7), vec3(269.5, 183.3, 77.1), vec3(-301.7, 27.3, 215.3));\n"; + code += " return 2.0 * fract(fract(p)*4375.55) -1.;\n"; + code += "}\n"; + code += "\n"; + code += "float noise( vec3 p) {\n"; + code += " vec3 i = floor(p);;\n"; + code += " vec3 f = fract(p);\n "; + code += " vec3 u = f * f * (3.0 - 2.0 * f);\n"; + code += "\n"; + code += " return 2.0*mix( mix( mix( dot( hash_noise( i + vec3(0.0,0.0,0.0) ), f - vec3(0.0,0.0,0.0) ), dot( hash_noise( i + vec3(1.0,0.0,0.0) ), f - vec3(1.0,0.0,0.0) ), u.x),\n"; + code += " mix( dot( hash_noise( i + vec3(0.0,1.0,0.0) ), f - vec3(0.0,1.0,0.0) ), dot( hash_noise( i + vec3(1.0,1.0,0.0) ), f - vec3(1.0,1.0,0.0) ), u.x), u.y),\n"; + code += " mix( mix( dot( hash_noise( i + vec3(0.0,0.0,1.0) ), f - vec3(0.0,0.0,1.0) ), dot( hash_noise( i + vec3(1.0,0.0,1.0) ), f - vec3(1.0,0.0,1.0) ), u.x),\n"; + code += " mix( dot( hash_noise( i + vec3(0.0,1.0,1.0) ), f - vec3(0.0,1.0,1.0) ), dot( hash_noise( i + vec3(1.0,1.0,1.0) ), f - vec3(1.0,1.0,1.0) ), u.x), u.y), u.z);\n"; + code += "}\n\n"; + code += "// Curl 3D and noise_3d function with friendly permission by Isaac Cohen\n"; + code += "vec3 noise_3d(vec3 p) {\n"; + code += " float s = noise(p);\n"; + code += " float s1 = noise(vec3(p.y - 19.1, p.z + 33.4, p.x + 47.2));\n"; + code += " float s2 = noise(vec3(p.z + 74.2, p.x - 124.5, p.y + 99.4));\n"; + code += " vec3 c = vec3(s, s1, s2);\n"; + code += " return c;\n"; + code += "}\n\n"; + code += "vec3 curl_3d(vec3 p, float c) {\n"; + code += " float epsilon = 0.001 + c;\n"; + code += " vec3 dx = vec3(epsilon, 0.0, 0.0);\n"; + code += " vec3 dy = vec3(0.0, epsilon, 0.0);\n"; + code += " vec3 dz = vec3(0.0, 0.0, epsilon);\n"; + code += " vec3 x0 = noise_3d(p - dx).xyz;\n"; + code += " vec3 x1 = noise_3d(p + dx).xyz;\n"; + code += " vec3 y0 = noise_3d(p - dy).xyz;\n"; + code += " vec3 y1 = noise_3d(p + dy).xyz;\n"; + code += " vec3 z0 = noise_3d(p - dz).xyz;\n"; + code += " vec3 z1 = noise_3d(p + dz).xyz;\n"; + code += " float x = y1.z - y0.z - z1.y + z0.y;\n"; + code += " float y = z1.x - z0.x - x1.z + x0.z;\n"; + code += " float z = x1.y - x0.y - y1.x + y0.x;\n"; + code += " float divisor = 1.0 / (2.0 * epsilon);\n"; + code += " return vec3(normalize(vec3(x, y, z) * divisor));\n"; + code += "}\n"; + code += "vec3 get_noise_direction(vec3 pos, vec3 emission_pos, vec3 time_noise) {\n"; + code += " float adj_contrast = max((turbulence_noise_strength - 1.0), 0.0) * 70.0;\n"; + code += " vec3 noise_time = (vec3(TIME) * turbulence_noise_speed) + time_noise;\n"; + code += " vec3 noise_pos = (pos * turbulence_noise_scale) - emission_pos;\n"; + code += " vec3 diff = pos - emission_pos;\n"; + code += " vec3 noise_direction = curl_3d(noise_pos + noise_time - diff, adj_contrast);\n"; + code += " noise_direction = mix(0.9 * noise_direction, noise_direction, turbulence_noise_strength - 9.0);\n"; + code += " return noise_direction;\n"; + code += "}\n"; + } + //need a random function code += "\n\n"; code += "float rand_from_seed(inout uint seed) {\n"; @@ -463,8 +544,18 @@ void ParticlesMaterial::_update_shader() { break; } } - code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; + // Apply noise/turbulence: initial displacement. + if (turbulence_enabled) { + if (get_turbulence_noise_speed_random() >= 0.0) { + code += " vec3 time_noise = noise_3d( vec3(TIME) * turbulence_noise_speed_random ) * -turbulence_noise_speed;\n"; + } else { + code += " const vec3 time_noise = vec3(0.0);\n"; + } + code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz, EMISSION_TRANSFORM[3].xyz, time_noise);\n"; + code += " float turb_init_displacement = mix(turbulence_initial_displacement_min, turbulence_initial_displacement_max, rand_from_seed(alt_seed));"; + code += " TRANSFORM[3].xyz += noise_direction * turb_init_displacement;\n"; + } code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; @@ -483,7 +574,6 @@ void ParticlesMaterial::_update_shader() { if (color_initial_ramp.is_valid()) { code += " float color_initial_rand = rand_from_seed(alt_seed);\n"; } - code += " float pi = 3.14159;\n"; code += " float degree_to_rad = pi / 180.0;\n"; code += "\n"; @@ -570,7 +660,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 diff = pos - org;\n"; code += " force += length(diff) > 0.0 ? normalize(diff) * tex_radial_accel * mix(radial_accel_min, radial_accel_max, rand_from_seed(alt_seed)) : vec3(0.0);\n"; code += " // apply tangential acceleration;\n"; - code += " float tangent_accel_val = tex_tangent_accel * mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed))\n;"; + code += " float tangent_accel_val = tex_tangent_accel * mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed));\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * tangent_accel_val : vec3(0.0);\n"; @@ -584,6 +674,41 @@ void ParticlesMaterial::_update_shader() { code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { + code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n"; + } + + // Apply noise/turbulence. + if (turbulence_enabled) { + code += " // apply turbulence\n"; + if (tex_parameters[PARAM_TURB_INFLUENCE_OVER_LIFE].is_valid()) { + code += " float turbulence_influence = textureLod(turbulence_influence_over_life, vec2(tv, 0.0), 0.0).r;\n"; + } else { + code += " const float turbulence_influence = 1.0;\n"; + } + code += " \n"; + if (get_turbulence_noise_speed_random() >= 0.0) { + code += " vec3 time_noise = noise_3d( vec3(TIME) * turbulence_noise_speed_random ) * -turbulence_noise_speed;\n"; + } else { + code += " const vec3 time_noise = vec3(0.0);\n"; + } + code += " vec3 noise_direction = get_noise_direction(TRANSFORM[3].xyz, EMISSION_TRANSFORM[3].xyz, time_noise);\n"; + // If collision happened, turbulence is no longer applied. + String extra_tab = ""; + if (collision_enabled) { + code += " if (!COLLIDED) {\n"; + extra_tab = " "; + } + code += extra_tab + " \n"; + code += extra_tab + " float vel_mag = length(VELOCITY);\n"; + code += extra_tab + " float vel_infl = clamp(mix(turbulence_influence_min, turbulence_influence_max, rand_from_seed(alt_seed)) * turbulence_influence, 0.0, 1.0);\n"; + code += extra_tab + " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + if (collision_enabled) { + code += " }"; + } + } + code += " \n"; code += " // orbit velocity\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float orbit_amount = tex_orbit_velocity * mix(orbit_velocity_min, orbit_velocity_max, rand_from_seed(alt_seed));\n"; @@ -595,9 +720,6 @@ void ParticlesMaterial::_update_shader() { code += " }\n"; } - if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n"; - } code += " float dmp = mix(damping_min, damping_max, rand_from_seed(alt_seed));\n"; code += " if (dmp * tex_damping > 0.0) {\n"; code += " float v = length(VELOCITY);\n"; @@ -701,24 +823,34 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3] = origin;\n"; } } - //scale by scale - code += " float base_scale = mix(scale_min, scale_max, scale_rand);\n"; - code += " base_scale = sign(base_scale) * max(abs(base_scale), 0.001);\n"; - code += " TRANSFORM[0].xyz *= base_scale * sign(tex_scale.r) * max(abs(tex_scale.r), 0.001);\n"; - code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n"; - code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n"; if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } + if (collision_enabled) { code += " if (COLLIDED) {\n"; - code += " TRANSFORM[3].xyz+=COLLISION_NORMAL * COLLISION_DEPTH;\n"; - code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; - code += " VELOCITY = mix(VELOCITY,vec3(0.0),collision_friction * DELTA * 100.0);\n"; + code += " if (length(VELOCITY) > 3.0) {\n"; + code += " TRANSFORM[3].xyz += COLLISION_NORMAL * COLLISION_DEPTH;\n"; + code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; + code += " VELOCITY = mix(VELOCITY,vec3(0.0),clamp(collision_friction, 0.0, 1.0));\n"; + code += " } else {\n"; + code += " VELOCITY = vec3(0.0);\n"; + // If turbulence is enabled, set the noise direction to up so the turbulence color is "neutral" + if (turbulence_enabled) { + code += " noise_direction = vec3(1.0, 0.0, 0.0);\n"; + } + code += " }\n"; code += " }\n"; } + + // scale by scale + code += " float base_scale = mix(scale_min, scale_max, scale_rand);\n"; + code += " base_scale = sign(base_scale) * max(abs(base_scale), 0.001);\n"; + code += " TRANSFORM[0].xyz *= base_scale * sign(tex_scale.r) * max(abs(tex_scale.r), 0.001);\n"; + code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n"; + code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n"; + if (sub_emitter_mode != SUB_EMITTER_DISABLED) { code += " int emit_count = 0;\n"; switch (sub_emitter_mode) { @@ -856,6 +988,15 @@ void ParticlesMaterial::set_param_min(Parameter p_param, float p_value) { case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_min, p_value); } break; + case PARAM_TURB_VEL_INFLUENCE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_min, p_value); + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_initial_displacement_min, p_value); + } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -912,6 +1053,15 @@ void ParticlesMaterial::set_param_max(Parameter p_param, float p_value) { case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_max, p_value); } break; + case PARAM_TURB_VEL_INFLUENCE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_max, p_value); + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_initial_displacement_max, p_value); + } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -986,6 +1136,16 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D case PARAM_ANIM_OFFSET: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, tex_rid); } break; + case PARAM_TURB_INFLUENCE_OVER_LIFE: { + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_influence_over_life, tex_rid); + _adjust_curve_range(p_texture, 0, 1); + } break; + case PARAM_TURB_VEL_INFLUENCE: { + // Can't happen, but silences warning + } break; + case PARAM_TURB_INIT_DISPLACEMENT: { + // Can't happen, but silences warning + } break; case PARAM_MAX: break; // Can't happen, but silences warning } @@ -1151,6 +1311,54 @@ real_t ParticlesMaterial::get_emission_ring_inner_radius() const { return emission_ring_inner_radius; } +void ParticlesMaterial::set_turbulence_enabled(const bool p_turbulence_enabled) { + turbulence_enabled = p_turbulence_enabled; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_enabled, turbulence_enabled); + _queue_shader_change(); + notify_property_list_changed(); +} + +bool ParticlesMaterial::get_turbulence_enabled() const { + return turbulence_enabled; +} + +void ParticlesMaterial::set_turbulence_noise_strength(float p_turbulence_noise_strength) { + turbulence_noise_strength = p_turbulence_noise_strength; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_strength, p_turbulence_noise_strength); +} + +float ParticlesMaterial::get_turbulence_noise_strength() const { + return turbulence_noise_strength; +} + +void ParticlesMaterial::set_turbulence_noise_scale(float p_turbulence_noise_scale) { + turbulence_noise_scale = p_turbulence_noise_scale; + float shader_turbulence_noise_scale = (pow(p_turbulence_noise_scale, 0.25) * 5.6234 / 10.0) * 4.0 - 3.0; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_scale, shader_turbulence_noise_scale); +} + +float ParticlesMaterial::get_turbulence_noise_scale() const { + return turbulence_noise_scale; +} + +void ParticlesMaterial::set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random) { + turbulence_noise_speed_random = p_turbulence_noise_speed_random; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed_random, p_turbulence_noise_speed_random); +} + +float ParticlesMaterial::get_turbulence_noise_speed_random() const { + return turbulence_noise_speed_random; +} + +void ParticlesMaterial::set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed) { + turbulence_noise_speed = p_turbulence_noise_speed; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed, turbulence_noise_speed); +} + +Vector3 ParticlesMaterial::get_turbulence_noise_speed() const { + return turbulence_noise_speed; +} + void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { gravity = p_gravity; Vector3 gset = gravity; @@ -1214,6 +1422,20 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = PROPERTY_USAGE_NONE; } + + if (!turbulence_enabled) { + if (property.name == "turbulence_noise_strength" || + property.name == "turbulence_noise_scale" || + property.name == "turbulence_noise_speed" || + property.name == "turbulence_noise_speed_random" || + property.name == "turbulence_influence_over_life" || + property.name == "turbulence_influence_min" || + property.name == "turbulence_influence_max" || + property.name == "turbulence_initial_displacement_min" || + property.name == "turbulence_initial_displacement_max") { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + } } void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { @@ -1365,6 +1587,21 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &ParticlesMaterial::set_emission_ring_inner_radius); ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &ParticlesMaterial::get_emission_ring_inner_radius); + ClassDB::bind_method(D_METHOD("get_turbulence_enabled"), &ParticlesMaterial::get_turbulence_enabled); + ClassDB::bind_method(D_METHOD("set_turbulence_enabled", "turbulence_enabled"), &ParticlesMaterial::set_turbulence_enabled); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_strength"), &ParticlesMaterial::get_turbulence_noise_strength); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_strength", "turbulence_noise_strength"), &ParticlesMaterial::set_turbulence_noise_strength); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_scale"), &ParticlesMaterial::get_turbulence_noise_scale); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_scale", "turbulence_noise_scale"), &ParticlesMaterial::set_turbulence_noise_scale); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed_random"), &ParticlesMaterial::get_turbulence_noise_speed_random); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed_random", "turbulence_noise_speed_random"), &ParticlesMaterial::set_turbulence_noise_speed_random); + + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed"), &ParticlesMaterial::get_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed", "turbulence_noise_speed"), &ParticlesMaterial::set_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); @@ -1413,7 +1650,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_height"), "set_emission_ring_height", "get_emission_ring_height"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_radius"), "set_emission_ring_radius", "get_emission_ring_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_ring_inner_radius"), "set_emission_ring_inner_radius", "get_emission_ring_inner_radius"); - ADD_GROUP("ParticleFlags", "particle_flag_"); + ADD_GROUP("Particle Flags", "particle_flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); @@ -1467,6 +1704,19 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION); + + ADD_GROUP("Turbulence", "turbulence_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_enabled"), "set_turbulence_enabled", "get_turbulence_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_strength", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_turbulence_noise_strength", "get_turbulence_noise_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "turbulence_noise_speed"), "set_turbulence_noise_speed", "get_turbulence_noise_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_speed_random", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_speed_random", "get_turbulence_noise_speed_random"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_min", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_min", "get_param_min", PARAM_TURB_INIT_DISPLACEMENT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_max", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_max", "get_param_max", PARAM_TURB_INIT_DISPLACEMENT); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); + ADD_GROUP("Animation", "anim_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED); @@ -1517,6 +1767,10 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_RING); BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); + BIND_ENUM_CONSTANT(PARAM_TURB_VEL_INFLUENCE); + BIND_ENUM_CONSTANT(PARAM_TURB_INIT_DISPLACEMENT); + BIND_ENUM_CONSTANT(PARAM_TURB_INFLUENCE_OVER_LIFE); + BIND_ENUM_CONSTANT(SUB_EMITTER_DISABLED); BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT); BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END); @@ -1560,6 +1814,17 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_ring_height(1); set_emission_ring_radius(1); set_emission_ring_inner_radius(0); + + set_turbulence_enabled(false); + set_turbulence_noise_speed(Vector3(0.5, 0.5, 0.5)); + set_turbulence_noise_strength(1); + set_turbulence_noise_scale(9); + set_turbulence_noise_speed_random(0); + set_param_min(PARAM_TURB_VEL_INFLUENCE, 0.1); + set_param_max(PARAM_TURB_VEL_INFLUENCE, 0.1); + set_param_min(PARAM_TURB_INIT_DISPLACEMENT, 0.0); + set_param_max(PARAM_TURB_INIT_DISPLACEMENT, 0.0); + set_gravity(Vector3(0, -9.8, 0)); set_lifetime_randomness(0); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index af45593f38..7fb46d6ac5 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -58,6 +58,9 @@ public: PARAM_HUE_VARIATION, PARAM_ANIM_SPEED, PARAM_ANIM_OFFSET, + PARAM_TURB_INFLUENCE_OVER_LIFE, + PARAM_TURB_VEL_INFLUENCE, + PARAM_TURB_INIT_DISPLACEMENT, PARAM_MAX }; @@ -105,9 +108,10 @@ private: uint32_t attractor_enabled : 1; uint32_t collision_enabled : 1; uint32_t collision_scale : 1; + uint32_t turbulence_enabled : 1; }; - uint32_t key = 0; + uint64_t key = 0; static uint32_t hash(const MaterialKey &p_key) { return hash_murmur3_one_32(p_key.key); @@ -152,6 +156,7 @@ private: mk.collision_enabled = collision_enabled; mk.attractor_enabled = attractor_interaction_enabled; mk.collision_scale = collision_scale; + mk.turbulence_enabled = turbulence_enabled; return mk; } @@ -216,6 +221,17 @@ private: StringName emission_ring_radius; StringName emission_ring_inner_radius; + StringName turbulence_enabled; + StringName turbulence_noise_strength; + StringName turbulence_noise_scale; + StringName turbulence_noise_speed; + StringName turbulence_noise_speed_random; + StringName turbulence_influence_over_life; + StringName turbulence_influence_min; + StringName turbulence_influence_max; + StringName turbulence_initial_displacement_min; + StringName turbulence_initial_displacement_max; + StringName gravity; StringName lifetime_randomness; @@ -243,6 +259,7 @@ private: float params_min[PARAM_MAX]; float params_max[PARAM_MAX]; + float params[PARAM_MAX]; Ref<Texture2D> tex_parameters[PARAM_MAX]; Color color; @@ -265,6 +282,13 @@ private: bool anim_loop = false; + bool turbulence_enabled; + Vector3 turbulence_noise_speed; + Ref<Texture2D> turbulence_color_ramp; + float turbulence_noise_strength = 0.0f; + float turbulence_noise_scale = 0.0f; + float turbulence_noise_speed_random = 0.0f; + Vector3 gravity; double lifetime_randomness = 0.0; @@ -340,6 +364,18 @@ public: real_t get_emission_ring_inner_radius() const; int get_emission_point_count() const; + void set_turbulence_enabled(bool p_turbulence_enabled); + void set_turbulence_noise_strength(float p_turbulence_noise_strength); + void set_turbulence_noise_scale(float p_turbulence_noise_scale); + void set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random); + void set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed); + + bool get_turbulence_enabled() const; + float get_turbulence_noise_strength() const; + float get_turbulence_noise_scale() const; + float get_turbulence_noise_speed_random() const; + Vector3 get_turbulence_noise_speed() const; + void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index 29135e30c9..5e18671c11 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -553,7 +553,7 @@ void PolygonPathFinder::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_penalty", "idx"), &PolygonPathFinder::get_point_penalty); ClassDB::bind_method(D_METHOD("get_bounds"), &PolygonPathFinder::get_bounds); - ClassDB::bind_method(D_METHOD("_set_data"), &PolygonPathFinder::_set_data); + ClassDB::bind_method(D_METHOD("_set_data", "data"), &PolygonPathFinder::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &PolygonPathFinder::_get_data); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 68441afb1c..f038a79b8f 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1622,6 +1622,134 @@ bool SphereMesh::get_is_hemisphere() const { SphereMesh::SphereMesh() {} /** + TorusMesh +*/ + +void TorusMesh::_create_mesh_array(Array &p_arr) const { + // set our bounding box + + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + ERR_FAIL_COND_MSG(inner_radius == outer_radius, "Inner radius and outer radius cannot be the same."); + + float min_radius = inner_radius; + float max_radius = outer_radius; + + if (min_radius > max_radius) { + SWAP(min_radius, max_radius); + } + + float radius = (max_radius - min_radius) * 0.5; + + for (int i = 0; i <= rings; i++) { + int prevrow = (i - 1) * (ring_segments + 1); + int thisrow = i * (ring_segments + 1); + float inci = float(i) / rings; + float angi = inci * Math_TAU; + + Vector2 normali = Vector2(-Math::sin(angi), -Math::cos(angi)); + + for (int j = 0; j <= ring_segments; j++) { + float incj = float(j) / ring_segments; + float angj = incj * Math_TAU; + + Vector2 normalj = Vector2(-Math::cos(angj), Math::sin(angj)); + Vector2 normalk = normalj * radius + Vector2(min_radius + radius, 0); + + points.push_back(Vector3(normali.x * normalk.x, normalk.y, normali.y * normalk.x)); + normals.push_back(Vector3(normali.x * normalj.x, normalj.y, normali.y * normalj.x)); + ADD_TANGENT(-Math::cos(angi), 0.0, Math::sin(angi), 1.0); + uvs.push_back(Vector2(inci, incj)); + + if (i > 0 && j > 0) { + indices.push_back(thisrow + j - 1); + indices.push_back(prevrow + j); + indices.push_back(prevrow + j - 1); + + indices.push_back(thisrow + j - 1); + indices.push_back(thisrow + j); + indices.push_back(prevrow + j); + } + } + } + + p_arr[RS::ARRAY_VERTEX] = points; + p_arr[RS::ARRAY_NORMAL] = normals; + p_arr[RS::ARRAY_TANGENT] = tangents; + p_arr[RS::ARRAY_TEX_UV] = uvs; + p_arr[RS::ARRAY_INDEX] = indices; +} + +void TorusMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_inner_radius", "radius"), &TorusMesh::set_inner_radius); + ClassDB::bind_method(D_METHOD("get_inner_radius"), &TorusMesh::get_inner_radius); + + ClassDB::bind_method(D_METHOD("set_outer_radius", "radius"), &TorusMesh::set_outer_radius); + ClassDB::bind_method(D_METHOD("get_outer_radius"), &TorusMesh::get_outer_radius); + + ClassDB::bind_method(D_METHOD("set_rings", "rings"), &TorusMesh::set_rings); + ClassDB::bind_method(D_METHOD("get_rings"), &TorusMesh::get_rings); + + ClassDB::bind_method(D_METHOD("set_ring_segments", "rings"), &TorusMesh::set_ring_segments); + ClassDB::bind_method(D_METHOD("get_ring_segments"), &TorusMesh::get_ring_segments); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_inner_radius", "get_inner_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_outer_radius", "get_outer_radius"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "3,128,1"), "set_rings", "get_rings"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_segments", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_segments", "get_ring_segments"); +} + +void TorusMesh::set_inner_radius(const float p_inner_radius) { + inner_radius = p_inner_radius; + _request_update(); +} + +float TorusMesh::get_inner_radius() const { + return inner_radius; +} + +void TorusMesh::set_outer_radius(const float p_outer_radius) { + outer_radius = p_outer_radius; + _request_update(); +} + +float TorusMesh::get_outer_radius() const { + return outer_radius; +} + +void TorusMesh::set_rings(const int p_rings) { + ERR_FAIL_COND(p_rings < 3); + rings = p_rings; + _request_update(); +} + +int TorusMesh::get_rings() const { + return rings; +} + +void TorusMesh::set_ring_segments(const int p_ring_segments) { + ERR_FAIL_COND(p_ring_segments < 3); + ring_segments = p_ring_segments; + _request_update(); +} + +int TorusMesh::get_ring_segments() const { + return ring_segments; +} + +TorusMesh::TorusMesh() {} + +/** PointMesh */ diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index cb93211756..64eefd2c07 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -351,6 +351,38 @@ public: }; /** + Big donut +*/ +class TorusMesh : public PrimitiveMesh { + GDCLASS(TorusMesh, PrimitiveMesh); + +private: + float inner_radius = 0.5; + float outer_radius = 1.0; + int rings = 64; + int ring_segments = 32; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr) const override; + +public: + void set_inner_radius(const float p_inner_radius); + float get_inner_radius() const; + + void set_outer_radius(const float p_outer_radius); + float get_outer_radius() const; + + void set_rings(const int p_rings); + int get_rings() const; + + void set_ring_segments(const int p_ring_segments); + int get_ring_segments() const; + + TorusMesh(); +}; + +/** A single point for use in particle systems */ @@ -595,4 +627,5 @@ public: }; VARIANT_ENUM_CAST(RibbonTrailMesh::Shape) -#endif + +#endif // PRIMITIVE_MESHES_H diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 66afb001fb..2b1d91e4ef 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -65,14 +65,18 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia return ERR_PARSE_ERROR; } - String unique_id = token.value; + if (p_data->no_placeholders) { + r_res.unref(); + } else { + String unique_id = token.value; - if (!p_data->resource_map.has(unique_id)) { - r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file"; - return ERR_PARSE_ERROR; - } + if (!p_data->resource_map.has(unique_id)) { + r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file"; + return ERR_PARSE_ERROR; + } - r_res = p_data->resource_map[unique_id]; + r_res = p_data->resource_map[unique_id]; + } VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -91,11 +95,15 @@ Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, Varia return ERR_PARSE_ERROR; } - String id = token.value; + if (p_data->no_placeholders) { + r_res.unref(); + } else { + String id = token.value; - ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); + ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); - r_res = p_data->rev_external_resources[id]; + r_res = p_data->rev_external_resources[id]; + } VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -1066,7 +1074,7 @@ static void bs_save_unicode_string(Ref<FileAccess> p_f, const String &p_string, p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); } -Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_path) { +Error ResourceLoaderText::save_as_binary(const String &p_path) { if (error) { return error; } @@ -1271,7 +1279,7 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa } if (next_tag.name == "node") { - //this is a node, must save one more! + // This is a node, must save one more! if (!is_scene) { error_text += "found the 'node' tag on a resource file!"; @@ -1346,6 +1354,126 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa return OK; } +Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) { + if (error) { + return error; + } + + ignore_resource_parsing = true; + + DummyReadData dummy_read; + dummy_read.no_placeholders = true; + VariantParser::ResourceParser rp; + rp.ext_func = _parse_ext_resource_dummys; + rp.sub_func = _parse_sub_resource_dummys; + rp.userdata = &dummy_read; + + while (next_tag.name == "ext_resource") { + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); + + if (error) { + _printerr(); + return error; + } + } + + while (next_tag.name == "sub_resource" || next_tag.name == "resource") { + if (next_tag.name == "sub_resource") { + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + r_classes->insert(next_tag.fields["type"]); + + } else { + r_classes->insert(next_tag.fields["res_type"]); + } + + while (true) { + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (error == ERR_FILE_EOF) { + return OK; + } + + _printerr(); + return error; + } + + if (!assign.is_empty()) { + continue; + } else if (!next_tag.name.is_empty()) { + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + } + + while (next_tag.name == "node") { + // This is a node, must save one more! + + if (!is_scene) { + error_text += "found the 'node' tag on a resource file!"; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + r_classes->insert(next_tag.fields["type"]); + + while (true) { + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (error == ERR_FILE_MISSING_DEPENDENCIES) { + // Resource loading error, just skip it. + } else if (error != ERR_FILE_EOF) { + _printerr(); + return error; + } else { + return OK; + } + } + + if (!assign.is_empty()) { + continue; + } else if (!next_tag.name.is_empty()) { + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + } + + return OK; +} + String ResourceLoaderText::recognize(Ref<FileAccess> p_f) { error = OK; @@ -1473,6 +1601,26 @@ bool ResourceFormatLoaderText::handles_type(const String &p_type) const { return true; } +void ResourceFormatLoaderText::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + String ext = p_path.get_extension().to_lower(); + if (ext == "tscn") { + r_classes->insert("PackedScene"); + } + + // ...for anything else must test... + + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + if (f.is_null()) { + return; // Could not read. + } + + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + loader.open(f); + loader.get_classes_used(r_classes); +} + String ResourceFormatLoaderText::get_resource_type(const String &p_path) const { String ext = p_path.get_extension().to_lower(); if (ext == "tscn") { @@ -1561,7 +1709,7 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.res_path = loader.local_path; loader.open(f); - return loader.save_as_binary(f, p_dst_path); + return loader.save_as_binary(p_dst_path); } /*****************************************************************************************************/ @@ -2063,7 +2211,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const Ref<Reso return OK; } -Error ResourceFormatSaverText::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverText::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { if (p_path.ends_with(".tscn") && !Ref<PackedScene>(p_resource).is_valid()) { return ERR_FILE_UNRECOGNIZED; } diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 5c6a937bf2..9154bcf795 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -90,6 +90,7 @@ class ResourceLoaderText { }; struct DummyReadData { + bool no_placeholders = false; HashMap<Ref<Resource>, int> external_resources; HashMap<String, Ref<Resource>> rev_external_resources; HashMap<Ref<Resource>, int> resource_index_map; @@ -125,8 +126,9 @@ public: ResourceUID::ID get_uid(Ref<FileAccess> p_f); void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types); Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map); + Error get_classes_used(HashSet<StringName> *r_classes); - Error save_as_binary(Ref<FileAccess> p_f, const String &p_path); + Error save_as_binary(const String &p_path); ResourceLoaderText(); }; @@ -137,6 +139,8 @@ public: virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); + virtual String get_resource_type(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -190,7 +194,7 @@ public: class ResourceFormatSaverText : public ResourceFormatSaver { public: static ResourceFormatSaverText *singleton; - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual bool recognize(const Ref<Resource> &p_resource) const; virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; diff --git a/scene/resources/scene_replication_config.cpp b/scene/resources/scene_replication_config.cpp deleted file mode 100644 index 6789f9f7d5..0000000000 --- a/scene/resources/scene_replication_config.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/*************************************************************************/ -/* scene_replication_config.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (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 "scene_replication_config.h" - -#include "core/multiplayer/multiplayer_api.h" -#include "scene/main/node.h" - -bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_value) { - String name = p_name; - - if (name.begins_with("properties/")) { - int idx = name.get_slicec('/', 1).to_int(); - String what = name.get_slicec('/', 2); - - if (properties.size() == idx && what == "path") { - ERR_FAIL_COND_V(p_value.get_type() != Variant::NODE_PATH, false); - NodePath path = p_value; - ERR_FAIL_COND_V(path.is_empty() || path.get_subname_count() == 0, false); - add_property(path); - return true; - } - ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false); - ERR_FAIL_INDEX_V(idx, properties.size(), false); - ReplicationProperty &prop = properties[idx]; - if (what == "sync") { - prop.sync = p_value; - if (prop.sync) { - sync_props.push_back(prop.name); - } else { - sync_props.erase(prop.name); - } - return true; - } else if (what == "spawn") { - prop.spawn = p_value; - if (prop.spawn) { - spawn_props.push_back(prop.name); - } else { - spawn_props.erase(prop.name); - } - return true; - } - } - return false; -} - -bool SceneReplicationConfig::_get(const StringName &p_name, Variant &r_ret) const { - String name = p_name; - - if (name.begins_with("properties/")) { - int idx = name.get_slicec('/', 1).to_int(); - String what = name.get_slicec('/', 2); - ERR_FAIL_INDEX_V(idx, properties.size(), false); - const ReplicationProperty &prop = properties[idx]; - if (what == "path") { - r_ret = prop.name; - return true; - } else if (what == "sync") { - r_ret = prop.sync; - return true; - } else if (what == "spawn") { - r_ret = prop.spawn; - return true; - } - } - return false; -} - -void SceneReplicationConfig::_get_property_list(List<PropertyInfo> *p_list) const { - for (int i = 0; i < properties.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); - p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/spawn", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); - p_list->push_back(PropertyInfo(Variant::STRING, "properties/" + itos(i) + "/sync", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); - } -} - -TypedArray<NodePath> SceneReplicationConfig::get_properties() const { - TypedArray<NodePath> paths; - for (const ReplicationProperty &prop : properties) { - paths.push_back(prop.name); - } - return paths; -} - -void SceneReplicationConfig::add_property(const NodePath &p_path, int p_index) { - ERR_FAIL_COND(properties.find(p_path)); - - if (p_index < 0 || p_index == properties.size()) { - properties.push_back(ReplicationProperty(p_path)); - return; - } - - ERR_FAIL_INDEX(p_index, properties.size()); - - List<ReplicationProperty>::Element *I = properties.front(); - int c = 0; - while (c < p_index) { - I = I->next(); - c++; - } - properties.insert_before(I, ReplicationProperty(p_path)); -} - -void SceneReplicationConfig::remove_property(const NodePath &p_path) { - properties.erase(p_path); -} - -bool SceneReplicationConfig::has_property(const NodePath &p_path) const { - for (int i = 0; i < properties.size(); i++) { - if (properties[i].name == p_path) { - return true; - } - } - return false; -} - -int SceneReplicationConfig::property_get_index(const NodePath &p_path) const { - for (int i = 0; i < properties.size(); i++) { - if (properties[i].name == p_path) { - return i; - } - } - ERR_FAIL_V(-1); -} - -bool SceneReplicationConfig::property_get_spawn(const NodePath &p_path) { - List<ReplicationProperty>::Element *E = properties.find(p_path); - ERR_FAIL_COND_V(!E, false); - return E->get().spawn; -} - -void SceneReplicationConfig::property_set_spawn(const NodePath &p_path, bool p_enabled) { - List<ReplicationProperty>::Element *E = properties.find(p_path); - ERR_FAIL_COND(!E); - if (E->get().spawn == p_enabled) { - return; - } - E->get().spawn = p_enabled; - spawn_props.clear(); - for (const ReplicationProperty &prop : properties) { - if (prop.spawn) { - spawn_props.push_back(p_path); - } - } -} - -bool SceneReplicationConfig::property_get_sync(const NodePath &p_path) { - List<ReplicationProperty>::Element *E = properties.find(p_path); - ERR_FAIL_COND_V(!E, false); - return E->get().sync; -} - -void SceneReplicationConfig::property_set_sync(const NodePath &p_path, bool p_enabled) { - List<ReplicationProperty>::Element *E = properties.find(p_path); - ERR_FAIL_COND(!E); - if (E->get().sync == p_enabled) { - return; - } - E->get().sync = p_enabled; - sync_props.clear(); - for (const ReplicationProperty &prop : properties) { - if (prop.sync) { - sync_props.push_back(p_path); - } - } -} - -void SceneReplicationConfig::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_properties"), &SceneReplicationConfig::get_properties); - ClassDB::bind_method(D_METHOD("add_property", "path", "index"), &SceneReplicationConfig::add_property, DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("has_property", "path"), &SceneReplicationConfig::has_property); - ClassDB::bind_method(D_METHOD("remove_property", "path"), &SceneReplicationConfig::remove_property); - ClassDB::bind_method(D_METHOD("property_get_index", "path"), &SceneReplicationConfig::property_get_index); - ClassDB::bind_method(D_METHOD("property_get_spawn", "path"), &SceneReplicationConfig::property_get_spawn); - ClassDB::bind_method(D_METHOD("property_set_spawn", "path", "enabled"), &SceneReplicationConfig::property_set_spawn); - ClassDB::bind_method(D_METHOD("property_get_sync", "path"), &SceneReplicationConfig::property_get_sync); - ClassDB::bind_method(D_METHOD("property_set_sync", "path", "enabled"), &SceneReplicationConfig::property_set_sync); -} diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp index 0d6aee47d8..fea41061fd 100644 --- a/scene/resources/separation_ray_shape_2d.cpp +++ b/scene/resources/separation_ray_shape_2d.cpp @@ -57,7 +57,7 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { xf.xform(Vector2(arrow_size, 0)), diff --git a/scene/resources/separation_ray_shape_3d.h b/scene/resources/separation_ray_shape_3d.h index 0e750a48e6..ae08ff7887 100644 --- a/scene/resources/separation_ray_shape_3d.h +++ b/scene/resources/separation_ray_shape_3d.h @@ -28,8 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SEPARATION_RAY_SHAPE_H -#define SEPARATION_RAY_SHAPE_H +#ifndef SEPARATION_RAY_SHAPE_3D_H +#define SEPARATION_RAY_SHAPE_3D_H + #include "scene/resources/shape_3d.h" class SeparationRayShape3D : public Shape3D { @@ -53,4 +54,5 @@ public: SeparationRayShape3D(); }; -#endif // SEPARATION_RAY_SHAPE_H + +#endif // SEPARATION_RAY_SHAPE_3D_H diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index d49157b1b8..db7b03f2be 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -33,6 +33,7 @@ #include "core/io/file_access.h" #include "scene/scene_string_names.h" #include "servers/rendering/shader_language.h" +#include "servers/rendering/shader_preprocessor.h" #include "servers/rendering_server.h" #include "texture.h" @@ -40,7 +41,23 @@ Shader::Mode Shader::get_mode() const { return mode; } +void Shader::_dependency_changed() { + RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader)); + params_cache_dirty = true; + + emit_changed(); +} + +void Shader::set_path(const String &p_path, bool p_take_over) { + Resource::set_path(p_path, p_take_over); + RS::get_singleton()->shader_set_path_hint(shader, p_path); +} + void Shader::set_code(const String &p_code) { + for (Ref<ShaderInclude> E : include_dependencies) { + E->disconnect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed)); + } + String type = ShaderLanguage::get_shader_type(p_code); if (type == "canvas_item") { @@ -55,7 +72,27 @@ void Shader::set_code(const String &p_code) { mode = MODE_SPATIAL; } - RenderingServer::get_singleton()->shader_set_code(shader, p_code); + code = p_code; + String pp_code = p_code; + + HashSet<Ref<ShaderInclude>> new_include_dependencies; + + { + // Preprocessor must run here and not in the server because: + // 1) Need to keep track of include dependencies at resource level + // 2) Server does not do interaction with Resource filetypes, this is a scene level feature. + ShaderPreprocessor preprocessor; + preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_include_dependencies); + } + + // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) + include_dependencies = new_include_dependencies; + + for (Ref<ShaderInclude> E : include_dependencies) { + E->connect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed)); + } + + RenderingServer::get_singleton()->shader_set_code(shader, pp_code); params_cache_dirty = true; emit_changed(); @@ -63,24 +100,28 @@ void Shader::set_code(const String &p_code) { String Shader::get_code() const { _update_shader(); - return RenderingServer::get_singleton()->shader_get_code(shader); + return code; } -void Shader::get_param_list(List<PropertyInfo> *p_params) const { +void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); List<PropertyInfo> local; - RenderingServer::get_singleton()->shader_get_param_list(shader, &local); + RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader, &local); params_cache.clear(); params_cache_dirty = false; for (PropertyInfo &pi : local) { - if (default_textures.has(pi.name)) { //do not show default textures + bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP; + if (!p_get_groups && is_group) { continue; } - String original_name = pi.name; - pi.name = "shader_param/" + pi.name; - params_cache[pi.name] = original_name; + if (!is_group) { + if (default_textures.has(pi.name)) { //do not show default textures + continue; + } + params_cache[pi.name] = pi.name; + } if (p_params) { //small little hack if (pi.type == Variant::RID) { @@ -135,8 +176,8 @@ bool Shader::is_text_shader() const { return true; } -bool Shader::has_param(const StringName &p_param) const { - return params_cache.has("shader_param/" + p_param); +bool Shader::has_uniform(const StringName &p_param) const { + return params_cache.has("shader_uniform/" + p_param); } void Shader::_update_shader() const { @@ -151,7 +192,7 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_texture_param", "param", "texture", "index"), &Shader::set_default_texture_param, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_default_texture_param", "param", "index"), &Shader::get_default_texture_param, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param); + ClassDB::bind_method(D_METHOD("has_uniform", "name"), &Shader::has_uniform); ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); @@ -210,7 +251,7 @@ String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const return ""; } -Error ResourceFormatSaverShader::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { +Error ResourceFormatSaverShader::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { Ref<Shader> shader = p_resource; ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER); diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 11c9f60ce8..abc953de5f 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -35,6 +35,7 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "scene/resources/texture.h" +#include "shader_include.h" class Shader : public Resource { GDCLASS(Shader, Resource); @@ -53,6 +54,8 @@ public: private: RID shader; Mode mode = MODE_SPATIAL; + HashSet<Ref<ShaderInclude>> include_dependencies; + String code; // hack the name of performance // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make @@ -61,6 +64,7 @@ private: mutable HashMap<StringName, StringName> params_cache; //map a shader param to a material param.. HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures; + void _dependency_changed(); virtual void _update_shader() const; //used for visual shader protected: static void _bind_methods(); @@ -69,24 +73,26 @@ public: //void set_mode(Mode p_mode); virtual Mode get_mode() const; + virtual void set_path(const String &p_path, bool p_take_over = false) override; + void set_code(const String &p_code); String get_code() const; - void get_param_list(List<PropertyInfo> *p_params) const; - bool has_param(const StringName &p_param) const; + void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; + bool has_uniform(const StringName &p_param) const; - void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index = 0); - Ref<Texture2D> get_default_texture_param(const StringName &p_param, int p_index = 0) const; + void set_default_texture_param(const StringName &p_uniform, const Ref<Texture2D> &p_texture, int p_index = 0); + Ref<Texture2D> get_default_texture_param(const StringName &p_uniform, int p_index = 0) const; void get_default_texture_param_list(List<StringName> *r_textures) const; virtual bool is_text_shader() const; - _FORCE_INLINE_ StringName remap_param(const StringName &p_param) const { + _FORCE_INLINE_ StringName remap_uniform(const StringName &p_uniform) const { if (params_cache_dirty) { - get_param_list(nullptr); + get_shader_uniform_list(nullptr); } - const HashMap<StringName, StringName>::Iterator E = params_cache.find(p_param); + const HashMap<StringName, StringName>::Iterator E = params_cache.find(p_uniform); if (E) { return E->value; } @@ -111,7 +117,7 @@ public: class ResourceFormatSaverShader : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; virtual bool recognize(const Ref<Resource> &p_resource) const; }; diff --git a/scene/resources/shader_include.cpp b/scene/resources/shader_include.cpp new file mode 100644 index 0000000000..42435fe3c7 --- /dev/null +++ b/scene/resources/shader_include.cpp @@ -0,0 +1,144 @@ +/*************************************************************************/ +/* shader_include.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (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 "shader_include.h" +#include "servers/rendering/shader_language.h" +#include "servers/rendering/shader_preprocessor.h" + +void ShaderInclude::_dependency_changed() { + emit_changed(); +} + +void ShaderInclude::set_code(const String &p_code) { + HashSet<Ref<ShaderInclude>> new_dependencies; + code = p_code; + + for (Ref<ShaderInclude> E : dependencies) { + E->disconnect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed)); + } + + { + String pp_code; + ShaderPreprocessor preprocessor; + preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_dependencies); + } + + // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) + dependencies = new_dependencies; + + for (Ref<ShaderInclude> E : dependencies) { + E->connect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed)); + } + + emit_changed(); +} + +String ShaderInclude::get_code() const { + return code; +} + +void ShaderInclude::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_code", "code"), &ShaderInclude::set_code); + ClassDB::bind_method(D_METHOD("get_code"), &ShaderInclude::get_code); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); +} + +// ResourceFormatLoaderShaderInclude + +Ref<Resource> ResourceFormatLoaderShaderInclude::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { + if (r_error) { + *r_error = ERR_FILE_CANT_OPEN; + } + + Ref<ShaderInclude> shader_inc; + shader_inc.instantiate(); + + Vector<uint8_t> buffer = FileAccess::get_file_as_array(p_path); + + String str; + str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + + shader_inc->set_code(str); + + if (r_error) { + *r_error = OK; + } + + return shader_inc; +} + +void ResourceFormatLoaderShaderInclude::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("gdshaderinc"); +} + +bool ResourceFormatLoaderShaderInclude::handles_type(const String &p_type) const { + return (p_type == "ShaderInclude"); +} + +String ResourceFormatLoaderShaderInclude::get_resource_type(const String &p_path) const { + String extension = p_path.get_extension().to_lower(); + if (extension == "gdshaderinc") { + return "ShaderInclude"; + } + return ""; +} + +// ResourceFormatSaverShaderInclude + +Error ResourceFormatSaverShaderInclude::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { + Ref<ShaderInclude> shader_inc = p_resource; + ERR_FAIL_COND_V(shader_inc.is_null(), ERR_INVALID_PARAMETER); + + String source = shader_inc->get_code(); + + Error error; + Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &error); + + ERR_FAIL_COND_V_MSG(error, error, "Cannot save shader include '" + p_path + "'."); + + file->store_string(source); + if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { + return ERR_CANT_CREATE; + } + + return OK; +} + +void ResourceFormatSaverShaderInclude::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { + const ShaderInclude *shader_inc = Object::cast_to<ShaderInclude>(*p_resource); + if (shader_inc != nullptr) { + p_extensions->push_back("gdshaderinc"); + } +} + +bool ResourceFormatSaverShaderInclude::recognize(const Ref<Resource> &p_resource) const { + return p_resource->get_class_name() == "ShaderInclude"; //only shader, not inherited +} diff --git a/scene/resources/scene_replication_config.h b/scene/resources/shader_include.h index ab3658d2a7..b0865e3a61 100644 --- a/scene/resources/scene_replication_config.h +++ b/scene/resources/shader_include.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* scene_replication_config.h */ +/* shader_include.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,64 +28,44 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_REPLICATION_CONFIG_H -#define SCENE_REPLICATION_CONFIG_H +#ifndef SHADER_INCLUDE_H +#define SHADER_INCLUDE_H #include "core/io/resource.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/templates/hash_set.h" -#include "core/variant/typed_array.h" - -class SceneReplicationConfig : public Resource { - GDCLASS(SceneReplicationConfig, Resource); - OBJ_SAVE_TYPE(SceneReplicationConfig); - RES_BASE_EXTENSION("repl"); +class ShaderInclude : public Resource { + GDCLASS(ShaderInclude, Resource); + OBJ_SAVE_TYPE(ShaderInclude); private: - struct ReplicationProperty { - NodePath name; - bool spawn = true; - bool sync = true; - - bool operator==(const ReplicationProperty &p_to) { - return name == p_to.name; - } - - ReplicationProperty() {} - - ReplicationProperty(const NodePath &p_name) { - name = p_name; - } - }; - - List<ReplicationProperty> properties; - List<NodePath> spawn_props; - List<NodePath> sync_props; + String code; + HashSet<Ref<ShaderInclude>> dependencies; + void _dependency_changed(); protected: static void _bind_methods(); - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - public: - TypedArray<NodePath> get_properties() const; - - void add_property(const NodePath &p_path, int p_index = -1); - void remove_property(const NodePath &p_path); - bool has_property(const NodePath &p_path) const; - - int property_get_index(const NodePath &p_path) const; - bool property_get_spawn(const NodePath &p_path); - void property_set_spawn(const NodePath &p_path, bool p_enabled); - - bool property_get_sync(const NodePath &p_path); - void property_set_sync(const NodePath &p_path, bool p_enabled); + void set_code(const String &p_text); + String get_code() const; +}; - const List<NodePath> &get_spawn_properties() { return spawn_props; } - const List<NodePath> &get_sync_properties() { return sync_props; } +class ResourceFormatLoaderShaderInclude : public ResourceFormatLoader { +public: + virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; - SceneReplicationConfig() {} +class ResourceFormatSaverShaderInclude : public ResourceFormatSaver { +public: + virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const Ref<Resource> &p_resource) const; }; -#endif // SCENE_REPLICATION_CONFIG_H +#endif // SHADER_INCLUDE_H diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index 77e79a269d..58fe723d89 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -73,4 +73,4 @@ public: ~Shape3D(); }; -#endif // SHAPE_H +#endif // SHAPE_3D_H diff --git a/scene/resources/skeleton_modification_2d.h b/scene/resources/skeleton_modification_2d.h index 3b9235ffd8..4c49119df0 100644 --- a/scene/resources/skeleton_modification_2d.h +++ b/scene/resources/skeleton_modification_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2D_H -#define SKELETONMODIFICATION2D_H +#ifndef SKELETON_MODIFICATION_2D_H +#define SKELETON_MODIFICATION_2D_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_stack_2d.h" @@ -86,4 +86,4 @@ public: SkeletonModification2D(); }; -#endif // SKELETONMODIFICATION2D_H +#endif // SKELETON_MODIFICATION_2D_H diff --git a/scene/resources/skeleton_modification_2d_ccdik.h b/scene/resources/skeleton_modification_2d_ccdik.h index 31485fa31f..e49dfca5b5 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.h +++ b/scene/resources/skeleton_modification_2d_ccdik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DCCDIK_H -#define SKELETONMODIFICATION2DCCDIK_H +#ifndef SKELETON_MODIFICATION_2D_CCDIK_H +#define SKELETON_MODIFICATION_2D_CCDIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -113,4 +113,4 @@ public: ~SkeletonModification2DCCDIK(); }; -#endif // SKELETONMODIFICATION2DCCDIK_H +#endif // SKELETON_MODIFICATION_2D_CCDIK_H diff --git a/scene/resources/skeleton_modification_2d_fabrik.h b/scene/resources/skeleton_modification_2d_fabrik.h index d5077084ef..4a875d039f 100644 --- a/scene/resources/skeleton_modification_2d_fabrik.h +++ b/scene/resources/skeleton_modification_2d_fabrik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DFABRIK_H -#define SKELETONMODIFICATION2DFABRIK_H +#ifndef SKELETON_MODIFICATION_2D_FABRIK_H +#define SKELETON_MODIFICATION_2D_FABRIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -105,4 +105,4 @@ public: ~SkeletonModification2DFABRIK(); }; -#endif // SKELETONMODIFICATION2DFABRIK_H +#endif // SKELETON_MODIFICATION_2D_FABRIK_H diff --git a/scene/resources/skeleton_modification_2d_jiggle.h b/scene/resources/skeleton_modification_2d_jiggle.h index a1abca6564..b9080eafa9 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.h +++ b/scene/resources/skeleton_modification_2d_jiggle.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DJIGGLE_H -#define SKELETONMODIFICATION2DJIGGLE_H +#ifndef SKELETON_MODIFICATION_2D_JIGGLE_H +#define SKELETON_MODIFICATION_2D_JIGGLE_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -136,4 +136,4 @@ public: ~SkeletonModification2DJiggle(); }; -#endif // SKELETONMODIFICATION2DJIGGLE_H +#endif // SKELETON_MODIFICATION_2D_JIGGLE_H diff --git a/scene/resources/skeleton_modification_2d_lookat.h b/scene/resources/skeleton_modification_2d_lookat.h index ff91b92e7d..e4d7afa605 100644 --- a/scene/resources/skeleton_modification_2d_lookat.h +++ b/scene/resources/skeleton_modification_2d_lookat.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DLOOKAT_H -#define SKELETONMODIFICATION2DLOOKAT_H +#ifndef SKELETON_MODIFICATION_2D_LOOKAT_H +#define SKELETON_MODIFICATION_2D_LOOKAT_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -97,4 +97,4 @@ public: ~SkeletonModification2DLookAt(); }; -#endif // SKELETONMODIFICATION2DLOOKAT_H +#endif // SKELETON_MODIFICATION_2D_LOOKAT_H diff --git a/scene/resources/skeleton_modification_2d_physicalbones.h b/scene/resources/skeleton_modification_2d_physicalbones.h index 373ff666ee..55482b2cca 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.h +++ b/scene/resources/skeleton_modification_2d_physicalbones.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DPHYSICALBONES_H -#define SKELETONMODIFICATION2DPHYSICALBONES_H +#ifndef SKELETON_MODIFICATION_2D_PHYSICALBONES_H +#define SKELETON_MODIFICATION_2D_PHYSICALBONES_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -79,4 +79,4 @@ public: ~SkeletonModification2DPhysicalBones(); }; -#endif // SKELETONMODIFICATION2DPHYSICALBONES_H +#endif // SKELETON_MODIFICATION_2D_PHYSICALBONES_H diff --git a/scene/resources/skeleton_modification_2d_stackholder.h b/scene/resources/skeleton_modification_2d_stackholder.h index 99d9f6f381..4da9fcc1f6 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.h +++ b/scene/resources/skeleton_modification_2d_stackholder.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DSTACKHOLDER_H -#define SKELETONMODIFICATION2DSTACKHOLDER_H +#ifndef SKELETON_MODIFICATION_2D_STACKHOLDER_H +#define SKELETON_MODIFICATION_2D_STACKHOLDER_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -61,4 +61,4 @@ public: ~SkeletonModification2DStackHolder(); }; -#endif // SKELETONMODIFICATION2DSTACKHOLDER_H +#endif // SKELETON_MODIFICATION_2D_STACKHOLDER_H diff --git a/scene/resources/skeleton_modification_2d_twoboneik.h b/scene/resources/skeleton_modification_2d_twoboneik.h index fc14d35f70..e1dbb6cfda 100644 --- a/scene/resources/skeleton_modification_2d_twoboneik.h +++ b/scene/resources/skeleton_modification_2d_twoboneik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DTWOBONEIK_H -#define SKELETONMODIFICATION2DTWOBONEIK_H +#ifndef SKELETON_MODIFICATION_2D_TWOBONEIK_H +#define SKELETON_MODIFICATION_2D_TWOBONEIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -104,4 +104,4 @@ public: ~SkeletonModification2DTwoBoneIK(); }; -#endif // SKELETONMODIFICATION2DTWOBONEIK_H +#endif // SKELETON_MODIFICATION_2D_TWOBONEIK_H diff --git a/scene/resources/skeleton_modification_3d.h b/scene/resources/skeleton_modification_3d.h index ab736fcbd2..6daf5efcd9 100644 --- a/scene/resources/skeleton_modification_3d.h +++ b/scene/resources/skeleton_modification_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION3D_H -#define SKELETONMODIFICATION3D_H +#ifndef SKELETON_MODIFICATION_3D_H +#define SKELETON_MODIFICATION_3D_H #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_stack_3d.h" @@ -76,4 +76,4 @@ public: SkeletonModification3D(); }; -#endif // SKELETONMODIFICATION3D_H +#endif // SKELETON_MODIFICATION_3D_H diff --git a/scene/resources/skeleton_modification_3d_ccdik.h b/scene/resources/skeleton_modification_3d_ccdik.h index 873ab8aa5a..7098794038 100644 --- a/scene/resources/skeleton_modification_3d_ccdik.h +++ b/scene/resources/skeleton_modification_3d_ccdik.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DCCDIK_H -#define SKELETONMODIFICATION3DCCDIK_H +#ifndef SKELETON_MODIFICATION_3D_CCDIK_H +#define SKELETON_MODIFICATION_3D_CCDIK_H class SkeletonModification3DCCDIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DCCDIK, SkeletonModification3D); @@ -111,4 +111,4 @@ public: ~SkeletonModification3DCCDIK(); }; -#endif //SKELETONMODIFICATION3DCCDIK_H +#endif // SKELETON_MODIFICATION_3D_CCDIK_H diff --git a/scene/resources/skeleton_modification_3d_fabrik.h b/scene/resources/skeleton_modification_3d_fabrik.h index cc4d3a5e20..3d66bb6d99 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.h +++ b/scene/resources/skeleton_modification_3d_fabrik.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DFABRIK_H -#define SKELETONMODIFICATION3DFABRIK_H +#ifndef SKELETON_MODIFICATION_3D_FABRIK_H +#define SKELETON_MODIFICATION_3D_FABRIK_H class SkeletonModification3DFABRIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DFABRIK, SkeletonModification3D); @@ -121,4 +121,4 @@ public: ~SkeletonModification3DFABRIK(); }; -#endif //SKELETONMODIFICATION3DFABRIK_H +#endif // SKELETON_MODIFICATION_3D_FABRIK_H diff --git a/scene/resources/skeleton_modification_3d_jiggle.h b/scene/resources/skeleton_modification_3d_jiggle.h index 7ec5ed4f11..f41ffcd58d 100644 --- a/scene/resources/skeleton_modification_3d_jiggle.h +++ b/scene/resources/skeleton_modification_3d_jiggle.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DJIGGLE_H -#define SKELETONMODIFICATION3DJIGGLE_H +#ifndef SKELETON_MODIFICATION_3D_JIGGLE_H +#define SKELETON_MODIFICATION_3D_JIGGLE_H class SkeletonModification3DJiggle : public SkeletonModification3D { GDCLASS(SkeletonModification3DJiggle, SkeletonModification3D); @@ -135,4 +135,4 @@ public: ~SkeletonModification3DJiggle(); }; -#endif //SKELETONMODIFICATION3DJIGGLE_H +#endif // SKELETON_MODIFICATION_3D_JIGGLE_H diff --git a/scene/resources/skeleton_modification_3d_lookat.h b/scene/resources/skeleton_modification_3d_lookat.h index 9f5120a0fd..4e5714b5dc 100644 --- a/scene/resources/skeleton_modification_3d_lookat.h +++ b/scene/resources/skeleton_modification_3d_lookat.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DLOOKAT_H -#define SKELETONMODIFICATION3DLOOKAT_H +#ifndef SKELETON_MODIFICATION_3D_LOOKAT_H +#define SKELETON_MODIFICATION_3D_LOOKAT_H class SkeletonModification3DLookAt : public SkeletonModification3D { GDCLASS(SkeletonModification3DLookAt, SkeletonModification3D); @@ -86,4 +86,4 @@ public: ~SkeletonModification3DLookAt(); }; -#endif //SKELETONMODIFICATION3DLOOKAT_H +#endif // SKELETON_MODIFICATION_3D_LOOKAT_H diff --git a/scene/resources/skeleton_modification_3d_stackholder.h b/scene/resources/skeleton_modification_3d_stackholder.h index 5780d7d43f..ae22099158 100644 --- a/scene/resources/skeleton_modification_3d_stackholder.h +++ b/scene/resources/skeleton_modification_3d_stackholder.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DSTACKHOLDER_H -#define SKELETONMODIFICATION3DSTACKHOLDER_H +#ifndef SKELETON_MODIFICATION_3D_STACKHOLDER_H +#define SKELETON_MODIFICATION_3D_STACKHOLDER_H class SkeletonModification3DStackHolder : public SkeletonModification3D { GDCLASS(SkeletonModification3DStackHolder, SkeletonModification3D); @@ -56,4 +56,4 @@ public: ~SkeletonModification3DStackHolder(); }; -#endif //SKELETONMODIFICATION3DSTACKHOLDER_H +#endif // SKELETON_MODIFICATION_3D_STACKHOLDER_H diff --git a/scene/resources/skeleton_modification_3d_twoboneik.h b/scene/resources/skeleton_modification_3d_twoboneik.h index a4ddc6cee7..57e8237511 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.h +++ b/scene/resources/skeleton_modification_3d_twoboneik.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DTWOBONEIK_H -#define SKELETONMODIFICATION3DTWOBONEIK_H +#ifndef SKELETON_MODIFICATION_3D_TWOBONEIK_H +#define SKELETON_MODIFICATION_3D_TWOBONEIK_H class SkeletonModification3DTwoBoneIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DTwoBoneIK, SkeletonModification3D); @@ -115,4 +115,4 @@ public: ~SkeletonModification3DTwoBoneIK(); }; -#endif //SKELETONMODIFICATION3DTWOBONEIK_H +#endif // SKELETON_MODIFICATION_3D_TWOBONEIK_H diff --git a/scene/resources/skeleton_modification_stack_2d.h b/scene/resources/skeleton_modification_stack_2d.h index 7b5f8e0322..ceffd71368 100644 --- a/scene/resources/skeleton_modification_stack_2d.h +++ b/scene/resources/skeleton_modification_stack_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATIONSTACK2D_H -#define SKELETONMODIFICATIONSTACK2D_H +#ifndef SKELETON_MODIFICATION_STACK_2D_H +#define SKELETON_MODIFICATION_STACK_2D_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -96,4 +96,4 @@ public: SkeletonModificationStack2D(); }; -#endif // SKELETONMODIFICATION2D_H +#endif // SKELETON_MODIFICATION_STACK_2D_H diff --git a/scene/resources/skeleton_modification_stack_3d.h b/scene/resources/skeleton_modification_stack_3d.h index 2c17fba2c5..4ff1bd1e33 100644 --- a/scene/resources/skeleton_modification_stack_3d.h +++ b/scene/resources/skeleton_modification_stack_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATIONSTACK3D_H -#define SKELETONMODIFICATIONSTACK3D_H +#ifndef SKELETON_MODIFICATION_STACK_3D_H +#define SKELETON_MODIFICATION_STACK_3D_H #include "core/templates/local_vector.h" #include "scene/3d/skeleton_3d.h" @@ -88,4 +88,4 @@ public: SkeletonModificationStack3D(); }; -#endif // SKELETONMODIFICATIONSTACK3D_H +#endif // SKELETON_MODIFICATION_STACK_3D_H diff --git a/scene/resources/skeleton_profile.cpp b/scene/resources/skeleton_profile.cpp index 0714de470c..bfb4bb6e2b 100644 --- a/scene/resources/skeleton_profile.cpp +++ b/scene/resources/skeleton_profile.cpp @@ -123,12 +123,20 @@ bool SkeletonProfile::_get(const StringName &p_path, Variant &r_ret) const { void SkeletonProfile::_validate_property(PropertyInfo &property) const { if (is_read_only) { - if (property.name == ("group_size") || property.name == ("bone_size")) { + if (property.name == ("group_size") || property.name == ("bone_size") || property.name == ("root_bone") || property.name == ("scale_base_bone")) { property.usage = PROPERTY_USAGE_NO_EDITOR; return; } } + if (property.name == ("root_bone") || property.name == ("scale_base_bone")) { + String hint = ""; + for (int i = 0; i < bones.size(); i++) { + hint += i == 0 ? String(bones[i].bone_name) : "," + String(bones[i].bone_name); + } + property.hint_string = hint; + } + PackedStringArray split = property.name.split("/"); if (split.size() == 3 && split[0] == "bones") { if (split[2] == "bone_tail" && get_tail_direction(split[1].to_int()) != TAIL_DIRECTION_SPECIFIC_CHILD) { @@ -168,6 +176,28 @@ void SkeletonProfile::_get_property_list(List<PropertyInfo> *p_list) const { } } +StringName SkeletonProfile::get_root_bone() { + return root_bone; +} + +void SkeletonProfile::set_root_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + root_bone = p_bone_name; +} + +StringName SkeletonProfile::get_scale_base_bone() { + return scale_base_bone; +} + +void SkeletonProfile::set_scale_base_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + scale_base_bone = p_bone_name; +} + int SkeletonProfile::get_group_size() { return groups.size(); } @@ -361,6 +391,12 @@ bool SkeletonProfile::has_bone(StringName p_bone_name) { } void SkeletonProfile::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_root_bone", "bone_name"), &SkeletonProfile::set_root_bone); + ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonProfile::get_root_bone); + + ClassDB::bind_method(D_METHOD("set_scale_base_bone", "bone_name"), &SkeletonProfile::set_scale_base_bone); + ClassDB::bind_method(D_METHOD("get_scale_base_bone"), &SkeletonProfile::get_scale_base_bone); + ClassDB::bind_method(D_METHOD("set_group_size", "size"), &SkeletonProfile::set_group_size); ClassDB::bind_method(D_METHOD("get_group_size"), &SkeletonProfile::get_group_size); @@ -396,6 +432,9 @@ void SkeletonProfile::_bind_methods() { ClassDB::bind_method(D_METHOD("get_group", "bone_idx"), &SkeletonProfile::get_group); ClassDB::bind_method(D_METHOD("set_group", "bone_idx", "group"), &SkeletonProfile::set_group); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_root_bone", "get_root_bone"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "scale_base_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_scale_base_bone", "get_scale_base_bone"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "group_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Groups,groups/"), "set_group_size", "get_group_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Bones,bones/"), "set_bone_size", "get_bone_size"); @@ -415,6 +454,9 @@ SkeletonProfile::~SkeletonProfile() { SkeletonProfileHumanoid::SkeletonProfileHumanoid() { is_read_only = true; + root_bone = "Root"; + scale_base_bone = "Hips"; + groups.resize(4); groups.write[0].group_name = "Body"; diff --git a/scene/resources/skeleton_profile.h b/scene/resources/skeleton_profile.h index d305311538..84dfca458e 100644 --- a/scene/resources/skeleton_profile.h +++ b/scene/resources/skeleton_profile.h @@ -64,6 +64,9 @@ protected: bool require = false; }; + StringName root_bone; + StringName scale_base_bone; + Vector<SkeletonProfileGroup> groups; Vector<SkeletonProfileBone> bones; @@ -74,6 +77,12 @@ protected: static void _bind_methods(); public: + StringName get_root_bone(); + void set_root_bone(StringName p_bone_name); + + StringName get_scale_base_bone(); + void set_scale_base_bone(StringName p_bone_name); + int get_group_size(); void set_group_size(int p_size); diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 5be8922ba4..61999af3c4 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -219,4 +219,4 @@ public: ~PhysicalSkyMaterial(); }; -#endif /* !SKY_MATERIAL_H */ +#endif // SKY_MATERIAL_H diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h index 8f77378ef4..91d72e01ec 100644 --- a/scene/resources/sphere_shape_3d.h +++ b/scene/resources/sphere_shape_3d.h @@ -52,4 +52,4 @@ public: SphereShape3D(); }; -#endif // SPHERE_SHAPE_H +#endif // SPHERE_SHAPE_3D_H diff --git a/scene/resources/sprite_frames.cpp b/scene/resources/sprite_frames.cpp index 55c9d7397d..3533e86c3a 100644 --- a/scene/resources/sprite_frames.cpp +++ b/scene/resources/sprite_frames.cpp @@ -207,7 +207,7 @@ void SpriteFrames::_bind_methods() { // `animations` property is for serialization. - ClassDB::bind_method(D_METHOD("_set_animations"), &SpriteFrames::_set_animations); + ClassDB::bind_method(D_METHOD("_set_animations", "animations"), &SpriteFrames::_set_animations); ClassDB::bind_method(D_METHOD("_get_animations"), &SpriteFrames::_get_animations); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_animations", "_get_animations"); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 3b3654775f..9f4f69d3ba 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -264,4 +264,4 @@ public: ~StyleBoxLine(); }; -#endif +#endif // STYLE_BOX_H diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 2d399ca3bf..6735d6623f 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -207,4 +207,4 @@ public: VARIANT_ENUM_CAST(SurfaceTool::CustomFormat) VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount) -#endif +#endif // SURFACE_TOOL_H diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 1243a9dbf7..69131ffbee 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -142,4 +142,4 @@ public: Color get_member_variable_color() const; }; -#endif +#endif // SYNTAX_HIGHLIGHTER_H diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h index 0c8cf855f0..168e4f5879 100644 --- a/scene/resources/text_file.h +++ b/scene/resources/text_file.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEXTFILE_H -#define TEXTFILE_H +#ifndef TEXT_FILE_H +#define TEXT_FILE_H #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -51,4 +51,4 @@ public: Error load_text(const String &p_path); }; -#endif // TEXTFILE_H +#endif // TEXT_FILE_H diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 4e7ec9315a..823d742d72 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -74,7 +74,7 @@ void TextLine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextLine::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextLine::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justication,Trim Edge Spaces After Justication,Justify Only After Last Tab,Constrain Ellipsis"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextLine::set_text_overrun_behavior); ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextLine::get_text_overrun_behavior); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 2d9e0066e1..43d3f329fa 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -77,12 +77,12 @@ void TextParagraph::_bind_methods() { ClassDB::bind_method(D_METHOD("set_break_flags", "flags"), &TextParagraph::set_break_flags); ClassDB::bind_method(D_METHOD("get_break_flags"), &TextParagraph::get_break_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "break_flags", PROPERTY_HINT_FLAGS, "Mandatory,Word Bouns,Grapheme Bound,Adaptive"), "set_break_flags", "get_break_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "break_flags", PROPERTY_HINT_FLAGS, "Mandatory,Word Bound,Grapheme Bound,Adaptive"), "set_break_flags", "get_break_flags"); ClassDB::bind_method(D_METHOD("set_justification_flags", "flags"), &TextParagraph::set_justification_flags); ClassDB::bind_method(D_METHOD("get_justification_flags"), &TextParagraph::get_justification_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justication,Trim Edge Spaces After Justication,Justify Only After Last Tab,Constrain Ellipsis"), "set_justification_flags", "get_justification_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_justification_flags", "get_justification_flags"); ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextParagraph::set_text_overrun_behavior); ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextParagraph::get_text_overrun_behavior); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 21ae62c92e..05ed9238b8 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -323,6 +323,7 @@ void ImageTexture::_bind_methods() { ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image); ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format); + ClassDB::bind_method(D_METHOD("set_image", "image"), &ImageTexture::set_image); ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update); ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override); } @@ -2008,7 +2009,7 @@ void CurveXYZTexture::set_curve_x(Ref<Curve> p_curve) { } _curve_x = p_curve; if (_curve_x.is_valid()) { - _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } @@ -2021,7 +2022,7 @@ void CurveXYZTexture::set_curve_y(Ref<Curve> p_curve) { } _curve_y = p_curve; if (_curve_y.is_valid()) { - _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } @@ -2034,7 +2035,7 @@ void CurveXYZTexture::set_curve_z(Ref<Curve> p_curve) { } _curve_z = p_curve; if (_curve_z.is_valid()) { - _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED); + _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED); } _update(); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index b107a2a70d..36b193c5d4 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -1106,4 +1106,4 @@ public: PlaceholderTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {} }; -#endif +#endif // TEXTURE_H diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 39b77568cf..3f6eec8497 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -295,7 +295,7 @@ void Theme::set_default_font(const Ref<Font> &p_default_font) { default_font = p_default_font; if (default_font.is_valid()) { - default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + default_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(); @@ -341,7 +341,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_theme_type, c icon_map[p_theme_type][p_name] = p_icon; if (p_icon.is_valid()) { - icon_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + icon_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); @@ -451,7 +451,7 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_theme_typ style_map[p_theme_type][p_name] = p_style; if (p_style.is_valid()) { - style_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + style_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); @@ -561,7 +561,7 @@ void Theme::set_font(const StringName &p_name, const StringName &p_theme_type, c font_map[p_theme_type][p_name] = p_font; if (p_font.is_valid()) { - font_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(false), CONNECT_REFERENCE_COUNTED); + font_map[p_theme_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed).bind(false), CONNECT_REFERENCE_COUNTED); } _emit_theme_changed(!existing); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 87d7d2fdea..a2aca5e61f 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -256,4 +256,4 @@ public: VARIANT_ENUM_CAST(Theme::DataType); -#endif +#endif // THEME_H diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 22b5ef0108..b0b9f1228f 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -1048,13 +1048,13 @@ int TileSet::get_custom_data_layer_by_name(String p_value) const { } } -void TileSet::set_custom_data_name(int p_layer_id, String p_value) { +void TileSet::set_custom_data_layer_name(int p_layer_id, String p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size()); // Exit if another property has the same name. if (!p_value.is_empty()) { for (int other_layer_id = 0; other_layer_id < get_custom_data_layers_count(); other_layer_id++) { - if (other_layer_id != p_layer_id && get_custom_data_name(other_layer_id) == p_value) { + if (other_layer_id != p_layer_id && get_custom_data_layer_name(other_layer_id) == p_value) { ERR_FAIL_MSG(vformat("There is already a custom property named %s", p_value)); } } @@ -1070,12 +1070,12 @@ void TileSet::set_custom_data_name(int p_layer_id, String p_value) { emit_changed(); } -String TileSet::get_custom_data_name(int p_layer_id) const { +String TileSet::get_custom_data_layer_name(int p_layer_id) const { ERR_FAIL_INDEX_V(p_layer_id, custom_data_layers.size(), ""); return custom_data_layers[p_layer_id].name; } -void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) { +void TileSet::set_custom_data_layer_type(int p_layer_id, Variant::Type p_value) { ERR_FAIL_INDEX(p_layer_id, custom_data_layers.size()); custom_data_layers.write[p_layer_id].type = p_value; @@ -1086,7 +1086,7 @@ void TileSet::set_custom_data_type(int p_layer_id, Variant::Type p_value) { emit_changed(); } -Variant::Type TileSet::get_custom_data_type(int p_layer_id) const { +Variant::Type TileSet::get_custom_data_layer_type(int p_layer_id) const { ERR_FAIL_INDEX_V(p_layer_id, custom_data_layers.size(), Variant::NIL); return custom_data_layers[p_layer_id].type; } @@ -2467,9 +2467,42 @@ Vector<Point2> TileSet::_get_half_offset_side_terrain_peering_bit_polygon(Vector } void TileSet::reset_state() { + // Rendering occlusion_layers.clear(); + tile_lines_mesh.instantiate(); + tile_filled_mesh.instantiate(); + tile_meshes_dirty = true; + + // Physics physics_layers.clear(); + + // Terrains + terrain_sets.clear(); + terrain_meshes.clear(); + terrain_peering_bits_meshes.clear(); + per_terrain_pattern_tiles.clear(); + terrains_cache_dirty = true; + + // Navigation + navigation_layers.clear(); + custom_data_layers.clear(); + custom_data_layers_by_name.clear(); + + // Proxies + source_level_proxies.clear(); + coords_level_proxies.clear(); + alternative_level_proxies.clear(); + +#ifndef DISABLE_DEPRECATED + for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) { + memdelete(E.value); + } + compatibility_data.clear(); +#endif // DISABLE_DEPRECATED + while (!source_ids.is_empty()) { + remove_source(source_ids[0]); + } } const Vector2i TileSetSource::INVALID_ATLAS_COORDS = Vector2i(-1, -1); @@ -3003,14 +3036,14 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { while (index >= custom_data_layers.size()) { add_custom_data_layer(); } - set_custom_data_name(index, p_value); + set_custom_data_layer_name(index, p_value); return true; } else if (components[1] == "type") { ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false); while (index >= custom_data_layers.size()) { add_custom_data_layer(); } - set_custom_data_type(index, Variant::Type(int(p_value))); + set_custom_data_layer_type(index, Variant::Type(int(p_value))); return true; } } else if (components.size() == 2 && components[0] == "sources" && components[1].is_valid_int()) { @@ -3132,10 +3165,10 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { return false; } if (components[1] == "name") { - r_ret = get_custom_data_name(index); + r_ret = get_custom_data_layer_name(index); return true; } else if (components[1] == "type") { - r_ret = get_custom_data_type(index); + r_ret = get_custom_data_layer_type(index); return true; } } else if (components.size() == 2 && components[0] == "sources" && components[1].is_valid_int()) { @@ -3358,6 +3391,11 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("add_custom_data_layer", "to_position"), &TileSet::add_custom_data_layer, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("move_custom_data_layer", "layer_index", "to_position"), &TileSet::move_custom_data_layer); ClassDB::bind_method(D_METHOD("remove_custom_data_layer", "layer_index"), &TileSet::remove_custom_data_layer); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_by_name", "layer_name"), &TileSet::get_custom_data_layer_by_name); + ClassDB::bind_method(D_METHOD("set_custom_data_layer_name", "layer_index", "layer_name"), &TileSet::set_custom_data_layer_name); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_name", "layer_index"), &TileSet::get_custom_data_layer_name); + ClassDB::bind_method(D_METHOD("set_custom_data_layer_type", "layer_index", "layer_type"), &TileSet::set_custom_data_layer_type); + ClassDB::bind_method(D_METHOD("get_custom_data_layer_type", "layer_index"), &TileSet::get_custom_data_layer_type); // Tile proxies ClassDB::bind_method(D_METHOD("set_source_level_tile_proxy", "source_from", "source_to"), &TileSet::set_source_level_tile_proxy); @@ -3457,6 +3495,10 @@ void TileSetSource::set_tile_set(const TileSet *p_tile_set) { tile_set = p_tile_set; } +void TileSetSource::reset_state() { + tile_set = nullptr; +}; + void TileSetSource::_bind_methods() { // Base tiles ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetSource::get_tiles_count); @@ -3640,12 +3682,17 @@ void TileSetAtlasSource::remove_custom_data_layer(int p_index) { } void TileSetAtlasSource::reset_state() { - // Reset all TileData. + tile_set = nullptr; + for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { - for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { - E_alternative.value->reset_state(); + for (const KeyValue<int, TileData *> &E_tile_data : E_tile.value.alternatives) { + memdelete(E_tile_data.value); } } + _coords_mapping_cache.clear(); + tiles.clear(); + tiles_ids.clear(); + _queue_update_padded_texture(); } void TileSetAtlasSource::set_texture(Ref<Texture2D> p_texture) { @@ -4805,14 +4852,14 @@ void TileData::notify_tile_data_properties_should_change() { // Convert custom data to the new type. custom_data.resize(tile_set->get_custom_data_layers_count()); for (int i = 0; i < custom_data.size(); i++) { - if (custom_data[i].get_type() != tile_set->get_custom_data_type(i)) { + if (custom_data[i].get_type() != tile_set->get_custom_data_layer_type(i)) { Variant new_val; Callable::CallError error; - if (Variant::can_convert(custom_data[i].get_type(), tile_set->get_custom_data_type(i))) { + if (Variant::can_convert(custom_data[i].get_type(), tile_set->get_custom_data_layer_type(i))) { const Variant *args[] = { &custom_data[i] }; - Variant::construct(tile_set->get_custom_data_type(i), new_val, args, 1, error); + Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, args, 1, error); } else { - Variant::construct(tile_set->get_custom_data_type(i), new_val, nullptr, 0, error); + Variant::construct(tile_set->get_custom_data_layer_type(i), new_val, nullptr, 0, error); } custom_data.write[i] = new_val; } @@ -4975,13 +5022,6 @@ void TileData::remove_custom_data_layer(int p_index) { custom_data.remove_at(p_index); } -void TileData::reset_state() { - occluders.clear(); - physics.clear(); - navigation.clear(); - custom_data.clear(); -} - void TileData::set_allow_transform(bool p_allow_transform) { allow_transform = p_allow_transform; } @@ -5626,7 +5666,7 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const { Variant default_val; Callable::CallError error; Variant::construct(custom_data[i].get_type(), default_val, nullptr, 0, error); - property_info = PropertyInfo(tile_set->get_custom_data_type(i), vformat("custom_data_%d", i), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + property_info = PropertyInfo(tile_set->get_custom_data_layer_type(i), vformat("custom_data_%d", i), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); if (custom_data[i] == default_val) { property_info.usage ^= PROPERTY_USAGE_STORAGE; } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 7368d2bd87..6ea3889fce 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -479,10 +479,10 @@ public: void move_custom_data_layer(int p_from_index, int p_to_pos); void remove_custom_data_layer(int p_index); int get_custom_data_layer_by_name(String p_value) const; - void set_custom_data_name(int p_layer_id, String p_value); - String get_custom_data_name(int p_layer_id) const; - void set_custom_data_type(int p_layer_id, Variant::Type p_value); - Variant::Type get_custom_data_type(int p_layer_id) const; + void set_custom_data_layer_name(int p_layer_id, String p_value); + String get_custom_data_layer_name(int p_layer_id) const; + void set_custom_data_layer_type(int p_layer_id, Variant::Type p_value); + Variant::Type get_custom_data_layer_type(int p_layer_id) const; // Tiles proxies. void set_source_level_tile_proxy(int p_source_from, int p_source_to); @@ -569,7 +569,7 @@ public: virtual void add_custom_data_layer(int p_index){}; virtual void move_custom_data_layer(int p_from_index, int p_to_pos){}; virtual void remove_custom_data_layer(int p_index){}; - virtual void reset_state() override{}; + virtual void reset_state() override; // Tiles. virtual int get_tiles_count() const = 0; @@ -847,7 +847,6 @@ public: void add_custom_data_layer(int p_index); void move_custom_data_layer(int p_from_index, int p_to_pos); void remove_custom_data_layer(int p_index); - void reset_state(); void set_allow_transform(bool p_allow_transform); bool is_allowing_transform() const; diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index 3e154d539b..35686b293c 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -72,7 +72,7 @@ class VideoStream : public Resource { public: virtual void set_audio_track(int p_track) = 0; - virtual Ref<VideoStreamPlayback> instance_playback() = 0; + virtual Ref<VideoStreamPlayback> instantiate_playback() = 0; }; -#endif +#endif // VIDEO_STREAM_H diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index b68cce9dda..a67716d52b 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -967,6 +967,12 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from ERR_FAIL_COND(!g->nodes.has(p_to_node)); ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); + for (const Connection &E : g->connections) { + if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) { + return; + } + } + Connection c; c.from_node = p_from_node; c.from_port = p_from_port; @@ -2641,6 +2647,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" }, // Node3D, Fragment { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" }, @@ -2669,6 +2679,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_right", "VIEW_RIGHT" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_world", "NODE_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_position_world", "CAMERA_POSITION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "camera_direction_world", "CAMERA_DIRECTION_WORLD" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "node_position_view", "NODE_POSITION_VIEW" }, // Node3D, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_4D, "fragcoord", "FRAGCOORD" }, @@ -3745,7 +3759,7 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T } return vformat(RTR("This uniform type does not support the '%s' qualifier."), qualifier_str); } else if (qualifier == Qualifier::QUAL_GLOBAL) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(uniform_name); + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(uniform_name); if (gvt == RS::GLOBAL_VAR_TYPE_MAX) { return vformat(RTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name); } diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index b8667f07fe..b422d298b2 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1901,13 +1901,7 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_REFLECT: - if (op_type == OP_TYPE_VECTOR_2D) { // Not supported. - code += "vec2(0.0);\n"; - } else if (op_type == OP_TYPE_VECTOR_4D) { // Not supported. - code += "vec4(0.0);\n"; - } else { - code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; - } + code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; @@ -1967,7 +1961,7 @@ String VisualShaderNodeVectorOp::get_warning(Shader::Mode p_mode, VisualShader:: bool invalid_type = false; if (op_type == OP_TYPE_VECTOR_2D || op_type == OP_TYPE_VECTOR_4D) { - if (op == OP_CROSS || op == OP_REFLECT) { + if (op == OP_CROSS) { invalid_type = true; } } @@ -4006,14 +4000,6 @@ int VisualShaderNodeVectorRefract::get_input_port_count() const { return 3; } -VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input_port_type(int p_port) const { - if (p_port == 2) { - return PORT_TYPE_SCALAR; - } - - return PORT_TYPE_VECTOR_3D; -} - String VisualShaderNodeVectorRefract::get_input_port_name(int p_port) const { switch (p_port) { case 0: @@ -4030,10 +4016,6 @@ int VisualShaderNodeVectorRefract::get_output_port_count() const { return 1; } -VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_output_port_type(int p_port) const { - return PORT_TYPE_VECTOR_3D; -} - String VisualShaderNodeVectorRefract::get_output_port_name(int p_port) const { return ""; } @@ -4042,6 +4024,31 @@ String VisualShaderNodeVectorRefract::generate_code(Shader::Mode p_mode, VisualS return " " + p_output_vars[0] + " = refract(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } +void VisualShaderNodeVectorRefract::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX)); + if (op_type == p_op_type) { + return; + } + switch (p_op_type) { + case OP_TYPE_VECTOR_2D: { + set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_3D: { + set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); + set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); + } break; + case OP_TYPE_VECTOR_4D: { + set_input_port_default_value(0, Quaternion(), get_input_port_default_value(0)); + set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1)); + } break; + default: + break; + } + op_type = p_op_type; + emit_changed(); +} + VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); @@ -5581,12 +5588,16 @@ String get_sampler_hint(VisualShaderNodeTextureUniform::TextureType p_texture_ty case VisualShaderNodeTextureUniform::TYPE_DATA: if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { type_code = "hint_default_black"; + } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + type_code = "hint_default_transparent"; } break; case VisualShaderNodeTextureUniform::TYPE_COLOR: type_code = "source_color"; if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_BLACK) { type_code += ", hint_default_black"; + } else if (p_color_default == VisualShaderNodeTextureUniform::COLOR_DEFAULT_TRANSPARENT) { + type_code += ", hint_default_transparent"; } break; case VisualShaderNodeTextureUniform::TYPE_NORMAL_MAP: @@ -5812,7 +5823,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("get_texture_repeat"), &VisualShaderNodeTextureUniform::get_texture_repeat); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black"), "set_color_default", "get_color_default"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White,Black,Transparent"), "set_color_default", "get_color_default"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Default,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Anisotropic,Linear Mipmap Anisotropic"), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Default,Enabled,Disabled"), "set_texture_repeat", "get_texture_repeat"); @@ -5824,6 +5835,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { BIND_ENUM_CONSTANT(COLOR_DEFAULT_WHITE); BIND_ENUM_CONSTANT(COLOR_DEFAULT_BLACK); + BIND_ENUM_CONSTANT(COLOR_DEFAULT_TRANSPARENT); BIND_ENUM_CONSTANT(COLOR_DEFAULT_MAX); BIND_ENUM_CONSTANT(FILTER_DEFAULT); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 1eb7b7240f..ffcb41072d 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1564,21 +1564,20 @@ public: /// REFRACT /////////////////////////////////////// -class VisualShaderNodeVectorRefract : public VisualShaderNode { - GDCLASS(VisualShaderNodeVectorRefract, VisualShaderNode); +class VisualShaderNodeVectorRefract : public VisualShaderNodeVectorBase { + GDCLASS(VisualShaderNodeVectorRefract, VisualShaderNodeVectorBase); public: virtual String get_caption() const override; virtual int get_input_port_count() const override; - virtual PortType get_input_port_type(int p_port) const override; virtual String get_input_port_name(int p_port) const override; virtual int get_output_port_count() const override; - virtual PortType get_output_port_type(int p_port) const override; virtual String get_output_port_name(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + virtual void set_op_type(OpType p_op_type) override; VisualShaderNodeVectorRefract(); }; @@ -2131,6 +2130,7 @@ public: enum ColorDefault { COLOR_DEFAULT_WHITE, COLOR_DEFAULT_BLACK, + COLOR_DEFAULT_TRANSPARENT, COLOR_DEFAULT_MAX, }; diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index 05a059373b..64acb6d18f 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -352,4 +352,4 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeParticleEmit::EmitFlags) -#endif +#endif // VISUAL_SHADER_PARTICLE_NODES_H diff --git a/scene/resources/world_boundary_shape_3d.h b/scene/resources/world_boundary_shape_3d.h index 5378bc52c7..5c34767106 100644 --- a/scene/resources/world_boundary_shape_3d.h +++ b/scene/resources/world_boundary_shape_3d.h @@ -53,4 +53,5 @@ public: WorldBoundaryShape3D(); }; -#endif // WORLD_BOUNDARY_SHAPE_H + +#endif // WORLD_BOUNDARY_SHAPE_3D_H |