diff options
Diffstat (limited to 'scene')
303 files changed, 12546 insertions, 15919 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 917ced5feb..f3f7ba9ddd 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -34,6 +34,7 @@ #include "scene/scene_string_names.h" #define NORMAL_SUFFIX "_normal" +#define SPECULAR_SUFFIX "_specular" #ifdef TOOLS_ENABLED Dictionary AnimatedSprite::_edit_get_state() const { @@ -68,7 +69,7 @@ bool AnimatedSprite::_edit_use_rect() const { if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { return false; } - Ref<Texture> t; + Ref<Texture2D> t; if (animation) t = frames->get_frame(animation, frame); return t.is_valid(); @@ -84,7 +85,7 @@ Rect2 AnimatedSprite::_get_rect() const { return Rect2(); } - Ref<Texture> t; + Ref<Texture2D> t; if (animation) t = frames->get_frame(animation, frame); if (t.is_null()) @@ -101,7 +102,7 @@ Rect2 AnimatedSprite::_get_rect() const { return Rect2(ofs, s); } -void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos) { +void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) { Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); @@ -150,6 +151,7 @@ void SpriteFrames::add_animation(const StringName &p_anim) { animations[p_anim] = Anim(); animations[p_anim].normal_name = String(p_anim) + NORMAL_SUFFIX; + animations[p_anim].specular_name = String(p_anim) + SPECULAR_SUFFIX; } bool SpriteFrames::has_animation(const StringName &p_anim) const { @@ -170,6 +172,7 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName & animations.erase(p_prev); animations[p_next] = anim; animations[p_next].normal_name = String(p_next) + NORMAL_SUFFIX; + animations[p_next].specular_name = String(p_next) + SPECULAR_SUFFIX; } Vector<String> SpriteFrames::_get_animation_list() const { @@ -438,11 +441,12 @@ void AnimatedSprite::_notification(int p_what) { if (!frames->has_animation(animation)) return; - Ref<Texture> texture = frames->get_frame(animation, frame); + Ref<Texture2D> texture = frames->get_frame(animation, frame); if (texture.is_null()) return; - Ref<Texture> normal = frames->get_normal_frame(animation, frame); + Ref<Texture2D> normal = frames->get_normal_frame(animation, frame); + Ref<Texture2D> specular = frames->get_specular_frame(animation, frame); RID ci = get_canvas_item(); @@ -462,7 +466,7 @@ void AnimatedSprite::_notification(int p_what) { if (vflip) dst_rect.size.y = -dst_rect.size.y; - texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal); + texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess)); } break; } @@ -471,10 +475,10 @@ void AnimatedSprite::_notification(int p_what) { void AnimatedSprite::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { if (frames.is_valid()) - frames->disconnect("changed", this, "_res_changed"); + frames->disconnect("changed", callable_mp(this, &AnimatedSprite::_res_changed)); frames = p_frames; if (frames.is_valid()) - frames->connect("changed", this, "_res_changed"); + frames->connect("changed", callable_mp(this, &AnimatedSprite::_res_changed)); if (!frames.is_valid()) { frame = 0; @@ -674,6 +678,24 @@ String AnimatedSprite::get_configuration_warning() const { return String(); } +void AnimatedSprite::set_specular_color(const Color &p_color) { + specular_color = p_color; + update(); +} + +Color AnimatedSprite::get_specular_color() const { + return specular_color; +} + +void AnimatedSprite::set_shininess(float p_shininess) { + shininess = CLAMP(p_shininess, 0.0, 1.0); + update(); +} + +float AnimatedSprite::get_shininess() const { + return shininess; +} + void AnimatedSprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite::set_sprite_frames); @@ -707,16 +729,25 @@ void AnimatedSprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_speed_scale", "speed_scale"), &AnimatedSprite::set_speed_scale); ClassDB::bind_method(D_METHOD("get_speed_scale"), &AnimatedSprite::get_speed_scale); - ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite::_res_changed); + ClassDB::bind_method(D_METHOD("set_specular_color", "color"), &AnimatedSprite::set_specular_color); + ClassDB::bind_method(D_METHOD("get_specular_color"), &AnimatedSprite::get_specular_color); + + ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &AnimatedSprite::set_shininess); + ClassDB::bind_method(D_METHOD("get_shininess"), &AnimatedSprite::get_shininess); ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("animation_finished")); + ADD_GROUP("Animation", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); + ADD_GROUP("Lighting", ""); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); + ADD_GROUP("Offset", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); @@ -736,4 +767,6 @@ AnimatedSprite::AnimatedSprite() { animation = "default"; timeout = 0; is_over = false; + specular_color = Color(1, 1, 1, 1); + shininess = 1.0; } diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index cd00a4e181..37d093e3d8 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -42,7 +42,7 @@ class SpriteFrames : public Resource { float speed; bool loop; - Vector<Ref<Texture> > frames; + Vector<Ref<Texture2D> > frames; Anim() { loop = true; @@ -50,8 +50,12 @@ class SpriteFrames : public Resource { } StringName normal_name; + StringName specular_name; }; + Color specular_color; + float shininess; + Map<StringName, Anim> animations; Array _get_frames() const; @@ -80,34 +84,48 @@ public: void set_animation_loop(const StringName &p_anim, bool p_loop); bool get_animation_loop(const StringName &p_anim) const; - void add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos = -1); + void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1); int get_frame_count(const StringName &p_anim) const; - _FORCE_INLINE_ Ref<Texture> get_frame(const StringName &p_anim, int p_idx) const { + _FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const { const Map<StringName, Anim>::Element *E = animations.find(p_anim); - ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist."); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>()); + ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist."); + ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); if (p_idx >= E->get().frames.size()) - return Ref<Texture>(); + return Ref<Texture2D>(); return E->get().frames[p_idx]; } - _FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const { + _FORCE_INLINE_ Ref<Texture2D> get_normal_frame(const StringName &p_anim, int p_idx) const { const Map<StringName, Anim>::Element *E = animations.find(p_anim); - ERR_FAIL_COND_V_MSG(!E, Ref<Texture>(), "Animation '" + String(p_anim) + "' doesn't exist."); - ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>()); + ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist."); + ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name); if (!EN || p_idx >= EN->get().frames.size()) - return Ref<Texture>(); + return Ref<Texture2D>(); + + return EN->get().frames[p_idx]; + } + + _FORCE_INLINE_ Ref<Texture2D> get_specular_frame(const StringName &p_anim, int p_idx) const { + + const Map<StringName, Anim>::Element *E = animations.find(p_anim); + ERR_FAIL_COND_V(!E, Ref<Texture2D>()); + ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>()); + + const Map<StringName, Anim>::Element *EN = animations.find(E->get().specular_name); + + if (!EN || p_idx >= EN->get().frames.size()) + return Ref<Texture2D>(); return EN->get().frames[p_idx]; } - void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture> &p_frame) { + void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture2D> &p_frame) { Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist."); ERR_FAIL_COND(p_idx < 0); @@ -150,6 +168,9 @@ class AnimatedSprite : public Node2D { bool _is_playing() const; Rect2 _get_rect() const; + Color specular_color; + float shininess; + protected: static void _bind_methods(); void _notification(int p_what); @@ -197,8 +218,11 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; - void set_modulate(const Color &p_color); - Color get_modulate() const; + void set_specular_color(const Color &p_color); + Color get_specular_color() const; + + void set_shininess(float p_shininess); + float get_shininess() const; virtual String get_configuration_warning() const; AnimatedSprite(); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 8302ba5336..b99c4c88bf 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "area_2d.h" + #include "scene/scene_string_names.h" #include "servers/audio_server.h" #include "servers/physics_2d_server.h" @@ -148,7 +149,7 @@ void Area2D::_body_exit_tree(ObjectID p_id) { } } -void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) { +void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) { bool body_in = p_status == Physics2DServer::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -171,8 +172,8 @@ void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_ E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -198,8 +199,8 @@ void Area2D::_body_inout(int p_status, const RID &p_body, int p_instance, int p_ if (E->get().rc == 0) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); if (E->get().in_tree) emit_signal(SceneStringNames::get_singleton()->body_exited, obj); } @@ -251,7 +252,7 @@ void Area2D::_area_exit_tree(ObjectID p_id) { } } -void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) { +void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) { bool area_in = p_status == Physics2DServer::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -273,8 +274,8 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->area_entered, node); } @@ -300,8 +301,8 @@ void Area2D::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ if (E->get().rc == 0) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); if (E->get().in_tree) emit_signal(SceneStringNames::get_singleton()->area_exited, obj); } @@ -333,12 +334,11 @@ void Area2D::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) //node may have been deleted in previous frame or at other legiminate point + if (!node) //node may have been deleted in previous frame or at other legitimate point continue; - //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree)); if (!E->get().in_tree) continue; @@ -363,12 +363,11 @@ void Area2D::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) //node may have been deleted in previous frame or at other legiminate point + if (!node) //node may have been deleted in previous frame or at other legitimate point continue; - //ERR_CONTINUE(!node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree)); if (!E->get().in_tree) continue; @@ -584,13 +583,6 @@ void Area2D::_validate_property(PropertyInfo &property) const { } void Area2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_body_enter_tree", "id"), &Area2D::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree", "id"), &Area2D::_body_exit_tree); - - ClassDB::bind_method(D_METHOD("_area_enter_tree", "id"), &Area2D::_area_enter_tree); - ClassDB::bind_method(D_METHOD("_area_exit_tree", "id"), &Area2D::_area_exit_tree); - ClassDB::bind_method(D_METHOD("set_space_override_mode", "space_override_mode"), &Area2D::set_space_override_mode); ClassDB::bind_method(D_METHOD("get_space_override_mode"), &Area2D::get_space_override_mode); @@ -660,11 +652,11 @@ void Area2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); @@ -674,7 +666,7 @@ void Area2D::_bind_methods() { ADD_GROUP("Audio Bus", "audio_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus_name", "get_audio_bus_name"); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_DISABLED); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 6d9386c535..c5e6635412 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -62,7 +62,7 @@ private: bool monitorable; bool locked; - void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape); + void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); @@ -94,7 +94,7 @@ private: Map<ObjectID, BodyState> body_map; - void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape); + void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape); void _area_enter_tree(ObjectID p_id); void _area_exit_tree(ObjectID p_id); diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 4f0f681a01..aa4ed233fb 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -512,17 +512,15 @@ void AudioStreamPlayer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer2D::get_stream_playback); - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer2D::_bus_layout_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "1,4096,1,or_greater"), "set_max_distance", "get_max_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "1,4096,1,or_greater"), "set_max_distance", "get_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); ADD_SIGNAL(MethodInfo("finished")); @@ -545,7 +543,7 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { stream_paused = false; stream_paused_fade_in = false; stream_paused_fade_out = false; - AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); + AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed)); } AudioStreamPlayer2D::~AudioStreamPlayer2D() { diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index e9f8c5dff2..a8860c3d81 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -128,9 +128,9 @@ Transform2D Camera2D::get_camera_transform() { } else { if (v_ofs < 0) { - camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; - } else { camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; + } else { + camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; } v_offset_changed = false; @@ -608,7 +608,7 @@ void Camera2D::set_custom_viewport(Node *p_viewport) { if (custom_viewport) { custom_viewport_id = custom_viewport->get_instance_id(); } else { - custom_viewport_id = 0; + custom_viewport_id = ObjectID(); } if (is_inside_tree()) { @@ -753,17 +753,17 @@ void Camera2D::_bind_methods() { ADD_GROUP("Smoothing", "smoothing_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smoothing_enabled"), "set_enable_follow_smoothing", "is_follow_smoothing_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothing_speed"), "set_follow_smoothing", "get_follow_smoothing"); ADD_GROUP("Offset", "offset_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_h", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset_v", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_v_offset", "get_v_offset"); ADD_GROUP("Drag Margin", "drag_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "drag_margin_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_left", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_top", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_right", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "drag_margin_bottom", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_margin", "get_drag_margin", MARGIN_BOTTOM); ADD_GROUP("Editor", "editor_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_screen"), "set_screen_drawing_enabled", "is_screen_drawing_enabled"); @@ -795,7 +795,7 @@ Camera2D::Camera2D() { smoothing_enabled = false; limit_smoothing_enabled = false; custom_viewport = NULL; - custom_viewport_id = 0; + process_mode = CAMERA2D_PROCESS_IDLE; smoothing = 5.0; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 5631aa3355..ef7aa9ba01 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -41,17 +41,13 @@ #include "servers/visual/visual_server_raster.h" #include "servers/visual_server.h" -Mutex *CanvasItemMaterial::material_mutex = NULL; +Mutex CanvasItemMaterial::material_mutex; SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL; Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL; void CanvasItemMaterial::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); shader_names = memnew(ShaderNames); @@ -66,10 +62,6 @@ void CanvasItemMaterial::finish_shaders() { memdelete(dirty_materials); memdelete(shader_names); dirty_materials = NULL; - -#ifndef NO_THREADS - memdelete(material_mutex); -#endif } void CanvasItemMaterial::_update_shader() { @@ -156,44 +148,28 @@ void CanvasItemMaterial::_update_shader() { void CanvasItemMaterial::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } void CanvasItemMaterial::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } bool CanvasItemMaterial::_is_shader_dirty() const { - bool dirty = false; - - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); - - if (material_mutex) - material_mutex->unlock(); + MutexLock lock(material_mutex); - return dirty; + return element.in_list(); } void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { @@ -332,8 +308,7 @@ CanvasItemMaterial::CanvasItemMaterial() : CanvasItemMaterial::~CanvasItemMaterial() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -345,9 +320,6 @@ CanvasItemMaterial::~CanvasItemMaterial() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } - - if (material_mutex) - material_mutex->unlock(); } /////////////////////////////////////////////////////////////////// @@ -572,6 +544,9 @@ void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + _update_texture_filter_changed(false); + _update_texture_repeat_changed(false); + first_draw = true; if (get_parent()) { CanvasItem *ci = Object::cast_to<CanvasItem>(get_parent()); @@ -717,30 +692,30 @@ void CanvasItem::item_rect_changed(bool p_size_changed) { emit_signal(SceneStringNames::get_singleton()->item_rect_changed); } -void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) { +void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); } -void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { +void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); Vector<Color> colors; colors.push_back(p_color); - VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, colors, p_width); } -void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { +void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width); } -void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width, bool p_antialiased) { +void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width) { Vector<Point2> points; points.resize(p_point_count); @@ -750,26 +725,26 @@ void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start points.set(i, p_center + Vector2(Math::cos(theta), Math::sin(theta)) * p_radius); } - draw_polyline(points, p_color, p_width, p_antialiased); + draw_polyline(points, p_color, p_width); } -void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) { +void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); Vector<Color> colors; colors.push_back(p_color); - VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width); } -void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) { +void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); - VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width); } -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) { +void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -778,10 +753,6 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); } - if (p_antialiased) { - WARN_PRINT("The draw_rect() \"antialiased\" argument has no effect when \"filled\" is \"true\"."); - } - VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color); } else { // Thick lines are offset depending on their width to avoid partial overlapping. @@ -798,29 +769,25 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil p_rect.position + Size2(-offset, 0), p_rect.position + Size2(p_rect.size.width + offset, 0), p_color, - p_width, - p_antialiased); + p_width); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, p_rect.position + Size2(p_rect.size.width, offset), p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), p_color, - p_width, - p_antialiased); + p_width); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), p_rect.position + Size2(-offset, p_rect.size.height), p_color, - p_width, - p_antialiased); + p_width); VisualServer::get_singleton()->canvas_item_add_line( canvas_item, p_rect.position + Size2(0, p_rect.size.height - offset), p_rect.position + Size2(0, offset), p_color, - p_width, - p_antialiased); + p_width); } } @@ -831,27 +798,27 @@ void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); } -void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) { +void CanvasItem::draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw(canvas_item, p_pos, p_modulate, false, p_normal_map); + p_texture->draw(canvas_item, p_pos, p_modulate, false, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } -void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) { +void CanvasItem::draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map); + p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } -void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) { +void CanvasItem::draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv); + p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat), p_clip_uv); } void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) { @@ -861,14 +828,15 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p p_style_box->draw(canvas_item, p_rect); } -void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) { +void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, float p_width, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal); + VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) { @@ -886,17 +854,18 @@ void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) { VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix); } -void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) { +void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } -void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map, bool p_antialiased) { +void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -904,24 +873,28 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo colors.push_back(p_color); RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + RID rid_specular = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased); + VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, rid_specular, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } -void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform, const Color &p_modulate) { +void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, const Transform2D &p_transform, const Color &p_modulate, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND(p_mesh.is_null()); RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + RID specular_map_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid); + VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid, specular_map_rid, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } -void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) { +void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) { ERR_FAIL_COND(p_multimesh.is_null()); RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid, normal_map_rid); + RID specular_map_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + + VisualServer::get_singleton()->canvas_item_add_multimesh(canvas_item, p_multimesh->get_rid(), texture_rid, normal_map_rid, specular_map_rid, p_specular_color_shininess, VS::CanvasItemTextureFilter(p_texture_filter), VS::CanvasItemTextureRepeat(p_texture_repeat)); } void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) { @@ -996,7 +969,7 @@ ObjectID CanvasItem::get_canvas_layer_instance_id() const { if (canvas_layer) { return canvas_layer->get_instance_id(); } else { - return 0; + return ObjectID(); } } @@ -1170,25 +1143,25 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_is_on_top"), &CanvasItem::_is_on_top); //ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform); - ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width"), &CanvasItem::draw_polyline, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width"), &CanvasItem::draw_arc, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width"), &CanvasItem::draw_multiline, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); - ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "specular_shininess", "clip_uv", "texture_filter", "texture_repeat"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(true), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); ClassDB::bind_method(D_METHOD("draw_style_box", "style_box", "rect"), &CanvasItem::draw_style_box); - ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width", "normal_map"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "transform", "modulate"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture>())); + ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture", "width", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_colored_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1, 1))); + ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "specular_map", "specular_shininess", "transform", "modulate", "texture_filter", "texture_repeat"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); + ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture", "normal_map", "specular_map", "specular_shininess", "texture_filter", "texture_repeat"), &CanvasItem::draw_multimesh, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(TEXTURE_FILTER_PARENT_NODE), DEFVAL(TEXTURE_REPEAT_PARENT_NODE)); ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform); ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix); @@ -1221,6 +1194,12 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local); ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local); + ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &CanvasItem::set_texture_filter); + ClassDB::bind_method(D_METHOD("get_texture_filter"), &CanvasItem::get_texture_filter); + + ClassDB::bind_method(D_METHOD("set_texture_repeat", "mode"), &CanvasItem::set_texture_repeat); + ClassDB::bind_method(D_METHOD("get_texture_repeat"), &CanvasItem::get_texture_repeat); + BIND_VMETHOD(MethodInfo("_draw")); ADD_GROUP("Visibility", ""); @@ -1231,6 +1210,10 @@ void CanvasItem::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_on_top", PROPERTY_HINT_NONE, "", 0), "_set_on_top", "_is_on_top"); //compatibility ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_light_mask", "get_light_mask"); + ADD_GROUP("Texture", "texture_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "ParentNode,Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "ParentNode,Disabled,Enabled,Mirror"), "set_texture_repeat", "get_texture_repeat"); + ADD_GROUP("Material", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial"), "set_material", "get_material"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_parent_material"), "set_use_parent_material", "get_use_parent_material"); @@ -1243,18 +1226,26 @@ void CanvasItem::_bind_methods() { ADD_SIGNAL(MethodInfo("hide")); ADD_SIGNAL(MethodInfo("item_rect_changed")); - BIND_ENUM_CONSTANT(BLEND_MODE_MIX); - BIND_ENUM_CONSTANT(BLEND_MODE_ADD); - BIND_ENUM_CONSTANT(BLEND_MODE_SUB); - BIND_ENUM_CONSTANT(BLEND_MODE_MUL); - BIND_ENUM_CONSTANT(BLEND_MODE_PREMULT_ALPHA); - BIND_ENUM_CONSTANT(BLEND_MODE_DISABLED); - BIND_CONSTANT(NOTIFICATION_TRANSFORM_CHANGED); BIND_CONSTANT(NOTIFICATION_DRAW); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS); BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS); + + BIND_ENUM_CONSTANT(TEXTURE_FILTER_PARENT_NODE); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX); + + BIND_ENUM_CONSTANT(TEXTURE_REPEAT_PARENT_NODE); + BIND_ENUM_CONSTANT(TEXTURE_REPEAT_DISABLED); + BIND_ENUM_CONSTANT(TEXTURE_REPEAT_ENABLED); + BIND_ENUM_CONSTANT(TEXTURE_REPEAT_MIRROR); + BIND_ENUM_CONSTANT(TEXTURE_REPEAT_MAX); } Transform2D CanvasItem::get_canvas_transform() const { @@ -1318,6 +1309,102 @@ int CanvasItem::get_canvas_layer() const { return 0; } +void CanvasItem::_update_texture_filter_changed(bool p_propagate) { + + if (!is_inside_tree()) { + return; + } + + if (texture_filter == TEXTURE_FILTER_PARENT_NODE) { + CanvasItem *parent_item = get_parent_item(); + if (parent_item) { + texture_filter_cache = parent_item->texture_filter_cache; + } else { + //from viewport + switch (get_viewport()->get_default_canvas_item_texture_filter()) { + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST; break; + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; break; + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; break; + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; break; + default: { + } + } + } + } else { + texture_filter_cache = VS::CanvasItemTextureFilter(texture_filter); + } + VS::get_singleton()->canvas_item_set_default_texture_filter(get_canvas_item(), texture_filter_cache); + update(); + + if (p_propagate) { + for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) { + if (!E->get()->toplevel && E->get()->texture_filter == TEXTURE_FILTER_PARENT_NODE) { + E->get()->_update_texture_filter_changed(true); + } + } + } +} + +void CanvasItem::set_texture_filter(TextureFilter p_texture_filter) { + ERR_FAIL_INDEX(p_texture_filter, TEXTURE_FILTER_MAX); + if (texture_filter == p_texture_filter) { + return; + } + texture_filter = p_texture_filter; + _update_texture_filter_changed(true); +} + +CanvasItem::TextureFilter CanvasItem::get_texture_filter() const { + return texture_filter; +} + +void CanvasItem::_update_texture_repeat_changed(bool p_propagate) { + + if (!is_inside_tree()) { + return; + } + + if (texture_repeat == TEXTURE_REPEAT_PARENT_NODE) { + CanvasItem *parent_item = get_parent_item(); + if (parent_item) { + texture_repeat_cache = parent_item->texture_repeat_cache; + } else { + //from viewport + switch (get_viewport()->get_default_canvas_item_texture_repeat()) { + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; break; + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED; break; + case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR; break; + default: { + } + } + } + } else { + texture_repeat_cache = VS::CanvasItemTextureRepeat(texture_repeat); + } + VS::get_singleton()->canvas_item_set_default_texture_repeat(get_canvas_item(), texture_repeat_cache); + update(); + if (p_propagate) { + for (List<CanvasItem *>::Element *E = children_items.front(); E; E = E->next()) { + if (!E->get()->toplevel && E->get()->texture_repeat == TEXTURE_REPEAT_PARENT_NODE) { + E->get()->_update_texture_repeat_changed(true); + } + } + } +} + +void CanvasItem::set_texture_repeat(TextureRepeat p_texture_repeat) { + ERR_FAIL_INDEX(p_texture_repeat, TEXTURE_REPEAT_MAX); + if (texture_repeat == p_texture_repeat) { + return; + } + texture_repeat = p_texture_repeat; + _update_texture_repeat_changed(true); +} + +CanvasItem::TextureRepeat CanvasItem::get_texture_repeat() const { + return texture_repeat; +} + CanvasItem::CanvasItem() : xform_change(this) { @@ -1338,6 +1425,10 @@ CanvasItem::CanvasItem() : notify_local_transform = false; notify_transform = false; light_mask = 1; + texture_repeat = TEXTURE_REPEAT_PARENT_NODE; + texture_filter = TEXTURE_FILTER_PARENT_NODE; + texture_filter_cache = VS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; + texture_repeat_cache = VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; C = NULL; } diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 8814d99edd..c7f9500ea1 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -108,7 +108,7 @@ private: return mk; } - static Mutex *material_mutex; + static Mutex material_mutex; static SelfList<CanvasItemMaterial>::List *dirty_materials; SelfList<CanvasItemMaterial> element; @@ -166,14 +166,23 @@ class CanvasItem : public Node { GDCLASS(CanvasItem, Node); public: - enum BlendMode { + enum TextureFilter { + TEXTURE_FILTER_PARENT_NODE, + TEXTURE_FILTER_NEAREST, + TEXTURE_FILTER_LINEAR, + TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, + TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, + TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, + TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, + TEXTURE_FILTER_MAX + }; - BLEND_MODE_MIX, //default - BLEND_MODE_ADD, - BLEND_MODE_SUB, - BLEND_MODE_MUL, - BLEND_MODE_PREMULT_ALPHA, - BLEND_MODE_DISABLED + enum TextureRepeat { + TEXTURE_REPEAT_PARENT_NODE, + TEXTURE_REPEAT_DISABLED, + TEXTURE_REPEAT_ENABLED, + TEXTURE_REPEAT_MIRROR, + TEXTURE_REPEAT_MAX, }; private: @@ -203,6 +212,12 @@ private: bool notify_local_transform; bool notify_transform; + VS::CanvasItemTextureFilter texture_filter_cache; + VS::CanvasItemTextureRepeat texture_repeat_cache; + + TextureFilter texture_filter; + TextureRepeat texture_repeat; + Ref<Material> material; mutable Transform2D global_transform; @@ -223,6 +238,9 @@ private: bool _is_on_top() const { return !is_draw_behind_parent_enabled(); } static CanvasItem *current_item_drawn; + friend class Viewport; + void _update_texture_repeat_changed(bool p_propagate); + void _update_texture_filter_changed(bool p_propagate); protected: _FORCE_INLINE_ void _notify_transform() { @@ -305,24 +323,24 @@ public: /* DRAWING API */ - void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); - void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); + void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0); + void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0); + void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0); + void draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width = 1.0); + void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0); + void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0); + void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); - void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = false); + void draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); + void draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); + void draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), bool p_clip_uv = false, TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect); - void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1, const Ref<Texture> &p_normal_map = Ref<Texture>()); - void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); - void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false); + void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture = Ref<Texture2D>(), float p_width = 1, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); + void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>(), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); + void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture2D> p_texture = Ref<Texture2D>(), const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); - void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1)); - void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map); + void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); + void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), TextureFilter p_texture_filter = TEXTURE_FILTER_PARENT_NODE, TextureRepeat p_texture_repeat = TEXTURE_REPEAT_PARENT_NODE); void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1); float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1)); @@ -383,6 +401,12 @@ public: void force_update_transform(); + void set_texture_filter(TextureFilter p_texture_filter); + TextureFilter get_texture_filter() const; + + void set_texture_repeat(TextureRepeat p_texture_repeat); + TextureRepeat get_texture_repeat() const; + // Used by control nodes to retrieve the parent's anchorable area virtual Rect2 get_anchorable_rect() const { return Rect2(0, 0, 0, 0); }; @@ -392,6 +416,7 @@ public: ~CanvasItem(); }; -VARIANT_ENUM_CAST(CanvasItem::BlendMode); +VARIANT_ENUM_CAST(CanvasItem::TextureFilter) +VARIANT_ENUM_CAST(CanvasItem::TextureRepeat) #endif // CANVAS_ITEM_H diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 3e9e63a7f0..4af2e846f7 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -95,9 +95,9 @@ void CollisionObject2D::_notification(int p_what) { case NOTIFICATION_EXIT_CANVAS: { if (area) - Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, 0); + Physics2DServer::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID()); else - Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, 0); + Physics2DServer::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID()); } break; } } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index d9cc94c6eb..4edf92197e 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -61,16 +61,15 @@ void CollisionPolygon2D::_build_polygon() { Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D); - PoolVector<Vector2> segments; + Vector<Vector2> segments; segments.resize(polygon.size() * 2); - PoolVector<Vector2>::Write w = segments.write(); + Vector2 *w = segments.ptrw(); for (int i = 0; i < polygon.size(); i++) { w[(i << 1) + 0] = polygon[i]; w[(i << 1) + 1] = polygon[(i + 1) % polygon.size()]; } - w.release(); concave->set_segments(segments); parent->shape_owner_add_shape(owner_id, concave); @@ -306,10 +305,10 @@ void CollisionPolygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionPolygon2D::get_one_way_collision_margin); ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Segments"), "set_build_mode", "get_build_mode"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); BIND_ENUM_CONSTANT(BUILD_SOLIDS); BIND_ENUM_CONSTANT(BUILD_SEGMENTS); diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index eace4c64fc..b2ad040654 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -130,7 +130,7 @@ void CollisionShape2D::_notification(int p_what) { draw_col = draw_col.darkened(0.25); } Vector2 line_to(0, 20); - draw_line(Vector2(), line_to, draw_col, 2, true); + draw_line(Vector2(), line_to, draw_col, 2); Vector<Vector2> pts; float tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); @@ -149,7 +149,7 @@ void CollisionShape2D::_notification(int p_what) { void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { if (shape.is_valid()) - shape->disconnect("changed", this, "_shape_changed"); + shape->disconnect("changed", callable_mp(this, &CollisionShape2D::_shape_changed)); shape = p_shape; update(); if (parent) { @@ -160,7 +160,7 @@ void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) { } if (shape.is_valid()) - shape->connect("changed", this, "_shape_changed"); + shape->connect("changed", callable_mp(this, &CollisionShape2D::_shape_changed)); update_configuration_warning(); } @@ -237,12 +237,11 @@ void CollisionShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionShape2D::is_one_way_collision_enabled); ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionShape2D::set_one_way_collision_margin); ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionShape2D::get_one_way_collision_margin); - ClassDB::bind_method(D_METHOD("_shape_changed"), &CollisionShape2D::_shape_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision"), "set_one_way_collision", "is_one_way_collision_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1"), "set_one_way_collision_margin", "get_one_way_collision_margin"); } CollisionShape2D::CollisionShape2D() { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index acb1b0b5a0..3b8a81d2ca 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "cpu_particles_2d.h" + #include "core/core_string_names.h" #include "scene/2d/canvas_item.h" #include "scene/2d/particles_2d.h" @@ -51,15 +52,15 @@ void CPUParticles2D::set_amount(int p_amount) { particles.resize(p_amount); { - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < p_amount; i++) { w[i].active = false; } } - particle_data.resize((8 + 4 + 1) * p_amount); - VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT); + particle_data.resize((8 + 4 + 4) * p_amount); + VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_2D, true, true); particle_order.resize(p_amount); } @@ -163,12 +164,12 @@ void CPUParticles2D::_update_mesh_texture() { } else { tex_size = Size2(1, 1); } - PoolVector<Vector2> vertices; + Vector<Vector2> vertices; vertices.push_back(-tex_size * 0.5); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0)); vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y)); vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); - PoolVector<Vector2> uvs; + Vector<Vector2> uvs; AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture); if (atlas_texure && atlas_texure->get_atlas().is_valid()) { Rect2 region_rect = atlas_texure->get_region(); @@ -183,12 +184,12 @@ void CPUParticles2D::_update_mesh_texture() { uvs.push_back(Vector2(1, 1)); uvs.push_back(Vector2(0, 1)); } - PoolVector<Color> colors; + Vector<Color> colors; colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); - PoolVector<int> indices; + Vector<int> indices; indices.push_back(0); indices.push_back(1); indices.push_back(2); @@ -207,17 +208,17 @@ void CPUParticles2D::_update_mesh_texture() { VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr); } -void CPUParticles2D::set_texture(const Ref<Texture> &p_texture) { +void CPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) { if (p_texture == texture) return; if (texture.is_valid()) - texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); texture = p_texture; if (texture.is_valid()) - texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed)); update(); _update_mesh_texture(); @@ -231,18 +232,18 @@ void CPUParticles2D::_texture_changed() { } } -Ref<Texture> CPUParticles2D::get_texture() const { +Ref<Texture2D> CPUParticles2D::get_texture() const { return texture; } -void CPUParticles2D::set_normalmap(const Ref<Texture> &p_normalmap) { +void CPUParticles2D::set_normalmap(const Ref<Texture2D> &p_normalmap) { normalmap = p_normalmap; update(); } -Ref<Texture> CPUParticles2D::get_normalmap() const { +Ref<Texture2D> CPUParticles2D::get_normalmap() const { return normalmap; } @@ -291,7 +292,7 @@ void CPUParticles2D::restart() { { int pc = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < pc; i++) { w[i].active = false; @@ -455,17 +456,17 @@ void CPUParticles2D::set_emission_rect_extents(Vector2 p_extents) { emission_rect_extents = p_extents; } -void CPUParticles2D::set_emission_points(const PoolVector<Vector2> &p_points) { +void CPUParticles2D::set_emission_points(const Vector<Vector2> &p_points) { emission_points = p_points; } -void CPUParticles2D::set_emission_normals(const PoolVector<Vector2> &p_normals) { +void CPUParticles2D::set_emission_normals(const Vector<Vector2> &p_normals) { emission_normals = p_normals; } -void CPUParticles2D::set_emission_colors(const PoolVector<Color> &p_colors) { +void CPUParticles2D::set_emission_colors(const Vector<Color> &p_colors) { emission_colors = p_colors; } @@ -478,16 +479,16 @@ Vector2 CPUParticles2D::get_emission_rect_extents() const { return emission_rect_extents; } -PoolVector<Vector2> CPUParticles2D::get_emission_points() const { +Vector<Vector2> CPUParticles2D::get_emission_points() const { return emission_points; } -PoolVector<Vector2> CPUParticles2D::get_emission_normals() const { +Vector<Vector2> CPUParticles2D::get_emission_normals() const { return emission_normals; } -PoolVector<Color> CPUParticles2D::get_emission_colors() const { +Vector<Color> CPUParticles2D::get_emission_colors() const { return emission_colors; } @@ -630,9 +631,9 @@ void CPUParticles2D::_particles_process(float p_delta) { p_delta *= speed_scale; int pcount = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); - Particle *parray = w.ptr(); + Particle *parray = w; float prev_time = time; time += p_delta; @@ -970,118 +971,103 @@ void CPUParticles2D::_particles_process(float p_delta) { } void CPUParticles2D::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { + int pc = particles.size(); - int pc = particles.size(); + int *ow; + int *order = NULL; - PoolVector<int>::Write ow; - int *order = NULL; + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.write(); - order = ow.ptr(); - - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; - sorter.compare.particles = r.ptr(); - sorter.sort(order, pc); - } + for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); } + } - for (int i = 0; i < pc; i++) { + for (int i = 0; i < pc; i++) { - int idx = order ? order[i] : i; + int idx = order ? order[i] : i; - Transform2D t = r[idx].transform; + Transform2D t = r[idx].transform; - if (!local_coords) { - t = inv_emission_transform * t; - } + if (!local_coords) { + t = inv_emission_transform * t; + } - if (r[idx].active) { + if (r[idx].active) { - ptr[0] = t.elements[0][0]; - ptr[1] = t.elements[1][0]; - ptr[2] = 0; - ptr[3] = t.elements[2][0]; - ptr[4] = t.elements[0][1]; - ptr[5] = t.elements[1][1]; - ptr[6] = 0; - ptr[7] = t.elements[2][1]; + ptr[0] = t.elements[0][0]; + ptr[1] = t.elements[1][0]; + ptr[2] = 0; + ptr[3] = t.elements[2][0]; + ptr[4] = t.elements[0][1]; + ptr[5] = t.elements[1][1]; + ptr[6] = 0; + ptr[7] = t.elements[2][1]; - } else { - zeromem(ptr, sizeof(float) * 8); - } + } else { + zeromem(ptr, sizeof(float) * 8); + } - Color c = r[idx].color; - uint8_t *data8 = (uint8_t *)&ptr[8]; - data8[0] = CLAMP(c.r * 255.0, 0, 255); - data8[1] = CLAMP(c.g * 255.0, 0, 255); - data8[2] = CLAMP(c.b * 255.0, 0, 255); - data8[3] = CLAMP(c.a * 255.0, 0, 255); + Color c = r[idx].color; - ptr[9] = r[idx].custom[0]; - ptr[10] = r[idx].custom[1]; - ptr[11] = r[idx].custom[2]; - ptr[12] = r[idx].custom[3]; + ptr[8] = c.r; + ptr[9] = c.g; + ptr[10] = c.b; + ptr[11] = c.a; - ptr += 13; - } - } + ptr[12] = r[idx].custom[0]; + ptr[13] = r[idx].custom[1]; + ptr[14] = r[idx].custom[2]; + ptr[15] = r[idx].custom[3]; -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + ptr += 16; + } } void CPUParticles2D::_set_redraw(bool p_redraw) { if (redraw == p_redraw) return; redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); - - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); - } - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + { + MutexLock lock(update_mutex); + + if (redraw) { + VS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread)); + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (VS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread))) { + VS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &CPUParticles2D::_update_render_thread)); + } + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + } } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + update(); // redraw to update render list } void CPUParticles2D::_update_render_thread() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); } void CPUParticles2D::_notification(int p_what) { @@ -1127,9 +1113,9 @@ void CPUParticles2D::_notification(int p_what) { int pc = particles.size(); - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; for (int i = 0; i < pc; i++) { @@ -1150,7 +1136,7 @@ void CPUParticles2D::_notification(int p_what) { zeromem(ptr, sizeof(float) * 8); } - ptr += 13; + ptr += 16; } } } @@ -1273,21 +1259,21 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); // No visibility_rect property contrarily to Particles2D, it's updated automatically. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normalmap", "get_normalmap"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normalmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normalmap", "get_normalmap"); BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); @@ -1341,72 +1327,69 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles); - ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles2D::_update_render_thread); - ClassDB::bind_method(D_METHOD("_texture_changed"), &CPUParticles2D::_texture_changed); - ADD_GROUP("Emission Shape", "emission_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents"), "set_emission_rect_extents", "get_emission_rect_extents"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); @@ -1494,18 +1477,10 @@ CPUParticles2D::CPUParticles2D() { set_color(Color(1, 1, 1, 1)); -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif - _update_mesh_texture(); } CPUParticles2D::~CPUParticles2D() { VS::get_singleton()->free(multimesh); VS::get_singleton()->free(mesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif } diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index d59b94bcbb..18d0caceed 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -108,9 +108,9 @@ private: RID mesh; RID multimesh; - PoolVector<Particle> particles; - PoolVector<float> particle_data; - PoolVector<int> particle_order; + Vector<Particle> particles; + Vector<float> particle_data; + Vector<int> particle_order; struct SortLifetime { const Particle *particles; @@ -147,8 +147,8 @@ private: DrawOrder draw_order; - Ref<Texture> texture; - Ref<Texture> normalmap; + Ref<Texture2D> texture; + Ref<Texture2D> normalmap; //////// @@ -167,9 +167,9 @@ private: EmissionShape emission_shape; float emission_sphere_radius; Vector2 emission_rect_extents; - PoolVector<Vector2> emission_points; - PoolVector<Vector2> emission_normals; - PoolVector<Color> emission_colors; + Vector<Vector2> emission_points; + Vector<Vector2> emission_normals; + Vector<Color> emission_colors; int emission_point_count; Vector2 gravity; @@ -178,7 +178,7 @@ private: void _particles_process(float p_delta); void _update_particle_data_buffer(); - Mutex *update_mutex; + Mutex update_mutex; void _update_render_thread(); @@ -230,11 +230,11 @@ public: void set_draw_passes(int p_count); int get_draw_passes() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normalmap(const Ref<Texture> &p_normalmap); - Ref<Texture> get_normalmap() const; + void set_normalmap(const Ref<Texture2D> &p_normalmap); + Ref<Texture2D> get_normalmap() const; /////////////////// @@ -265,17 +265,17 @@ public: void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); void set_emission_rect_extents(Vector2 p_extents); - void set_emission_points(const PoolVector<Vector2> &p_points); - void set_emission_normals(const PoolVector<Vector2> &p_normals); - void set_emission_colors(const PoolVector<Color> &p_colors); + void set_emission_points(const Vector<Vector2> &p_points); + void set_emission_normals(const Vector<Vector2> &p_normals); + void set_emission_colors(const Vector<Color> &p_colors); void set_emission_point_count(int p_count); EmissionShape get_emission_shape() const; float get_emission_sphere_radius() const; Vector2 get_emission_rect_extents() const; - PoolVector<Vector2> get_emission_points() const; - PoolVector<Vector2> get_emission_normals() const; - PoolVector<Color> get_emission_colors() const; + Vector<Vector2> get_emission_points() const; + Vector<Vector2> get_emission_normals() const; + Vector<Color> get_emission_colors() const; int get_emission_point_count() const; void set_gravity(const Vector2 &p_gravity); diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp index 656ff45654..9cc9ab25ac 100644 --- a/scene/2d/joints_2d.cpp +++ b/scene/2d/joints_2d.cpp @@ -158,7 +158,7 @@ void Joint2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision"); } @@ -215,7 +215,7 @@ void PinJoint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_softness", "softness"), &PinJoint2D::set_softness); ClassDB::bind_method(D_METHOD("get_softness"), &PinJoint2D::get_softness); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "softness", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_softness", "get_softness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "softness", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_softness", "get_softness"); } PinJoint2D::PinJoint2D() { @@ -285,8 +285,8 @@ void GrooveJoint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_initial_offset", "offset"), &GrooveJoint2D::set_initial_offset); ClassDB::bind_method(D_METHOD("get_initial_offset"), &GrooveJoint2D::get_initial_offset); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "initial_offset", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_initial_offset", "get_initial_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "initial_offset", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_initial_offset", "get_initial_offset"); } GrooveJoint2D::GrooveJoint2D() { @@ -394,10 +394,10 @@ void DampedSpringJoint2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_damping", "damping"), &DampedSpringJoint2D::set_damping); ClassDB::bind_method(D_METHOD("get_damping"), &DampedSpringJoint2D::get_damping); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rest_length", PROPERTY_HINT_EXP_RANGE, "0,65535,1"), "set_rest_length", "get_rest_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "stiffness", PROPERTY_HINT_EXP_RANGE, "0.1,64,0.1"), "set_stiffness", "get_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_EXP_RANGE, "0.01,16,0.01"), "set_damping", "get_damping"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_EXP_RANGE, "1,65535,1"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rest_length", PROPERTY_HINT_EXP_RANGE, "0,65535,1"), "set_rest_length", "get_rest_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stiffness", PROPERTY_HINT_EXP_RANGE, "0.1,64,0.1"), "set_stiffness", "get_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_EXP_RANGE, "0.01,16,0.01"), "set_damping", "get_damping"); } DampedSpringJoint2D::DampedSpringJoint2D() { diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 1bffaf8084..e61b1fa339 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -125,7 +125,7 @@ bool Light2D::is_editor_only() const { return editor_only; } -void Light2D::set_texture(const Ref<Texture> &p_texture) { +void Light2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; if (texture.is_valid()) @@ -136,7 +136,7 @@ void Light2D::set_texture(const Ref<Texture> &p_texture) { update_configuration_warning(); } -Ref<Texture> Light2D::get_texture() const { +Ref<Texture2D> Light2D::get_texture() const { return texture; } @@ -296,18 +296,8 @@ int Light2D::get_shadow_buffer_size() const { return shadow_buffer_size; } -void Light2D::set_shadow_gradient_length(float p_multiplier) { - - shadow_gradient_length = p_multiplier; - VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light, p_multiplier); -} - -float Light2D::get_shadow_gradient_length() const { - - return shadow_gradient_length; -} - void Light2D::set_shadow_filter(ShadowFilter p_filter) { + ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX); shadow_filter = p_filter; VS::get_singleton()->canvas_light_set_shadow_filter(canvas_light, VS::CanvasLightShadowFilter(p_filter)); } @@ -426,9 +416,6 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth); ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth); - ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length); - ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length); - ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter); ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter); @@ -437,14 +424,14 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix,Mask"), "set_mode", "get_mode"); ADD_GROUP("Range", "range_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "range_height", PROPERTY_HINT_RANGE, "-2048,2048,0.1,or_lesser,or_greater"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_height", PROPERTY_HINT_RANGE, "-2048,2048,0.1,or_lesser,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_min", PROPERTY_HINT_RANGE, "-512,512,1"), "set_layer_range_min", "get_layer_range_min"); @@ -455,9 +442,8 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF7,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); BIND_ENUM_CONSTANT(MODE_ADD); @@ -466,10 +452,7 @@ void Light2D::_bind_methods() { BIND_ENUM_CONSTANT(MODE_MASK); BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF3); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF7); - BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF9); BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13); } @@ -490,7 +473,6 @@ Light2D::Light2D() { item_shadow_mask = 1; mode = MODE_ADD; shadow_buffer_size = 2048; - shadow_gradient_length = 0; energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 65db5c6ee6..7134029441 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -47,11 +47,9 @@ public: enum ShadowFilter { SHADOW_FILTER_NONE, - SHADOW_FILTER_PCF3, SHADOW_FILTER_PCF5, - SHADOW_FILTER_PCF7, - SHADOW_FILTER_PCF9, SHADOW_FILTER_PCF13, + SHADOW_FILTER_MAX }; private: @@ -72,9 +70,8 @@ private: int item_shadow_mask; int shadow_buffer_size; float shadow_smooth; - float shadow_gradient_length; Mode mode; - Ref<Texture> texture; + Ref<Texture2D> texture; Vector2 texture_offset; ShadowFilter shadow_filter; @@ -104,8 +101,8 @@ public: void set_editor_only(bool p_editor_only); bool is_editor_only() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; void set_texture_offset(const Vector2 &p_offset); Vector2 get_texture_offset() const; @@ -149,9 +146,6 @@ public: void set_shadow_buffer_size(int p_size); int get_shadow_buffer_size() const; - void set_shadow_gradient_length(float p_multiplier); - float get_shadow_gradient_length() const; - void set_shadow_filter(ShadowFilter p_filter); ShadowFilter get_shadow_filter() const; diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 0e8e8f6679..d4a5c93823 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -39,7 +39,7 @@ Rect2 OccluderPolygon2D::_edit_get_rect() const { if (rect_cache_dirty) { if (closed) { - PoolVector<Vector2>::Read r = polygon.read(); + const Vector2 *r = polygon.ptr(); item_rect = Rect2(); for (int i = 0; i < polygon.size(); i++) { Vector2 pos = r[i]; @@ -72,7 +72,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double return Geometry::is_point_in_polygon(p_point, Variant(polygon)); } else { const real_t d = LINE_GRAB_WIDTH / 2 + p_tolerance; - PoolVector<Vector2>::Read points = polygon.read(); + const Vector2 *points = polygon.ptr(); for (int i = 0; i < polygon.size() - 1; i++) { Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]); if (p.distance_to(p_point) <= d) @@ -84,7 +84,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double } #endif -void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { +void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) { polygon = p_polygon; rect_cache_dirty = true; @@ -92,7 +92,7 @@ void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { emit_changed(); } -PoolVector<Vector2> OccluderPolygon2D::get_polygon() const { +Vector<Vector2> OccluderPolygon2D::get_polygon() const { return polygon; } @@ -141,7 +141,7 @@ void OccluderPolygon2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "closed"), "set_closed", "is_closed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Disabled,ClockWise,CounterClockWise"), "set_cull_mode", "get_cull_mode"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); BIND_ENUM_CONSTANT(CULL_DISABLED); BIND_ENUM_CONSTANT(CULL_CLOCKWISE); @@ -191,7 +191,7 @@ void LightOccluder2D::_notification(int p_what) { if (occluder_polygon.is_valid()) { - PoolVector<Vector2> poly = occluder_polygon->get_polygon(); + Vector<Vector2> poly = occluder_polygon->get_polygon(); if (poly.size()) { if (occluder_polygon->is_closed()) { @@ -201,7 +201,7 @@ void LightOccluder2D::_notification(int p_what) { } else { int ps = poly.size(); - PoolVector<Vector2>::Read r = poly.read(); + const Vector2 *r = poly.ptr(); for (int i = 0; i < ps - 1; i++) { draw_line(r[i], r[i + 1], Color(0, 0, 0, 0.6), 3); @@ -234,7 +234,7 @@ void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polyg #ifdef DEBUG_ENABLED if (occluder_polygon.is_valid()) - occluder_polygon->disconnect("changed", this, "_poly_changed"); + occluder_polygon->disconnect("changed", callable_mp(this, &LightOccluder2D::_poly_changed)); #endif occluder_polygon = p_polygon; @@ -245,7 +245,7 @@ void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polyg #ifdef DEBUG_ENABLED if (occluder_polygon.is_valid()) - occluder_polygon->connect("changed", this, "_poly_changed"); + occluder_polygon->connect("changed", callable_mp(this, &LightOccluder2D::_poly_changed)); update(); #endif } @@ -287,8 +287,6 @@ void LightOccluder2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_occluder_light_mask", "mask"), &LightOccluder2D::set_occluder_light_mask); ClassDB::bind_method(D_METHOD("get_occluder_light_mask"), &LightOccluder2D::get_occluder_light_mask); - ClassDB::bind_method("_poly_changed", &LightOccluder2D::_poly_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "occluder", PROPERTY_HINT_RESOURCE_TYPE, "OccluderPolygon2D"), "set_occluder_polygon", "get_occluder_polygon"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_occluder_light_mask", "get_occluder_light_mask"); } diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index b20e347c35..83702f2875 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -46,7 +46,7 @@ public: private: RID occ_polygon; - PoolVector<Vector2> polygon; + Vector<Vector2> polygon; bool closed; CullMode cull; @@ -62,8 +62,8 @@ public: virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; #endif - void set_polygon(const PoolVector<Vector2> &p_polygon); - PoolVector<Vector2> get_polygon() const; + void set_polygon(const Vector<Vector2> &p_polygon); + Vector<Vector2> get_polygon() const; void set_closed(bool p_closed); bool is_closed() const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index c31840c8e1..873c901c0a 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ #include "line_2d.h" -#include "line_builder.h" #include "core/core_string_names.h" +#include "line_builder.h" // Needed so we can bind functions VARIANT_ENUM_CAST(Line2D::LineJointMode) @@ -71,7 +71,7 @@ bool Line2D::_edit_use_rect() const { bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { const real_t d = _width / 2 + p_tolerance; - PoolVector<Vector2>::Read points = _points.read(); + const Vector2 *points = _points.ptr(); for (int i = 0; i < _points.size() - 1; i++) { Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]); if (p.distance_to(p_point) <= d) @@ -82,7 +82,7 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc } #endif -void Line2D::set_points(const PoolVector<Vector2> &p_points) { +void Line2D::set_points(const Vector<Vector2> &p_points) { _points = p_points; update(); } @@ -101,14 +101,14 @@ float Line2D::get_width() const { void Line2D::set_curve(const Ref<Curve> &p_curve) { // Cleanup previous connection if any if (_curve.is_valid()) { - _curve->disconnect(CoreStringNames::get_singleton()->changed, this, "_curve_changed"); + _curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_curve_changed)); } _curve = p_curve; // Connect to the curve so the line will update when it is changed if (_curve.is_valid()) { - _curve->connect(CoreStringNames::get_singleton()->changed, this, "_curve_changed"); + _curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_curve_changed)); } update(); @@ -118,7 +118,7 @@ Ref<Curve> Line2D::get_curve() const { return _curve; } -PoolVector<Vector2> Line2D::get_points() const { +Vector<Vector2> Line2D::get_points() const { return _points; } @@ -146,7 +146,7 @@ void Line2D::clear_points() { void Line2D::add_point(Vector2 p_pos, int p_atpos) { if (p_atpos < 0 || _points.size() < p_atpos) { - _points.append(p_pos); + _points.push_back(p_pos); } else { _points.insert(p_atpos, p_pos); } @@ -171,14 +171,14 @@ void Line2D::set_gradient(const Ref<Gradient> &p_gradient) { // Cleanup previous connection if any if (_gradient.is_valid()) { - _gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_gradient_changed"); + _gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); } _gradient = p_gradient; // Connect to the gradient so the line will update when the ColorRamp is changed if (_gradient.is_valid()) { - _gradient->connect(CoreStringNames::get_singleton()->changed, this, "_gradient_changed"); + _gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed)); } update(); @@ -188,12 +188,12 @@ Ref<Gradient> Line2D::get_gradient() const { return _gradient; } -void Line2D::set_texture(const Ref<Texture> &p_texture) { +void Line2D::set_texture(const Ref<Texture2D> &p_texture) { _texture = p_texture; update(); } -Ref<Texture> Line2D::get_texture() const { +Ref<Texture2D> Line2D::get_texture() const { return _texture; } @@ -282,7 +282,7 @@ void Line2D::_draw() { points.resize(_points.size()); int len = points.size(); { - PoolVector<Vector2>::Read points_read = _points.read(); + const Vector2 *points_read = _points.ptr(); for (int i = 0; i < len; ++i) { points.write[i] = points_read[i]; } @@ -317,8 +317,7 @@ void Line2D::_draw() { lb.vertices, lb.colors, lb.uvs, Vector<int>(), Vector<float>(), - texture_rid, -1, RID(), - _antialiased, true); + texture_rid); // DEBUG // Draw wireframe @@ -401,20 +400,20 @@ void Line2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &Line2D::set_antialiased); ClassDB::bind_method(D_METHOD("get_antialiased"), &Line2D::get_antialiased); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "points"), "set_points", "get_points"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "width_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color"); ADD_GROUP("Fill", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode"); ADD_GROUP("Capping", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "end_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_end_cap_mode", "get_end_cap_mode"); ADD_GROUP("Border", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sharp_limit"), "set_sharp_limit", "get_sharp_limit"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sharp_limit"), "set_sharp_limit", "get_sharp_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "round_precision"), "set_round_precision", "get_round_precision"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); @@ -429,7 +428,4 @@ void Line2D::_bind_methods() { BIND_ENUM_CONSTANT(LINE_TEXTURE_NONE); BIND_ENUM_CONSTANT(LINE_TEXTURE_TILE); BIND_ENUM_CONSTANT(LINE_TEXTURE_STRETCH); - - ClassDB::bind_method(D_METHOD("_gradient_changed"), &Line2D::_gradient_changed); - ClassDB::bind_method(D_METHOD("_curve_changed"), &Line2D::_curve_changed); } diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 3c7239f67c..51706befdb 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -64,8 +64,8 @@ public: Line2D(); - void set_points(const PoolVector<Vector2> &p_points); - PoolVector<Vector2> get_points() const; + void set_points(const Vector<Vector2> &p_points); + Vector<Vector2> get_points() const; void set_point_position(int i, Vector2 pos); Vector2 get_point_position(int i) const; @@ -89,8 +89,8 @@ public: void set_gradient(const Ref<Gradient> &gradient); Ref<Gradient> get_gradient() const; - void set_texture(const Ref<Texture> &texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &texture); + Ref<Texture2D> get_texture() const; void set_texture_mode(const LineTextureMode mode); LineTextureMode get_texture_mode() const; @@ -124,7 +124,7 @@ private: void _curve_changed(); private: - PoolVector<Vector2> _points; + Vector<Vector2> _points; LineJointMode _joint_mode; LineCapMode _begin_cap_mode; LineCapMode _end_cap_mode; @@ -132,7 +132,7 @@ private: Ref<Curve> _curve; Color _default_color; Ref<Gradient> _gradient; - Ref<Texture> _texture; + Ref<Texture2D> _texture; LineTextureMode _texture_mode; float _sharp_limit; int _round_precision; diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp index 93432ec40b..5e258be700 100644 --- a/scene/2d/mesh_instance_2d.cpp +++ b/scene/2d/mesh_instance_2d.cpp @@ -53,8 +53,8 @@ void MeshInstance2D::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); } void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) { @@ -68,7 +68,7 @@ Ref<Mesh> MeshInstance2D::get_mesh() const { return mesh; } -void MeshInstance2D::set_texture(const Ref<Texture> &p_texture) { +void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { if (p_texture == texture) return; @@ -78,18 +78,18 @@ void MeshInstance2D::set_texture(const Ref<Texture> &p_texture) { _change_notify("texture"); } -void MeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) { +void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> MeshInstance2D::get_normal_map() const { +Ref<Texture2D> MeshInstance2D::get_normal_map() const { return normal_map; } -Ref<Texture> MeshInstance2D::get_texture() const { +Ref<Texture2D> MeshInstance2D::get_texture() const { return texture; } diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h index 51f75a3ead..3356f44e91 100644 --- a/scene/2d/mesh_instance_2d.h +++ b/scene/2d/mesh_instance_2d.h @@ -38,8 +38,8 @@ class MeshInstance2D : public Node2D { Ref<Mesh> mesh; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; protected: void _notification(int p_what); @@ -53,11 +53,11 @@ public: void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_normal_map() const; MeshInstance2D(); }; diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 028459e778..6620027020 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -53,8 +53,8 @@ void MultiMeshInstance2D::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); } void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) { @@ -68,7 +68,7 @@ Ref<MultiMesh> MultiMeshInstance2D::get_multimesh() const { return multimesh; } -void MultiMeshInstance2D::set_texture(const Ref<Texture> &p_texture) { +void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) { if (p_texture == texture) return; @@ -78,18 +78,18 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture> &p_texture) { _change_notify("texture"); } -Ref<Texture> MultiMeshInstance2D::get_texture() const { +Ref<Texture2D> MultiMeshInstance2D::get_texture() const { return texture; } -void MultiMeshInstance2D::set_normal_map(const Ref<Texture> &p_texture) { +void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> MultiMeshInstance2D::get_normal_map() const { +Ref<Texture2D> MultiMeshInstance2D::get_normal_map() const { return normal_map; } diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h index c3f3e52920..a843606ebf 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -39,8 +39,8 @@ class MultiMeshInstance2D : public Node2D { Ref<MultiMesh> multimesh; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; protected: void _notification(int p_what); @@ -54,11 +54,11 @@ public: void set_multimesh(const Ref<MultiMesh> &p_multimesh); Ref<MultiMesh> get_multimesh() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_normal_map() const; MultiMeshInstance2D(); ~MultiMeshInstance2D(); diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index 9209cc5074..bbabfa16c7 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -29,710 +29,66 @@ /*************************************************************************/ #include "navigation_2d.h" +#include "servers/navigation_2d_server.h" -#define USE_ENTRY_POINT - -void Navigation2D::_navpoly_link(int p_id) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - ERR_FAIL_COND(nm.linked); - - PoolVector<Vector2> vertices = nm.navpoly->get_vertices(); - int len = vertices.size(); - if (len == 0) - return; - - PoolVector<Vector2>::Read r = vertices.read(); - - for (int i = 0; i < nm.navpoly->get_polygon_count(); i++) { - - //build - - List<Polygon>::Element *P = nm.polygons.push_back(Polygon()); - Polygon &p = P->get(); - p.owner = &nm; - - Vector<int> poly = nm.navpoly->get_polygon(i); - int plen = poly.size(); - const int *indices = poly.ptr(); - bool valid = true; - p.edges.resize(plen); - - Vector2 center; - float sum = 0; - - for (int j = 0; j < plen; j++) { - - int idx = indices[j]; - if (idx < 0 || idx >= len) { - valid = false; - break; - } - - Polygon::Edge e; - Vector2 ep = nm.xform.xform(r[idx]); - center += ep; - e.point = _get_point(ep); - p.edges.write[j] = e; - - int idxn = indices[(j + 1) % plen]; - if (idxn < 0 || idxn >= len) { - valid = false; - break; - } - - Vector2 epn = nm.xform.xform(r[idxn]); - - sum += (epn.x - ep.x) * (epn.y + ep.y); - } - - p.clockwise = sum > 0; - - if (!valid) { - nm.polygons.pop_back(); - ERR_CONTINUE(!valid); - } - - p.center = center / plen; - - //connect - - for (int j = 0; j < plen; j++) { - - int next = (j + 1) % plen; - EdgeKey ek(p.edges[j].point, p.edges[next].point); - - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - if (!C) { +void Navigation2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_rid"), &Navigation2D::get_rid); - Connection c; - c.A = &p; - c.A_edge = j; - c.B = NULL; - c.B_edge = -1; - connections[ek] = c; - } else { + ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point); + ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner); - if (C->get().B != NULL) { - ConnectionPending pending; - pending.polygon = &p; - pending.edge = j; - p.edges.write[j].P = C->get().pending.push_back(pending); - continue; - } + ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation2D::set_cell_size); + ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation2D::get_cell_size); - C->get().B = &p; - C->get().B_edge = j; - C->get().A->edges.write[C->get().A_edge].C = &p; - C->get().A->edges.write[C->get().A_edge].C_edge = j; - p.edges.write[j].C = C->get().A; - p.edges.write[j].C_edge = C->get().A_edge; - //connection successful. - } - } - } + ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation2D::set_edge_connection_margin); + ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation2D::get_edge_connection_margin); - nm.linked = true; + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); } -void Navigation2D::_navpoly_unlink(int p_id) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - ERR_FAIL_COND(!nm.linked); - - for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) { - - Polygon &p = E->get(); - - int ec = p.edges.size(); - Polygon::Edge *edges = p.edges.ptrw(); - - for (int i = 0; i < ec; i++) { - int next = (i + 1) % ec; - - EdgeKey ek(edges[i].point, edges[next].point); - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - ERR_CONTINUE(!C); +void Navigation2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + Navigation2DServer::get_singleton()->map_set_active(map, true); + } break; + case NOTIFICATION_EXIT_TREE: { - if (edges[i].P) { - C->get().pending.erase(edges[i].P); - edges[i].P = NULL; - - } else if (C->get().B) { - //disconnect - - C->get().B->edges.write[C->get().B_edge].C = NULL; - C->get().B->edges.write[C->get().B_edge].C_edge = -1; - C->get().A->edges.write[C->get().A_edge].C = NULL; - C->get().A->edges.write[C->get().A_edge].C_edge = -1; - - if (C->get().A == &E->get()) { - - C->get().A = C->get().B; - C->get().A_edge = C->get().B_edge; - } - C->get().B = NULL; - C->get().B_edge = -1; - - if (C->get().pending.size()) { - //reconnect if something is pending - ConnectionPending cp = C->get().pending.front()->get(); - C->get().pending.pop_front(); - - C->get().B = cp.polygon; - C->get().B_edge = cp.edge; - C->get().A->edges.write[C->get().A_edge].C = cp.polygon; - C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge; - cp.polygon->edges.write[cp.edge].C = C->get().A; - cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge; - cp.polygon->edges.write[cp.edge].P = NULL; - } - - } else { - connections.erase(C); - //erase - } - } + Navigation2DServer::get_singleton()->map_set_active(map, false); + } break; } - - nm.polygons.clear(); - - nm.linked = false; -} - -int Navigation2D::navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner) { - - int id = last_id++; - NavMesh nm; - nm.linked = false; - nm.navpoly = p_mesh; - nm.xform = p_xform; - nm.owner = p_owner; - navpoly_map[id] = nm; - - _navpoly_link(id); - - return id; } -void Navigation2D::navpoly_set_transform(int p_id, const Transform2D &p_xform) { - - ERR_FAIL_COND(!navpoly_map.has(p_id)); - NavMesh &nm = navpoly_map[p_id]; - if (nm.xform == p_xform) - return; //bleh - _navpoly_unlink(p_id); - nm.xform = p_xform; - _navpoly_link(p_id); +void Navigation2D::set_cell_size(float p_cell_size) { + cell_size = p_cell_size; + Navigation2DServer::get_singleton()->map_set_cell_size(map, cell_size); } -void Navigation2D::navpoly_remove(int p_id) { - ERR_FAIL_COND(!navpoly_map.has(p_id)); - _navpoly_unlink(p_id); - navpoly_map.erase(p_id); +void Navigation2D::set_edge_connection_margin(float p_edge_connection_margin) { + edge_connection_margin = p_edge_connection_margin; + Navigation2DServer::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); } -Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) { - - Polygon *begin_poly = NULL; - Polygon *end_poly = NULL; - Vector2 begin_point; - Vector2 end_point; - float begin_d = 1e20; - float end_d = 1e20; - - //look for point inside triangle - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - if (begin_d || end_d) { - for (int i = 2; i < p.edges.size(); i++) { - - if (begin_d > 0) { - - if (Geometry::is_point_in_triangle(p_start, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - begin_poly = &p; - begin_point = p_start; - begin_d = 0; - if (end_d == 0) - break; - } - } - - if (end_d > 0) { - - if (Geometry::is_point_in_triangle(p_end, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - end_poly = &p; - end_point = p_end; - end_d = 0; - if (begin_d == 0) - break; - } - } - } - } - - p.prev_edge = -1; - } - } - - //start or end not inside triangle.. look for closest segment :| - if (begin_d || end_d) { - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - if (begin_d > 0) { - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_start, edge); - float d = spoint.distance_to(p_start); - if (d < begin_d) { - begin_poly = &p; - begin_point = spoint; - begin_d = d; - } - } - - if (end_d > 0) { - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_end, edge); - float d = spoint.distance_to(p_end); - if (d < end_d) { - end_poly = &p; - end_point = spoint; - end_d = d; - } - } - } - } - } - } - - if (!begin_poly || !end_poly) { - - return Vector<Vector2>(); //no path - } - - if (begin_poly == end_poly) { - - Vector<Vector2> path; - path.resize(2); - path.write[0] = begin_point; - path.write[1] = end_point; - return path; - } - - bool found_route = false; - - List<Polygon *> open_list; - - begin_poly->entry = p_start; - - for (int i = 0; i < begin_poly->edges.size(); i++) { - - if (begin_poly->edges[i].C) { - - begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge; -#ifdef USE_ENTRY_POINT - Vector2 edge[2] = { - _get_vertex(begin_poly->edges[i].point), - _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point) - }; - - Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry, edge); - begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry); - begin_poly->edges[i].C->entry = entry; -#else - begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center); -#endif - open_list.push_back(begin_poly->edges[i].C); - - if (begin_poly->edges[i].C == end_poly) { - found_route = true; - } - } - } - - while (!found_route) { - - if (open_list.size() == 0) { - break; - } - //check open list - - List<Polygon *>::Element *least_cost_poly = NULL; - float least_cost = 1e30; - - //this could be faster (cache previous results) - for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) { - - Polygon *p = E->get(); - - float cost = p->distance; - -#ifdef USE_ENTRY_POINT - int es = p->edges.size(); - - float shortest_distance = 1e30; - - for (int i = 0; i < es; i++) { - Polygon::Edge &e = p->edges.write[i]; - - if (!e.C) - continue; - - Vector2 edge[2] = { - _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i + 1) % es].point) - }; - - Vector2 edge_point = Geometry::get_closest_point_to_segment_2d(p->entry, edge); - float dist = p->entry.distance_to(edge_point); - if (dist < shortest_distance) - shortest_distance = dist; - } - - cost += shortest_distance; -#else - cost += p->center.distance_to(end_point); -#endif - if (cost < least_cost) { - least_cost_poly = E; - least_cost = cost; - } - } - - Polygon *p = least_cost_poly->get(); - //open the neighbours for search - int es = p->edges.size(); - - for (int i = 0; i < es; i++) { - - Polygon::Edge &e = p->edges.write[i]; - - if (!e.C) - continue; - -#ifdef USE_ENTRY_POINT - Vector2 edge[2] = { - _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i + 1) % es].point) - }; - - Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry, edge); - float distance = p->entry.distance_to(edge_entry) + p->distance; - -#else - - float distance = p->center.distance_to(e.C->center) + p->distance; - -#endif - - if (e.C->prev_edge != -1) { - //oh this was visited already, can we win the cost? - - if (e.C->distance > distance) { - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = edge_entry; -#endif - } - } else { - //add to open neighbours - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = edge_entry; -#endif - - open_list.push_back(e.C); - - if (e.C == end_poly) { - //oh my reached end! stop algorithm - found_route = true; - break; - } - } - } - - if (found_route) - break; - - open_list.erase(least_cost_poly); - } - - if (found_route) { - - Vector<Vector2> path; - - if (p_optimize) { - //string pulling - - Vector2 apex_point = end_point; - Vector2 portal_left = apex_point; - Vector2 portal_right = apex_point; - Polygon *left_poly = end_poly; - Polygon *right_poly = end_poly; - Polygon *p = end_poly; - - while (p) { - - Vector2 left; - Vector2 right; - -//#define CLOCK_TANGENT(m_a,m_b,m_c) ( ((m_a)-(m_c)).cross((m_a)-(m_b)) ) -#define CLOCK_TANGENT(m_a, m_b, m_c) ((((m_a).x - (m_c).x) * ((m_b).y - (m_c).y) - ((m_b).x - (m_c).x) * ((m_a).y - (m_c).y))) - - if (p == begin_poly) { - left = begin_point; - right = begin_point; - } else { - int prev = p->prev_edge; - int prev_n = (p->prev_edge + 1) % p->edges.size(); - left = _get_vertex(p->edges[prev].point); - right = _get_vertex(p->edges[prev_n].point); - - if (p->clockwise) { - SWAP(left, right); - } - /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){ - SWAP(left,right); - }*/ - } - - bool skip = false; - - /* - print_line("-----\nAPEX: "+(apex_point-end_point)); - print_line("LEFT:"); - print_line("\tPortal: "+(portal_left-end_point)); - print_line("\tPoint: "+(left-end_point)); - print_line("\tLeft Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_left,left))); - print_line("\tLeft Distance: "+rtos(portal_left.distance_squared_to(apex_point))); - print_line("\tLeft Test: "+rtos(CLOCK_TANGENT(apex_point,left,portal_right))); - print_line("RIGHT:"); - print_line("\tPortal: "+(portal_right-end_point)); - print_line("\tPoint: "+(right-end_point)); - print_line("\tRight Tangent: "+rtos(CLOCK_TANGENT(apex_point,portal_right,right))); - print_line("\tRight Distance: "+rtos(portal_right.distance_squared_to(apex_point))); - print_line("\tRight Test: "+rtos(CLOCK_TANGENT(apex_point,right,portal_left))); - */ - - if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) { - //process - if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) { - left_poly = p; - portal_left = left; - } else { - - apex_point = portal_right; - p = right_poly; - left_poly = p; - portal_left = apex_point; - portal_right = apex_point; - if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) - path.push_back(apex_point); - skip = true; - } - } - - if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) { - //process - if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) { - right_poly = p; - portal_right = right; - } else { - - apex_point = portal_left; - p = left_poly; - right_poly = p; - portal_right = apex_point; - portal_left = apex_point; - if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point)) - path.push_back(apex_point); - } - } - - if (p != begin_poly) - p = p->edges[p->prev_edge].C; - else - p = NULL; - } - - } else { - //midpoints - Polygon *p = end_poly; - - while (true) { - int prev = p->prev_edge; - int prev_n = (p->prev_edge + 1) % p->edges.size(); - Vector2 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5; - path.push_back(point); - p = p->edges[prev].C; - if (p == begin_poly) - break; - } - } - - if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) { - path.push_back(begin_point); // Add the begin point - } else { - path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point - } - - path.invert(); - - if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) { - path.push_back(end_point); // Add the end point - } else { - path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point - } - - return path; - } - - return Vector<Vector2>(); +Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize) const { + return Navigation2DServer::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); } -Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) { - - Vector2 closest_point = Vector2(); - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - return p_point; //inside triangle, nothing else to discuss - } - } - } - } - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); - float d = spoint.distance_squared_to(p_point); - if (d < closest_point_d) { - - closest_point = spoint; - closest_point_d = d; - } - } - } - } - - return closest_point; +Vector2 Navigation2D::get_closest_point(const Vector2 &p_point) const { + return Navigation2DServer::get_singleton()->map_get_closest_point(map, p_point); } -Object *Navigation2D::get_closest_point_owner(const Vector2 &p_point) { - - Object *owner = NULL; - Vector2 closest_point = Vector2(); - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - if (Geometry::is_point_in_triangle(p_point, _get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point))) { - - return E->get().owner; - } - } - } - } - - for (Map<int, NavMesh>::Element *E = navpoly_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - int es = p.edges.size(); - for (int i = 0; i < es; i++) { - - Vector2 edge[2] = { - _get_vertex(p.edges[i].point), - _get_vertex(p.edges[(i + 1) % es].point) - }; - - Vector2 spoint = Geometry::get_closest_point_to_segment_2d(p_point, edge); - float d = spoint.distance_squared_to(p_point); - if (d < closest_point_d) { - - closest_point = spoint; - closest_point_d = d; - owner = E->get().owner; - } - } - } - } - - return owner; +RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const { + return Navigation2DServer::get_singleton()->map_get_closest_point_owner(map, p_point); } -void Navigation2D::_bind_methods() { - - ClassDB::bind_method(D_METHOD("navpoly_add", "mesh", "xform", "owner"), &Navigation2D::navpoly_add, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("navpoly_set_transform", "id", "xform"), &Navigation2D::navpoly_set_transform); - ClassDB::bind_method(D_METHOD("navpoly_remove", "id"), &Navigation2D::navpoly_remove); +Navigation2D::Navigation2D() { - ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation2D::get_simple_path, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation2D::get_closest_point); - ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation2D::get_closest_point_owner); + map = Navigation2DServer::get_singleton()->map_create(); + set_cell_size(10); // Ten pixels + set_edge_connection_margin(100); } -Navigation2D::Navigation2D() { - - ERR_FAIL_COND(sizeof(Point) != 8); - cell_size = 1; // one pixel - last_id = 1; +Navigation2D::~Navigation2D() { + Navigation2DServer::get_singleton()->free(map); } diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h index 41b9aea35a..5520f5006e 100644 --- a/scene/2d/navigation_2d.h +++ b/scene/2d/navigation_2d.h @@ -38,137 +38,35 @@ class Navigation2D : public Node2D { GDCLASS(Navigation2D, Node2D); - union Point { + RID map; + real_t cell_size; + real_t edge_connection_margin; - struct { - int64_t x : 32; - int64_t y : 32; - }; - - uint64_t key; - bool operator<(const Point &p_key) const { return key < p_key.key; } - }; - - struct EdgeKey { - - Point a; - Point b; - - bool operator<(const EdgeKey &p_key) const { - return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key); - }; - - EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) : - a(p_a), - b(p_b) { - if (a.key > b.key) { - SWAP(a, b); - } - } - }; - - struct NavMesh; - struct Polygon; - - struct ConnectionPending { - - Polygon *polygon; - int edge; - }; - - struct Polygon { - - struct Edge { - Point point; - Polygon *C; //connection - int C_edge; - List<ConnectionPending>::Element *P; - Edge() { - C = NULL; - C_edge = -1; - P = NULL; - } - }; - - Vector<Edge> edges; - - Vector2 center; - Vector2 entry; - - float distance; - int prev_edge; - - bool clockwise; - - NavMesh *owner; - }; - - struct Connection { - - Polygon *A; - int A_edge; - Polygon *B; - int B_edge; - - List<ConnectionPending> pending; - - Connection() { - A = NULL; - B = NULL; - A_edge = -1; - B_edge = -1; - } - }; - - Map<EdgeKey, Connection> connections; - - struct NavMesh { - - Object *owner; - Transform2D xform; - bool linked; - Ref<NavigationPolygon> navpoly; - List<Polygon> polygons; - }; - - _FORCE_INLINE_ Point _get_point(const Vector2 &p_pos) const { - - int x = int(Math::floor(p_pos.x / cell_size)); - int y = int(Math::floor(p_pos.y / cell_size)); +protected: + static void _bind_methods(); + void _notification(int p_what); - Point p; - p.key = 0; - p.x = x; - p.y = y; - return p; +public: + RID get_rid() const { + return map; } - _FORCE_INLINE_ Vector2 _get_vertex(const Point &p_point) const { - - return Vector2(p_point.x, p_point.y) * cell_size; + void set_cell_size(float p_cell_size); + float get_cell_size() const { + return cell_size; } - void _navpoly_link(int p_id); - void _navpoly_unlink(int p_id); - - float cell_size; - Map<int, NavMesh> navpoly_map; - int last_id; - -protected: - static void _bind_methods(); - -public: - //API should be as dynamic as possible - int navpoly_add(const Ref<NavigationPolygon> &p_mesh, const Transform2D &p_xform, Object *p_owner = NULL); - void navpoly_set_transform(int p_id, const Transform2D &p_xform); - void navpoly_remove(int p_id); + void set_edge_connection_margin(float p_edge_connection_margin); + float get_edge_connection_margin() const { + return edge_connection_margin; + } - Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true); - Vector2 get_closest_point(const Vector2 &p_point); - Object *get_closest_point_owner(const Vector2 &p_point); + Vector<Vector2> get_simple_path(const Vector2 &p_start, const Vector2 &p_end, bool p_optimize = true) const; + Vector2 get_closest_point(const Vector2 &p_point) const; + RID get_closest_point_owner(const Vector2 &p_point) const; Navigation2D(); + ~Navigation2D(); }; #endif // NAVIGATION_2D_H diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp new file mode 100644 index 0000000000..f5fe113f29 --- /dev/null +++ b/scene/2d/navigation_agent_2d.cpp @@ -0,0 +1,341 @@ +/*************************************************************************/ +/* navigation_agent_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_agent_2d.h" + +#include "core/engine.h" +#include "scene/2d/navigation_2d.h" +#include "servers/navigation_2d_server.h" + +void NavigationAgent2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance); + ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance); + + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent2D::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent2D::get_radius); + + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent2D::set_navigation_node); + ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent2D::get_navigation_node); + + ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent2D::set_neighbor_dist); + ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent2D::get_neighbor_dist); + + ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent2D::set_max_neighbors); + ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent2D::get_max_neighbors); + + ClassDB::bind_method(D_METHOD("set_time_horizon", "time_horizon"), &NavigationAgent2D::set_time_horizon); + ClassDB::bind_method(D_METHOD("get_time_horizon"), &NavigationAgent2D::get_time_horizon); + + ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent2D::set_max_speed); + ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent2D::get_max_speed); + + ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent2D::set_path_max_distance); + ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent2D::get_path_max_distance); + + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location); + ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location); + ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location); + ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent2D::distance_to_target); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent2D::set_velocity); + ClassDB::bind_method(D_METHOD("get_nav_path"), &NavigationAgent2D::get_nav_path); + ClassDB::bind_method(D_METHOD("get_nav_path_index"), &NavigationAgent2D::get_nav_path_index); + ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent2D::is_target_reached); + ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent2D::is_target_reachable); + ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent2D::is_navigation_finished); + ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent2D::get_final_location); + + ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_target_desired_distance", "get_target_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_neighbor_dist", "get_neighbor_dist"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance"); + + ADD_SIGNAL(MethodInfo("path_changed")); + ADD_SIGNAL(MethodInfo("target_reached")); + ADD_SIGNAL(MethodInfo("navigation_finished")); + ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity"))); +} + +void NavigationAgent2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + + agent_parent = Object::cast_to<Node2D>(get_parent()); + + Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + + // Search the navigation node and set it + { + Navigation2D *nav = NULL; + Node *p = get_parent(); + while (p != NULL) { + nav = Object::cast_to<Navigation2D>(p); + if (nav != NULL) + p = NULL; + else + p = p->get_parent(); + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + agent_parent = NULL; + set_navigation(NULL); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (agent_parent) { + + Navigation2DServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().get_origin()); + if (!target_reached) { + if (distance_to_target() < target_desired_distance) { + emit_signal("target_reached"); + target_reached = true; + } + } + } + } break; + } +} + +NavigationAgent2D::NavigationAgent2D() : + agent_parent(NULL), + navigation(NULL), + agent(RID()), + target_desired_distance(1.0), + path_max_distance(3.0), + velocity_submitted(false), + target_reached(false), + navigation_finished(true) { + agent = Navigation2DServer::get_singleton()->agent_create(); + set_neighbor_dist(500.0); + set_max_neighbors(10); + set_time_horizon(20.0); + set_radius(10.0); + set_max_speed(200.0); +} + +NavigationAgent2D::~NavigationAgent2D() { + Navigation2DServer::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationAgent2D::set_navigation(Navigation2D *p_nav) { + if (navigation == p_nav) + return; // Pointless + + navigation = p_nav; + Navigation2DServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid()); +} + +void NavigationAgent2D::set_navigation_node(Node *p_nav) { + Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav); + ERR_FAIL_COND(nav == NULL); + set_navigation(nav); +} + +Node *NavigationAgent2D::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +void NavigationAgent2D::set_target_desired_distance(real_t p_dd) { + target_desired_distance = p_dd; +} + +void NavigationAgent2D::set_radius(real_t p_radius) { + radius = p_radius; + Navigation2DServer::get_singleton()->agent_set_radius(agent, radius); +} + +void NavigationAgent2D::set_neighbor_dist(real_t p_dist) { + neighbor_dist = p_dist; + Navigation2DServer::get_singleton()->agent_set_neighbor_dist(agent, neighbor_dist); +} + +void NavigationAgent2D::set_max_neighbors(int p_count) { + max_neighbors = p_count; + Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors); +} + +void NavigationAgent2D::set_time_horizon(real_t p_time) { + time_horizon = p_time; + Navigation2DServer::get_singleton()->agent_set_time_horizon(agent, time_horizon); +} + +void NavigationAgent2D::set_max_speed(real_t p_max_speed) { + max_speed = p_max_speed; + Navigation2DServer::get_singleton()->agent_set_max_speed(agent, max_speed); +} + +void NavigationAgent2D::set_path_max_distance(real_t p_pmd) { + path_max_distance = p_pmd; +} + +real_t NavigationAgent2D::get_path_max_distance() { + return path_max_distance; +} + +void NavigationAgent2D::set_target_location(Vector2 p_location) { + target_location = p_location; + navigation_path.clear(); + target_reached = false; + navigation_finished = false; +} + +Vector2 NavigationAgent2D::get_target_location() const { + return target_location; +} + +Vector2 NavigationAgent2D::get_next_location() { + update_navigation(); + if (navigation_path.size() == 0) { + ERR_FAIL_COND_V(agent_parent == NULL, Vector2()); + return agent_parent->get_global_transform().get_origin(); + } else { + return navigation_path[nav_path_index]; + } +} + +real_t NavigationAgent2D::distance_to_target() const { + ERR_FAIL_COND_V(agent_parent == NULL, 0.0); + return agent_parent->get_global_transform().get_origin().distance_to(target_location); +} + +bool NavigationAgent2D::is_target_reached() const { + return target_reached; +} + +bool NavigationAgent2D::is_target_reachable() { + return target_desired_distance >= get_final_location().distance_to(target_location); +} + +bool NavigationAgent2D::is_navigation_finished() { + update_navigation(); + return navigation_finished; +} + +Vector2 NavigationAgent2D::get_final_location() { + update_navigation(); + if (navigation_path.size() == 0) { + return Vector2(); + } + return navigation_path[navigation_path.size() - 1]; +} + +void NavigationAgent2D::set_velocity(Vector2 p_velocity) { + target_velocity = p_velocity; + Navigation2DServer::get_singleton()->agent_set_target_velocity(agent, target_velocity); + Navigation2DServer::get_singleton()->agent_set_velocity(agent, prev_safe_velocity); + velocity_submitted = true; +} + +void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) { + const Vector2 velocity = Vector2(p_new_velocity.x, p_new_velocity.z); + prev_safe_velocity = velocity; + + if (!velocity_submitted) { + target_velocity = Vector2(); + return; + } + velocity_submitted = false; + + emit_signal("velocity_computed", velocity); +} + +String NavigationAgent2D::get_configuration_warning() const { + if (!Object::cast_to<Node2D>(get_parent())) { + return TTR("The NavigationAgent2D can be used only under a Node2D node"); + } + + return String(); +} + +void NavigationAgent2D::update_navigation() { + + if (agent_parent == NULL) return; + if (navigation == NULL) return; + if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return; + + update_frame_id = Engine::get_singleton()->get_physics_frames(); + + Vector2 o = agent_parent->get_global_transform().get_origin(); + + bool reload_path = false; + + if (Navigation2DServer::get_singleton()->agent_is_map_changed(agent)) { + reload_path = true; + } else if (navigation_path.size() == 0) { + reload_path = true; + } else { + // Check if too far from the navigation path + if (nav_path_index > 0) { + Vector2 segment[2]; + segment[0] = navigation_path[nav_path_index - 1]; + segment[1] = navigation_path[nav_path_index]; + Vector2 p = Geometry::get_closest_point_to_segment_2d(o, segment); + if (o.distance_to(p) >= path_max_distance) { + // To faraway, reload path + reload_path = true; + } + } + } + + if (reload_path) { + navigation_path = Navigation2DServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_finished = false; + nav_path_index = 0; + emit_signal("path_changed"); + } + + if (navigation_path.size() == 0) + return; + + // Check if we can advance the navigation path + if (navigation_finished == false) { + // Advances to the next far away location. + while (o.distance_to(navigation_path[nav_path_index]) < target_desired_distance) { + nav_path_index += 1; + if (nav_path_index == navigation_path.size()) { + nav_path_index -= 1; + navigation_finished = true; + emit_signal("navigation_finished"); + break; + } + } + } +} diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h new file mode 100644 index 0000000000..26eccfc949 --- /dev/null +++ b/scene/2d/navigation_agent_2d.h @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* navigation_agent_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_AGENT_2D_H +#define NAVIGATION_AGENT_2D_H + +#include "core/vector.h" +#include "scene/main/node.h" + +class Node2D; +class Navigation2D; + +class NavigationAgent2D : public Node { + GDCLASS(NavigationAgent2D, Node); + + Node2D *agent_parent; + Navigation2D *navigation; + + RID agent; + + real_t target_desired_distance; + real_t radius; + real_t neighbor_dist; + int max_neighbors; + real_t time_horizon; + real_t max_speed; + + real_t path_max_distance; + + Vector2 target_location; + Vector<Vector2> navigation_path; + int nav_path_index; + bool velocity_submitted; + Vector2 prev_safe_velocity; + /// The submitted target velocity + Vector2 target_velocity; + bool target_reached; + bool navigation_finished; + // No initialized on purpose + uint32_t update_frame_id; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationAgent2D(); + virtual ~NavigationAgent2D(); + + void set_navigation(Navigation2D *p_nav); + const Navigation2D *get_navigation() const { + return navigation; + } + + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; + + RID get_rid() const { + return agent; + } + + void set_target_desired_distance(real_t p_dd); + real_t get_target_desired_distance() const { + return target_desired_distance; + } + + void set_radius(real_t p_radius); + real_t get_radius() const { + return radius; + } + + void set_neighbor_dist(real_t p_dist); + real_t get_neighbor_dist() const { + return neighbor_dist; + } + + void set_max_neighbors(int p_count); + int get_max_neighbors() const { + return max_neighbors; + } + + void set_time_horizon(real_t p_time); + real_t get_time_horizon() const { + return time_horizon; + } + + void set_max_speed(real_t p_max_speed); + real_t get_max_speed() const { + return max_speed; + } + + void set_path_max_distance(real_t p_pmd); + real_t get_path_max_distance(); + + void set_target_location(Vector2 p_location); + Vector2 get_target_location() const; + + Vector2 get_next_location(); + + Vector<Vector2> get_nav_path() const { + return navigation_path; + } + + int get_nav_path_index() const { + return nav_path_index; + } + + real_t distance_to_target() const; + bool is_target_reached() const; + bool is_target_reachable(); + bool is_navigation_finished(); + Vector2 get_final_location(); + + void set_velocity(Vector2 p_velocity); + void _avoidance_done(Vector3 p_new_velocity); + + virtual String get_configuration_warning() const; + +private: + void update_navigation(); +}; + +#endif diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp new file mode 100644 index 0000000000..cc9f5740a9 --- /dev/null +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -0,0 +1,154 @@ +/*************************************************************************/ +/* navigation_obstacle_2d.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_obstacle_2d.h" + +#include "scene/2d/collision_shape_2d.h" +#include "scene/2d/navigation_2d.h" +#include "scene/2d/physics_body_2d.h" +#include "servers/navigation_2d_server.h" + +void NavigationObstacle2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node); + ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node); +} + +void NavigationObstacle2D::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + + update_agent_shape(); + + // Search the navigation node and set it + { + Navigation2D *nav = NULL; + Node *p = get_parent(); + while (p != NULL) { + nav = Object::cast_to<Navigation2D>(p); + if (nav != NULL) + p = NULL; + else + p = p->get_parent(); + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + set_navigation(NULL); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + Node2D *node = Object::cast_to<Node2D>(get_parent()); + if (node) { + Navigation2DServer::get_singleton()->agent_set_position(agent, node->get_global_transform().get_origin()); + } + + } break; + } +} + +NavigationObstacle2D::NavigationObstacle2D() : + navigation(NULL), + agent(RID()) { + agent = Navigation2DServer::get_singleton()->agent_create(); +} + +NavigationObstacle2D::~NavigationObstacle2D() { + Navigation2DServer::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) { + if (navigation == p_nav) + return; // Pointless + + navigation = p_nav; + Navigation2DServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid()); +} + +void NavigationObstacle2D::set_navigation_node(Node *p_nav) { + Navigation2D *nav = Object::cast_to<Navigation2D>(p_nav); + ERR_FAIL_COND(nav == NULL); + set_navigation(nav); +} + +Node *NavigationObstacle2D::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +String NavigationObstacle2D::get_configuration_warning() const { + if (!Object::cast_to<Node2D>(get_parent())) { + return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."); + } + + return String(); +} + +void NavigationObstacle2D::update_agent_shape() { + Node *node = get_parent(); + + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < node->get_child_count(); i++) { + // For each collision shape + CollisionShape2D *cs = Object::cast_to<CollisionShape2D>(node->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().get_origin().length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Size2 s = cs->get_global_transform().get_scale(); + r *= MAX(s.x, s.y); + // Takes the biggest radius + radius = MAX(radius, r); + } + } + Node2D *node_2d = Object::cast_to<Node2D>(node); + if (node_2d) { + Vector2 s = node_2d->get_global_transform().get_scale(); + radius *= MAX(s.x, s.y); + } + + if (radius == 0.0) + radius = 1.0; // Never a 0 radius + + // Initialize the Agent as an object + Navigation2DServer::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + Navigation2DServer::get_singleton()->agent_set_max_neighbors(agent, 0); + Navigation2DServer::get_singleton()->agent_set_time_horizon(agent, 0.0); + Navigation2DServer::get_singleton()->agent_set_radius(agent, radius); + Navigation2DServer::get_singleton()->agent_set_max_speed(agent, 0.0); +} diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h new file mode 100644 index 0000000000..3935fe1bc5 --- /dev/null +++ b/scene/2d/navigation_obstacle_2d.h @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* navigation_obstacle_2d.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_OBSTACLE_2D_H +#define NAVIGATION_OBSTACLE_2D_H + +#include "scene/main/node.h" + +class Navigation2D; + +class NavigationObstacle2D : public Node { + GDCLASS(NavigationObstacle2D, Node); + + Navigation2D *navigation; + + RID agent; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationObstacle2D(); + virtual ~NavigationObstacle2D(); + + void set_navigation(Navigation2D *p_nav); + const Navigation2D *get_navigation() const { + return navigation; + } + + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; + + RID get_rid() const { + return agent; + } + + virtual String get_configuration_warning() const; + +private: + void update_agent_shape(); +}; + +#endif diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 883fb37668..9159ef21c5 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -32,7 +32,9 @@ #include "core/core_string_names.h" #include "core/engine.h" +#include "core/os/mutex.h" #include "navigation_2d.h" +#include "servers/navigation_2d_server.h" #include "thirdparty/misc/triangulator.h" @@ -44,11 +46,11 @@ Rect2 NavigationPolygon::_edit_get_rect() const { bool first = true; for (int i = 0; i < outlines.size(); i++) { - const PoolVector<Vector2> &outline = outlines[i]; + const Vector<Vector2> &outline = outlines[i]; const int outline_size = outline.size(); if (outline_size < 3) continue; - PoolVector<Vector2>::Read p = outline.read(); + const Vector2 *p = outline.ptr(); for (int j = 0; j < outline_size; j++) { if (first) { item_rect = Rect2(p[j], Vector2(0, 0)); @@ -67,7 +69,7 @@ Rect2 NavigationPolygon::_edit_get_rect() const { bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { for (int i = 0; i < outlines.size(); i++) { - const PoolVector<Vector2> &outline = outlines[i]; + const Vector<Vector2> &outline = outlines[i]; const int outline_size = outline.size(); if (outline_size < 3) continue; @@ -78,19 +80,27 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double } #endif -void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) { +void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } vertices = p_vertices; rect_cache_dirty = true; } -PoolVector<Vector2> NavigationPolygon::get_vertices() const { +Vector<Vector2> NavigationPolygon::get_vertices() const { return vertices; } void NavigationPolygon::_set_polygons(const Array &p_array) { + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } polygons.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { polygons.write[i].indices = p_array[i]; @@ -133,9 +143,13 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } } -void NavigationPolygon::add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index) { +void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) { outlines.insert(p_index, p_outline); rect_cache_dirty = true; @@ -153,9 +167,39 @@ Vector<int> NavigationPolygon::get_polygon(int p_idx) { void NavigationPolygon::clear_polygons() { polygons.clear(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } } -void NavigationPolygon::add_outline(const PoolVector<Vector2> &p_outline) { +Ref<NavigationMesh> NavigationPolygon::get_mesh() { + MutexLock lock(navmesh_generation); + + if (navmesh.is_null()) { + navmesh.instance(); + Vector<Vector3> verts; + { + verts.resize(get_vertices().size()); + Vector3 *w = verts.ptrw(); + + const Vector2 *r = get_vertices().ptr(); + + for (int i(0); i < get_vertices().size(); i++) { + w[i] = Vector3(r[i].x, 0.0, r[i].y); + } + } + navmesh->set_vertices(verts); + + for (int i(0); i < get_polygon_count(); i++) { + navmesh->add_polygon(get_polygon(i)); + } + } + + return navmesh; +} + +void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) { outlines.push_back(p_outline); rect_cache_dirty = true; @@ -166,7 +210,7 @@ int NavigationPolygon::get_outline_count() const { return outlines.size(); } -void NavigationPolygon::set_outline(int p_idx, const PoolVector<Vector2> &p_outline) { +void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline) { ERR_FAIL_INDEX(p_idx, outlines.size()); outlines.write[p_idx] = p_outline; rect_cache_dirty = true; @@ -179,8 +223,8 @@ void NavigationPolygon::remove_outline(int p_idx) { rect_cache_dirty = true; } -PoolVector<Vector2> NavigationPolygon::get_outline(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, outlines.size(), PoolVector<Vector2>()); +Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, outlines.size(), Vector<Vector2>()); return outlines[p_idx]; } @@ -191,17 +235,21 @@ void NavigationPolygon::clear_outlines() { } void NavigationPolygon::make_polygons_from_outlines() { + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } List<TriangulatorPoly> in_poly, out_poly; Vector2 outside_point(-1e10, -1e10); for (int i = 0; i < outlines.size(); i++) { - PoolVector<Vector2> ol = outlines[i]; + Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); if (olsize < 3) continue; - PoolVector<Vector2>::Read r = ol.read(); + const Vector2 *r = ol.ptr(); for (int j = 0; j < olsize; j++) { outside_point.x = MAX(r[j].x, outside_point.x); outside_point.y = MAX(r[j].y, outside_point.y); @@ -212,11 +260,11 @@ void NavigationPolygon::make_polygons_from_outlines() { for (int i = 0; i < outlines.size(); i++) { - PoolVector<Vector2> ol = outlines[i]; + Vector<Vector2> ol = outlines[i]; int olsize = ol.size(); if (olsize < 3) continue; - PoolVector<Vector2>::Read r = ol.read(); + const Vector2 *r = ol.ptr(); int interscount = 0; //test if this is an outer outline @@ -225,11 +273,11 @@ void NavigationPolygon::make_polygons_from_outlines() { if (i == k) continue; //no self intersect - PoolVector<Vector2> ol2 = outlines[k]; + Vector<Vector2> ol2 = outlines[k]; int olsize2 = ol2.size(); if (olsize2 < 3) continue; - PoolVector<Vector2>::Read r2 = ol2.read(); + const Vector2 *r2 = ol2.ptr(); for (int l = 0; l < olsize2; l++) { @@ -314,7 +362,7 @@ void NavigationPolygon::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_outlines", "outlines"), &NavigationPolygon::_set_outlines); ClassDB::bind_method(D_METHOD("_get_outlines"), &NavigationPolygon::_get_outlines); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines"); } @@ -323,7 +371,10 @@ NavigationPolygon::NavigationPolygon() : rect_cache_dirty(true) { } -void NavigationPolygonInstance::set_enabled(bool p_enabled) { +NavigationPolygon::~NavigationPolygon() { +} + +void NavigationRegion2D::set_enabled(bool p_enabled) { if (enabled == p_enabled) return; @@ -334,18 +385,12 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { if (!enabled) { - if (nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } + Navigation2DServer::get_singleton()->region_set_map(region, RID()); } else { if (navigation) { - if (navpoly.is_valid()) { - - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); - } + Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid()); } } @@ -353,25 +398,25 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { update(); } -bool NavigationPolygonInstance::is_enabled() const { +bool NavigationRegion2D::is_enabled() const { return enabled; } ///////////////////////////// #ifdef TOOLS_ENABLED -Rect2 NavigationPolygonInstance::_edit_get_rect() const { +Rect2 NavigationRegion2D::_edit_get_rect() const { return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); } -bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { +bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false; } #endif -void NavigationPolygonInstance::_notification(int p_what) { +void NavigationRegion2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -382,9 +427,9 @@ void NavigationPolygonInstance::_notification(int p_what) { navigation = Object::cast_to<Navigation2D>(c); if (navigation) { - if (enabled && navpoly.is_valid()) { + if (enabled) { - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); + Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid()); } break; } @@ -395,19 +440,14 @@ void NavigationPolygonInstance::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - if (navigation && nav_id != -1) { - navigation->navpoly_set_transform(nav_id, get_relative_transform_to_parent(navigation)); - } + Navigation2DServer::get_singleton()->region_set_transform(region, get_global_transform()); } break; case NOTIFICATION_EXIT_TREE: { if (navigation) { - if (nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } + Navigation2DServer::get_singleton()->region_set_map(region, RID()); } navigation = NULL; } break; @@ -415,7 +455,7 @@ void NavigationPolygonInstance::_notification(int p_what) { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) { - PoolVector<Vector2> verts = navpoly->get_vertices(); + Vector<Vector2> verts = navpoly->get_vertices(); int vsize = verts.size(); if (vsize < 3) return; @@ -431,7 +471,7 @@ void NavigationPolygonInstance::_notification(int p_what) { vertices.resize(vsize); colors.resize(vsize); { - PoolVector<Vector2>::Read vr = verts.read(); + const Vector2 *vr = verts.ptr(); for (int i = 0; i < vsize; i++) { vertices.write[i] = vr[i]; colors.write[i] = color; @@ -460,46 +500,40 @@ void NavigationPolygonInstance::_notification(int p_what) { } } -void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { +void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { if (p_navpoly == navpoly) { return; } - if (navigation && nav_id != -1) { - navigation->navpoly_remove(nav_id); - nav_id = -1; - } - if (navpoly.is_valid()) { - navpoly->disconnect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); + navpoly->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); } + navpoly = p_navpoly; + Navigation2DServer::get_singleton()->region_set_navpoly(region, p_navpoly); + if (navpoly.is_valid()) { - navpoly->connect(CoreStringNames::get_singleton()->changed, this, "_navpoly_changed"); + navpoly->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NavigationRegion2D::_navpoly_changed)); } _navpoly_changed(); - if (navigation && navpoly.is_valid() && enabled) { - nav_id = navigation->navpoly_add(navpoly, get_relative_transform_to_parent(navigation), this); - } - _change_notify("navpoly"); update_configuration_warning(); } -Ref<NavigationPolygon> NavigationPolygonInstance::get_navigation_polygon() const { +Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const { return navpoly; } -void NavigationPolygonInstance::_navpoly_changed() { +void NavigationRegion2D::_navpoly_changed() { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) update(); } -String NavigationPolygonInstance::get_configuration_warning() const { +String NavigationRegion2D::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); @@ -517,27 +551,32 @@ String NavigationPolygonInstance::get_configuration_warning() const { c = Object::cast_to<Node2D>(c->get_parent()); } - return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + return TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); } -void NavigationPolygonInstance::_bind_methods() { +void NavigationRegion2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationPolygonInstance::set_navigation_polygon); - ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationPolygonInstance::get_navigation_polygon); + ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationRegion2D::set_navigation_polygon); + ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon); - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationPolygonInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationPolygonInstance::is_enabled); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled); - ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationPolygonInstance::_navpoly_changed); + ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); } -NavigationPolygonInstance::NavigationPolygonInstance() { +NavigationRegion2D::NavigationRegion2D() { - navigation = NULL; - nav_id = -1; enabled = true; set_notify_transform(true); + region = Navigation2DServer::get_singleton()->region_create(); + + navigation = NULL; +} + +NavigationRegion2D::~NavigationRegion2D() { + Navigation2DServer::get_singleton()->free(region); } diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index cbc1711a32..579d6b0e0e 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -32,21 +32,26 @@ #define NAVIGATION_POLYGON_H #include "scene/2d/node_2d.h" +#include "scene/resources/navigation_mesh.h" class NavigationPolygon : public Resource { GDCLASS(NavigationPolygon, Resource); - PoolVector<Vector2> vertices; + Vector<Vector2> vertices; struct Polygon { Vector<int> indices; }; Vector<Polygon> polygons; - Vector<PoolVector<Vector2> > outlines; + Vector<Vector<Vector2> > outlines; mutable Rect2 item_rect; mutable bool rect_cache_dirty; + Mutex navmesh_generation; + // Navigation mesh + Ref<NavigationMesh> navmesh; + protected: static void _bind_methods(); @@ -62,16 +67,16 @@ public: bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; #endif - void set_vertices(const PoolVector<Vector2> &p_vertices); - PoolVector<Vector2> get_vertices() const; + void set_vertices(const Vector<Vector2> &p_vertices); + Vector<Vector2> get_vertices() const; void add_polygon(const Vector<int> &p_polygon); int get_polygon_count() const; - void add_outline(const PoolVector<Vector2> &p_outline); - void add_outline_at_index(const PoolVector<Vector2> &p_outline, int p_index); - void set_outline(int p_idx, const PoolVector<Vector2> &p_outline); - PoolVector<Vector2> get_outline(int p_idx) const; + void add_outline(const Vector<Vector2> &p_outline); + void add_outline_at_index(const Vector<Vector2> &p_outline, int p_index); + void set_outline(int p_idx, const Vector<Vector2> &p_outline); + Vector<Vector2> get_outline(int p_idx) const; void remove_outline(int p_idx); int get_outline_count() const; @@ -81,17 +86,20 @@ public: Vector<int> get_polygon(int p_idx); void clear_polygons(); + Ref<NavigationMesh> get_mesh(); + NavigationPolygon(); + ~NavigationPolygon(); }; class Navigation2D; -class NavigationPolygonInstance : public Node2D { +class NavigationRegion2D : public Node2D { - GDCLASS(NavigationPolygonInstance, Node2D); + GDCLASS(NavigationRegion2D, Node2D); bool enabled; - int nav_id; + RID region; Navigation2D *navigation; Ref<NavigationPolygon> navpoly; @@ -115,7 +123,8 @@ public: String get_configuration_warning() const; - NavigationPolygonInstance(); + NavigationRegion2D(); + ~NavigationRegion2D(); }; #endif // NAVIGATIONPOLYGON_H diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 7deebe9b27..df21538609 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -440,14 +440,14 @@ void Node2D::_bind_methods() { ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rotation", PROPERTY_HINT_NONE, "", 0), "set_global_rotation", "get_global_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rotation_degrees", PROPERTY_HINT_NONE, "", 0), "set_global_rotation_degrees", "get_global_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "global_rotation", PROPERTY_HINT_NONE, "", 0), "set_global_rotation", "get_global_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "global_rotation_degrees", PROPERTY_HINT_NONE, "", 0), "set_global_rotation_degrees", "get_global_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_scale", PROPERTY_HINT_NONE, "", 0), "set_global_scale", "get_global_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 746feeaa82..2ba2fd8f79 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -268,22 +268,22 @@ Rect2 Particles2D::capture_rect() const { return r; } -void Particles2D::set_texture(const Ref<Texture> &p_texture) { +void Particles2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); } -Ref<Texture> Particles2D::get_texture() const { +Ref<Texture2D> Particles2D::get_texture() const { return texture; } -void Particles2D::set_normal_map(const Ref<Texture> &p_normal_map) { +void Particles2D::set_normal_map(const Ref<Texture2D> &p_normal_map) { normal_map = p_normal_map; update(); } -Ref<Texture> Particles2D::get_normal_map() const { +Ref<Texture2D> Particles2D::get_normal_map() const { return normal_map; } @@ -384,12 +384,12 @@ void Particles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -399,8 +399,8 @@ void Particles2D::_bind_methods() { ADD_GROUP("Process Material", "process_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Textures", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 56c328fc38..66281d7950 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -64,8 +64,8 @@ private: DrawOrder draw_order; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; void _update_particle_emission_transform(); @@ -108,11 +108,11 @@ public: void set_draw_order(DrawOrder p_order); DrawOrder get_draw_order() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_normal_map); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_normal_map); + Ref<Texture2D> get_normal_map() const; virtual String get_configuration_warning() const; diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index ef7c343c1a..3e807f12dc 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -112,7 +112,7 @@ void Path2D::_notification(int p_what) { real_t frac = j / 8.0; Vector2 p = curve->interpolate(i, frac); - draw_line(prev_p, p, color, line_width, true); + draw_line(prev_p, p, color, line_width); prev_p = p; } } @@ -134,13 +134,13 @@ void Path2D::_curve_changed() { void Path2D::set_curve(const Ref<Curve2D> &p_curve) { if (curve.is_valid()) { - curve->disconnect("changed", this, "_curve_changed"); + curve->disconnect("changed", callable_mp(this, &Path2D::_curve_changed)); } curve = p_curve; if (curve.is_valid()) { - curve->connect("changed", this, "_curve_changed"); + curve->connect("changed", callable_mp(this, &Path2D::_curve_changed)); } _curve_changed(); @@ -155,7 +155,6 @@ void Path2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve); - ClassDB::bind_method(D_METHOD("_curve_changed"), &Path2D::_curve_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve2D"), "set_curve", "get_curve"); } @@ -308,14 +307,14 @@ void PathFollow2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead); ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotate"), "set_rotate", "is_rotating"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"), "set_lookahead", "get_lookahead"); } void PathFollow2D::set_offset(float p_offset) { diff --git a/scene/2d/path_texture.cpp b/scene/2d/path_texture.cpp index df59c9e2bb..590f70a1b2 100644 --- a/scene/2d/path_texture.cpp +++ b/scene/2d/path_texture.cpp @@ -30,33 +30,33 @@ #include "path_texture.h" -void PathTexture::set_begin_texture(const Ref<Texture> &p_texture) { +void PathTexture::set_begin_texture(const Ref<Texture2D> &p_texture) { begin = p_texture; update(); } -Ref<Texture> PathTexture::get_begin_texture() const { +Ref<Texture2D> PathTexture::get_begin_texture() const { return begin; } -void PathTexture::set_repeat_texture(const Ref<Texture> &p_texture) { +void PathTexture::set_repeat_texture(const Ref<Texture2D> &p_texture) { repeat = p_texture; update(); } -Ref<Texture> PathTexture::get_repeat_texture() const { +Ref<Texture2D> PathTexture::get_repeat_texture() const { return repeat; } -void PathTexture::set_end_texture(const Ref<Texture> &p_texture) { +void PathTexture::set_end_texture(const Ref<Texture2D> &p_texture) { end = p_texture; update(); } -Ref<Texture> PathTexture::get_end_texture() const { +Ref<Texture2D> PathTexture::get_end_texture() const { return end; } diff --git a/scene/2d/path_texture.h b/scene/2d/path_texture.h index 9cfa004cfb..014d0dc959 100644 --- a/scene/2d/path_texture.h +++ b/scene/2d/path_texture.h @@ -36,21 +36,21 @@ class PathTexture : public Node2D { GDCLASS(PathTexture, Node2D); - Ref<Texture> begin; - Ref<Texture> repeat; - Ref<Texture> end; + Ref<Texture2D> begin; + Ref<Texture2D> repeat; + Ref<Texture2D> end; int subdivs; bool overlap; public: - void set_begin_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_begin_texture() const; + void set_begin_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_begin_texture() const; - void set_repeat_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_repeat_texture() const; + void set_repeat_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_repeat_texture() const; - void set_end_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_end_texture() const; + void set_end_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_end_texture() const; void set_subdivisions(int p_amount); int get_subdivisions() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index d42bd6adaf..9bfeca7e56 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -190,74 +190,17 @@ real_t StaticBody2D::get_constant_angular_velocity() const { return constant_angular_velocity; } -#ifndef DISABLE_DEPRECATED -void StaticBody2D::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} - -real_t StaticBody2D::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void StaticBody2D::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} - -real_t StaticBody2D::get_bounce() const { - - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif // DISABLE_DEPRECATED - void StaticBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody2D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -273,25 +216,11 @@ void StaticBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody2D::get_constant_angular_velocity); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody2D::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody2D::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody2D::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody2D::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody2D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody2D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody2D::_reload_physics_characteristics); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); } @@ -381,8 +310,8 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap //E->get().rc=0; E->get().in_scene = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree), make_binds(objid)); if (E->get().in_scene) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -410,8 +339,8 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (E->get().shapes.empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); if (in_scene) emit_signal(SceneStringNames::get_singleton()->body_exited, node); } @@ -613,72 +542,17 @@ real_t RigidBody2D::get_weight() const { return mass * (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10); } -#ifndef DISABLE_DEPRECATED -void RigidBody2D::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} -real_t RigidBody2D::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void RigidBody2D::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} -real_t RigidBody2D::get_bounce() const { - - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif // DISABLE_DEPRECATED - void RigidBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -900,9 +774,8 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree)); } } @@ -968,19 +841,9 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody2D::set_weight); ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody2D::get_weight); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody2D::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody2D::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody2D::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody2D::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody2D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody2D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody2D::_reload_physics_characteristics); - ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody2D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody2D::get_gravity_scale); @@ -1032,23 +895,17 @@ void RigidBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("test_motion", "motion", "infinite_inertia", "margin", "result"), &RigidBody2D::_test_motion, DEFVAL(true), DEFVAL(0.08), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("_direct_state_changed"), &RigidBody2D::_direct_state_changed); - ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody2D::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody2D::_body_exit_tree); ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "Physics2DDirectBodyState"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported"); @@ -1057,13 +914,13 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_GROUP("Angular", "angular_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_GROUP("Applied Forces", "applied_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); @@ -1495,7 +1352,7 @@ void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody2D::_direct_state_changed); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled"); } @@ -1544,7 +1401,7 @@ Object *KinematicCollision2D::get_local_shape() const { Object *KinematicCollision2D::get_collider() const { - if (collision.collider) { + if (collision.collider.is_valid()) { return ObjectDB::get_instance(collision.collider); } @@ -1608,7 +1465,7 @@ void KinematicCollision2D::_bind_methods() { } KinematicCollision2D::KinematicCollision2D() { - collision.collider = 0; + collision.collider_shape = 0; collision.local_shape = 0; owner = NULL; diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 6766bafde3..20e9f3ffcf 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -87,13 +87,6 @@ protected: static void _bind_methods(); public: -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -211,14 +204,6 @@ public: void set_weight(real_t p_weight); real_t get_weight() const; -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif - void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index a6da027e0a..95656b9610 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -61,7 +61,7 @@ bool Polygon2D::_edit_use_pivot() const { Rect2 Polygon2D::_edit_get_rect() const { if (rect_cache_dirty) { int l = polygon.size(); - PoolVector<Vector2>::Read r = polygon.read(); + const Vector2 *r = polygon.ptr(); item_rect = Rect2(); for (int i = 0; i < l; i++) { Vector2 pos = r[i] + offset; @@ -108,7 +108,7 @@ void Polygon2D::_notification(int p_what) { skeleton_node = Object::cast_to<Skeleton2D>(get_node(skeleton)); } - ObjectID new_skeleton_id = 0; + ObjectID new_skeleton_id; if (skeleton_node) { VS::get_singleton()->canvas_item_attach_skeleton(get_canvas_item(), skeleton_node->get_skeleton()); @@ -120,11 +120,11 @@ void Polygon2D::_notification(int p_what) { if (new_skeleton_id != current_skeleton_id) { Object *old_skeleton = ObjectDB::get_instance(current_skeleton_id); if (old_skeleton) { - old_skeleton->disconnect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + old_skeleton->disconnect("bone_setup_changed", callable_mp(this, &Polygon2D::_skeleton_bone_setup_changed)); } if (skeleton_node) { - skeleton_node->connect("bone_setup_changed", this, "_skeleton_bone_setup_changed"); + skeleton_node->connect("bone_setup_changed", callable_mp(this, &Polygon2D::_skeleton_bone_setup_changed)); } current_skeleton_id = new_skeleton_id; @@ -148,7 +148,7 @@ void Polygon2D::_notification(int p_what) { { - PoolVector<Vector2>::Read polyr = polygon.read(); + const Vector2 *polyr = polygon.ptr(); for (int i = 0; i < len; i++) { points.write[i] = polyr[i] + offset; } @@ -217,7 +217,7 @@ void Polygon2D::_notification(int p_what) { if (points.size() == uv.size()) { - PoolVector<Vector2>::Read uvr = uv.read(); + const Vector2 *uvr = uv.ptr(); for (int i = 0; i < len; i++) { uvs.write[i] = texmat.xform(uvr[i]) / tex_size; @@ -257,7 +257,7 @@ void Polygon2D::_notification(int p_what) { } int bone_index = bone->get_index_in_skeleton(); - PoolVector<float>::Read r = bone_weights[i].weights.read(); + const float *r = bone_weights[i].weights.ptr(); for (int j = 0; j < vc; j++) { if (r[j] == 0.0) continue; //weight is unpainted, skip @@ -296,7 +296,7 @@ void Polygon2D::_notification(int p_what) { Vector<Color> colors; if (vertex_colors.size() == points.size()) { colors.resize(len); - PoolVector<Color>::Read color_r = vertex_colors.read(); + const Color *color_r = vertex_colors.ptr(); for (int i = 0; i < len; i++) { colors.write[i] = color_r[i]; } @@ -304,23 +304,20 @@ void Polygon2D::_notification(int p_what) { colors.push_back(color); } - // Vector<int> indices = Geometry::triangulate_polygon(points); - // VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, texture.is_valid() ? texture->get_rid() : RID()); - if (invert || polygons.size() == 0) { Vector<int> indices = Geometry::triangulate_polygon(points); if (indices.size()) { - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased); + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, normal_map.is_valid() ? normal_map->get_rid() : RID(), specular_map.is_valid() ? specular_map->get_rid() : RID(), Color(specular_color.r, specular_color.g, specular_color.b, shininess)); } } else { //draw individual polygons Vector<int> total_indices; for (int i = 0; i < polygons.size(); i++) { - PoolVector<int> src_indices = polygons[i]; + Vector<int> src_indices = polygons[i]; int ic = src_indices.size(); if (ic < 3) continue; - PoolVector<int>::Read r = src_indices.read(); + const int *r = src_indices.ptr(); Vector<Vector2> tmp_points; tmp_points.resize(ic); @@ -344,7 +341,7 @@ void Polygon2D::_notification(int p_what) { } if (total_indices.size()) { - VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased); + VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID()); } } @@ -352,13 +349,13 @@ void Polygon2D::_notification(int p_what) { } } -void Polygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) { +void Polygon2D::set_polygon(const Vector<Vector2> &p_polygon) { polygon = p_polygon; rect_cache_dirty = true; update(); } -PoolVector<Vector2> Polygon2D::get_polygon() const { +Vector<Vector2> Polygon2D::get_polygon() const { return polygon; } @@ -372,13 +369,13 @@ int Polygon2D::get_internal_vertex_count() const { return internal_vertices; } -void Polygon2D::set_uv(const PoolVector<Vector2> &p_uv) { +void Polygon2D::set_uv(const Vector<Vector2> &p_uv) { uv = p_uv; update(); } -PoolVector<Vector2> Polygon2D::get_uv() const { +Vector<Vector2> Polygon2D::get_uv() const { return uv; } @@ -404,17 +401,17 @@ Color Polygon2D::get_color() const { return color; } -void Polygon2D::set_vertex_colors(const PoolVector<Color> &p_colors) { +void Polygon2D::set_vertex_colors(const Vector<Color> &p_colors) { vertex_colors = p_colors; update(); } -PoolVector<Color> Polygon2D::get_vertex_colors() const { +Vector<Color> Polygon2D::get_vertex_colors() const { return vertex_colors; } -void Polygon2D::set_texture(const Ref<Texture> &p_texture) { +void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; @@ -428,11 +425,47 @@ void Polygon2D::set_texture(const Ref<Texture> &p_texture) { }*/ update(); } -Ref<Texture> Polygon2D::get_texture() const { +Ref<Texture2D> Polygon2D::get_texture() const { return texture; } +void Polygon2D::set_normal_map(const Ref<Texture2D> &p_normal_map) { + normal_map = p_normal_map; + update(); +} + +Ref<Texture2D> Polygon2D::get_normal_map() const { + return normal_map; +} + +void Polygon2D::set_specular_map(const Ref<Texture2D> &p_specular_map) { + specular_map = p_specular_map; + update(); +} + +Ref<Texture2D> Polygon2D::get_specular_map() const { + return specular_map; +} + +void Polygon2D::set_specular_color(const Color &p_specular_color) { + specular_color = p_specular_color; + update(); +} + +Color Polygon2D::get_specular_color() const { + return specular_color; +} + +void Polygon2D::set_shininess(float p_shininess) { + shininess = CLAMP(p_shininess, 0.0, 1.0); + update(); +} + +float Polygon2D::get_shininess() const { + return shininess; +} + void Polygon2D::set_texture_offset(const Vector2 &p_offset) { tex_ofs = p_offset; @@ -515,7 +548,7 @@ Vector2 Polygon2D::get_offset() const { return offset; } -void Polygon2D::add_bone(const NodePath &p_path, const PoolVector<float> &p_weights) { +void Polygon2D::add_bone(const NodePath &p_path, const Vector<float> &p_weights) { Bone bone; bone.path = p_path; @@ -529,9 +562,9 @@ NodePath Polygon2D::get_bone_path(int p_index) const { ERR_FAIL_INDEX_V(p_index, bone_weights.size(), NodePath()); return bone_weights[p_index].path; } -PoolVector<float> Polygon2D::get_bone_weights(int p_index) const { +Vector<float> Polygon2D::get_bone_weights(int p_index) const { - ERR_FAIL_INDEX_V(p_index, bone_weights.size(), PoolVector<float>()); + ERR_FAIL_INDEX_V(p_index, bone_weights.size(), Vector<float>()); return bone_weights[p_index].weights; } void Polygon2D::erase_bone(int p_idx) { @@ -544,7 +577,7 @@ void Polygon2D::clear_bones() { bone_weights.clear(); } -void Polygon2D::set_bone_weights(int p_index, const PoolVector<float> &p_weights) { +void Polygon2D::set_bone_weights(int p_index, const Vector<float> &p_weights) { ERR_FAIL_INDEX(p_index, bone_weights.size()); bone_weights.write[p_index].weights = p_weights; update(); @@ -603,6 +636,18 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Polygon2D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &Polygon2D::get_texture); + ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Polygon2D::set_normal_map); + ClassDB::bind_method(D_METHOD("get_normal_map"), &Polygon2D::get_normal_map); + + ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Polygon2D::set_specular_map); + ClassDB::bind_method(D_METHOD("get_specular_map"), &Polygon2D::get_specular_map); + + ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Polygon2D::set_specular_color); + ClassDB::bind_method(D_METHOD("get_specular_color"), &Polygon2D::get_specular_color); + + ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Polygon2D::set_shininess); + ClassDB::bind_method(D_METHOD("get_shininess"), &Polygon2D::get_shininess); + ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &Polygon2D::set_texture_offset); ClassDB::bind_method(D_METHOD("get_texture_offset"), &Polygon2D::get_texture_offset); @@ -645,29 +690,32 @@ void Polygon2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_bones", "bones"), &Polygon2D::_set_bones); ClassDB::bind_method(D_METHOD("_get_bones"), &Polygon2D::_get_bones); - ClassDB::bind_method(D_METHOD("_skeleton_bone_setup_changed"), &Polygon2D::_skeleton_bone_setup_changed); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "get_antialiased"); - ADD_GROUP("Texture", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_GROUP("Texture", "texture_"); + ADD_GROUP("Texture2D", ""); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_GROUP("Texture2D", "texture_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_offset"), "set_texture_offset", "get_texture_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_scale"), "set_texture_scale", "get_texture_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_texture_rotation_degrees", "get_texture_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation"); + ADD_GROUP("Lighting", ""); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); ADD_GROUP("Skeleton", ""); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton"); ADD_GROUP("Invert", "invert_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "invert_border", PROPERTY_HINT_RANGE, "0.1,16384,0.1"), "set_invert_border", "get_invert_border"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "invert_border", PROPERTY_HINT_RANGE, "0.1,16384,0.1"), "set_invert_border", "get_invert_border"); ADD_GROUP("Data", ""); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_bones", "_get_bones"); ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count"); @@ -684,5 +732,7 @@ Polygon2D::Polygon2D() { color = Color(1, 1, 1); rect_cache_dirty = true; internal_vertices = 0; - current_skeleton_id = 0; + + specular_color = Color(1, 1, 1, 1); + shininess = 1.0; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 07b8828532..777c1f82f3 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -37,21 +37,26 @@ class Polygon2D : public Node2D { GDCLASS(Polygon2D, Node2D); - PoolVector<Vector2> polygon; - PoolVector<Vector2> uv; - PoolVector<Color> vertex_colors; + Vector<Vector2> polygon; + Vector<Vector2> uv; + Vector<Color> vertex_colors; Array polygons; int internal_vertices; struct Bone { NodePath path; - PoolVector<float> weights; + Vector<float> weights; }; Vector<Bone> bone_weights; Color color; - Ref<Texture> texture; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; + Ref<Texture2D> specular_map; + Color specular_color; + float shininess; + Size2 tex_scale; Vector2 tex_ofs; bool tex_tile; @@ -90,14 +95,14 @@ public: virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; #endif - void set_polygon(const PoolVector<Vector2> &p_polygon); - PoolVector<Vector2> get_polygon() const; + void set_polygon(const Vector<Vector2> &p_polygon); + Vector<Vector2> get_polygon() const; void set_internal_vertex_count(int p_count); int get_internal_vertex_count() const; - void set_uv(const PoolVector<Vector2> &p_uv); - PoolVector<Vector2> get_uv() const; + void set_uv(const Vector<Vector2> &p_uv); + Vector<Vector2> get_uv() const; void set_polygons(const Array &p_polygons); Array get_polygons() const; @@ -105,11 +110,23 @@ public: void set_color(const Color &p_color); Color get_color() const; - void set_vertex_colors(const PoolVector<Color> &p_colors); - PoolVector<Color> get_vertex_colors() const; + void set_vertex_colors(const Vector<Color> &p_colors); + Vector<Color> get_vertex_colors() const; + + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; + + void set_normal_map(const Ref<Texture2D> &p_normal_map); + Ref<Texture2D> get_normal_map() const; + + void set_specular_map(const Ref<Texture2D> &p_specular_map); + Ref<Texture2D> get_specular_map() const; + + void set_specular_color(const Color &p_specular_color); + Color get_specular_color() const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_shininess(float p_shininess); + float get_shininess() const; void set_texture_offset(const Vector2 &p_offset); Vector2 get_texture_offset() const; @@ -135,13 +152,13 @@ public: void set_offset(const Vector2 &p_offset); Vector2 get_offset() const; - void add_bone(const NodePath &p_path = NodePath(), const PoolVector<float> &p_weights = PoolVector<float>()); + void add_bone(const NodePath &p_path = NodePath(), const Vector<float> &p_weights = Vector<float>()); int get_bone_count() const; NodePath get_bone_path(int p_index) const; - PoolVector<float> get_bone_weights(int p_index) const; + Vector<float> get_bone_weights(int p_index) const; void erase_bone(int p_idx); void clear_bones(); - void set_bone_weights(int p_index, const PoolVector<float> &p_weights); + void set_bone_weights(int p_index, const Vector<float> &p_weights); void set_bone_path(int p_index, const NodePath &p_path); void set_skeleton(const NodePath &p_skeleton); diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index cdeb905c0c..9e95a55d9f 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -96,7 +96,7 @@ void Position2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_gizmo_extents", "extents"), &Position2D::set_gizmo_extents); ClassDB::bind_method(D_METHOD("_get_gizmo_extents"), &Position2D::get_gizmo_extents); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gizmo_extents", PROPERTY_HINT_RANGE, "0,1000,0.1,or_greater", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_gizmo_extents", "_get_gizmo_extents"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gizmo_extents", PROPERTY_HINT_RANGE, "0,1000,0.1,or_greater", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_gizmo_extents", "_get_gizmo_extents"); } Position2D::Position2D() { diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 5098d5115a..fd6e0aebcc 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -78,7 +78,7 @@ bool RayCast2D::is_colliding() const { } Object *RayCast2D::get_collider() const { - if (against == 0) + if (against.is_null()) return NULL; return ObjectDB::get_instance(against); @@ -176,7 +176,7 @@ void RayCast2D::_notification(int p_what) { draw_col.g = g; draw_col.b = g; } - draw_line(Vector2(), cast_to, draw_col, 2, true); + draw_line(Vector2(), cast_to, draw_col, 2); Vector<Vector2> pts; float tsize = 8; pts.push_back(xf.xform(Vector2(tsize, 0))); @@ -225,7 +225,7 @@ void RayCast2D::_update_raycast_state() { against_shape = rr.shape; } else { collided = false; - against = 0; + against = ObjectID(); against_shape = 0; } } @@ -339,7 +339,7 @@ void RayCast2D::_bind_methods() { RayCast2D::RayCast2D() { enabled = false; - against = 0; + collided = false; against_shape = 0; collision_mask = 1; diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 53072f942d..ec50f5f922 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -33,7 +33,7 @@ void RemoteTransform2D::_update_cache() { - cache = 0; + cache = ObjectID(); if (has_node(remote_node)) { Node *node = get_node(remote_node); if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) { @@ -49,7 +49,7 @@ void RemoteTransform2D::_update_remote() { if (!is_inside_tree()) return; - if (!cache) + if (cache.is_null()) return; Node2D *n = Object::cast_to<Node2D>(ObjectDB::get_instance(cache)); @@ -119,7 +119,7 @@ void RemoteTransform2D::_notification(int p_what) { if (!is_inside_tree()) break; - if (cache) { + if (cache.is_valid()) { _update_remote(); } @@ -225,6 +225,5 @@ RemoteTransform2D::RemoteTransform2D() { update_remote_rotation = true; update_remote_scale = true; - cache = 0; set_notify_transform(true); } diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 6f64464cc9..9ebaf23c3a 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -90,7 +90,7 @@ void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_default_length"), &Bone2D::get_default_length); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "rest"), "set_rest", "get_rest"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_length", PROPERTY_HINT_RANGE, "1,1024,1"), "set_default_length", "get_default_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_length", PROPERTY_HINT_RANGE, "1,1024,1"), "set_default_length", "get_default_length"); } void Bone2D::set_rest(const Transform2D &p_rest) { diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 55daed0585..7eaafe5348 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "sprite.h" + #include "core/core_string_names.h" #include "core/os/os.h" #include "scene/main/viewport.h" @@ -130,24 +131,24 @@ void Sprite::_notification(int p_what) { Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); - texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip); + texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess), VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, filter_clip); } break; } } -void Sprite::set_texture(const Ref<Texture> &p_texture) { +void Sprite::set_texture(const Ref<Texture2D> &p_texture) { if (p_texture == texture) return; if (texture.is_valid()) - texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite::_texture_changed)); texture = p_texture; if (texture.is_valid()) - texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite::_texture_changed)); update(); emit_signal("texture_changed"); @@ -155,18 +156,47 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { _change_notify("texture"); } -void Sprite::set_normal_map(const Ref<Texture> &p_texture) { +void Sprite::set_normal_map(const Ref<Texture2D> &p_texture) { normal_map = p_texture; update(); } -Ref<Texture> Sprite::get_normal_map() const { +Ref<Texture2D> Sprite::get_normal_map() const { return normal_map; } -Ref<Texture> Sprite::get_texture() const { +void Sprite::set_specular_map(const Ref<Texture2D> &p_texture) { + + specular = p_texture; + update(); +} + +Ref<Texture2D> Sprite::get_specular_map() const { + + return specular; +} + +void Sprite::set_specular_color(const Color &p_color) { + specular_color = p_color; + update(); +} + +Color Sprite::get_specular_color() const { + return specular_color; +} + +void Sprite::set_shininess(float p_shininess) { + shininess = CLAMP(p_shininess, 0.0, 1.0); + update(); +} + +float Sprite::get_shininess() const { + return shininess; +} + +Ref<Texture2D> Sprite::get_texture() const { return texture; } @@ -334,9 +364,11 @@ bool Sprite::is_pixel_opaque(const Point2 &p_point) const { if (vflip) q.y = 1.0f - q.y; q = q * src_rect.size + src_rect.position; - - bool is_repeat = texture->get_flags() & Texture::FLAG_REPEAT; - bool is_mirrored_repeat = texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT; +#ifndef _MSC_VER +#warning this need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that) +#endif + bool is_repeat = false; + bool is_mirrored_repeat = false; if (is_repeat) { int mirror_x = 0; int mirror_y = 0; @@ -415,6 +447,15 @@ void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &Sprite::set_normal_map); ClassDB::bind_method(D_METHOD("get_normal_map"), &Sprite::get_normal_map); + ClassDB::bind_method(D_METHOD("set_specular_map", "specular_map"), &Sprite::set_specular_map); + ClassDB::bind_method(D_METHOD("get_specular_map"), &Sprite::get_specular_map); + + ClassDB::bind_method(D_METHOD("set_specular_color", "specular_color"), &Sprite::set_specular_color); + ClassDB::bind_method(D_METHOD("get_specular_color"), &Sprite::get_specular_color); + + ClassDB::bind_method(D_METHOD("set_shininess", "shininess"), &Sprite::set_shininess); + ClassDB::bind_method(D_METHOD("get_shininess"), &Sprite::get_shininess); + ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite::set_centered); ClassDB::bind_method(D_METHOD("is_centered"), &Sprite::is_centered); @@ -452,13 +493,15 @@ void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rect"), &Sprite::get_rect); - ClassDB::bind_method(D_METHOD("_texture_changed"), &Sprite::_texture_changed); - ADD_SIGNAL(MethodInfo("frame_changed")); ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_GROUP("Lighting", ""); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "specular_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_specular_map", "get_specular_map"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_shininess", "get_shininess"); ADD_GROUP("Offset", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); @@ -483,6 +526,8 @@ Sprite::Sprite() { vflip = false; region = false; region_filter_clip = false; + shininess = 1.0; + specular_color = Color(1, 1, 1, 1); frame = 0; diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index d72bf3168d..a96f023231 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -38,8 +38,11 @@ class Sprite : public Node2D { GDCLASS(Sprite, Node2D); - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; + Ref<Texture2D> specular; + Color specular_color; + float shininess; bool centered; Point2 offset; @@ -82,11 +85,20 @@ public: bool is_pixel_opaque(const Point2 &p_point) const; - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(const Ref<Texture> &p_texture); - Ref<Texture> get_normal_map() const; + void set_normal_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_normal_map() const; + + void set_specular_map(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_specular_map() const; + + void set_specular_color(const Color &p_color); + Color get_specular_color() const; + + void set_shininess(float p_shininess); + float get_shininess() const; void set_centered(bool p_center); bool is_centered() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index b6db025d44..601be17274 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -35,6 +35,7 @@ #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "scene/2d/area_2d.h" +#include "servers/navigation_2d_server.h" #include "servers/physics_2d_server.h" int TileMap::_get_quadrant_size() const { @@ -86,7 +87,7 @@ void TileMap::_notification(int p_what) { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_remove(F->get().id); + Navigation2DServer::get_singleton()->region_set_map(F->get().region, RID()); } q.navpoly_ids.clear(); } @@ -163,7 +164,7 @@ void TileMap::_update_quadrant_transform() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) { - navigation->navpoly_set_transform(F->get().id, nav_rel * F->get().xform); + Navigation2DServer::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform); } } @@ -176,7 +177,7 @@ void TileMap::_update_quadrant_transform() { void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { if (tile_set.is_valid()) { - tile_set->disconnect("changed", this, "_recreate_quadrants"); + tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->remove_change_receptor(this); } @@ -184,7 +185,7 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { tile_set = p_tileset; if (tile_set.is_valid()) { - tile_set->connect("changed", this, "_recreate_quadrants"); + tile_set->connect("changed", callable_mp(this, &TileMap::_recreate_quadrants)); tile_set->add_change_receptor(this); } else { clear(); @@ -377,7 +378,7 @@ void TileMap::update_dirty_quadrants() { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - navigation->navpoly_remove(E->get().id); + Navigation2DServer::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); } @@ -398,7 +399,7 @@ void TileMap::update_dirty_quadrants() { //moment of truth if (!tile_set->has_tile(c.id)) continue; - Ref<Texture> tex = tile_set->tile_get_texture(c.id); + Ref<Texture2D> tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); Vector2 wofs = _map_to_world(E->key().x, E->key().y); @@ -541,7 +542,7 @@ void TileMap::update_dirty_quadrants() { rect.position += tile_ofs; } - Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id); + Ref<Texture2D> normal_map = tile_set->tile_get_normal_map(c.id); Color modulate = tile_set->tile_get_modulate(c.id); Color self_modulate = get_self_modulate(); modulate = Color(modulate.r * self_modulate.r, modulate.g * self_modulate.g, @@ -549,7 +550,7 @@ void TileMap::update_dirty_quadrants() { if (r == Rect2()) { tex->draw_rect(canvas_item, rect, false, modulate, c.transpose, normal_map); } else { - tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, clip_uv); + tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose, normal_map, Ref<Texture2D>(), Color(1, 1, 1, 1), VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, clip_uv); } Vector<TileSet::ShapeData> shapes = tile_set->tile_get_shapes(c.id); @@ -611,10 +612,13 @@ void TileMap::update_dirty_quadrants() { xform.set_origin(offset.floor() + q.pos); _fix_cell_transform(xform, c, npoly_ofs, s); - int pid = navigation->navpoly_add(navpoly, nav_rel * xform); + RID region = Navigation2DServer::get_singleton()->region_create(); + Navigation2DServer::get_singleton()->region_set_map(region, navigation->get_rid()); + Navigation2DServer::get_singleton()->region_set_transform(region, nav_rel * xform); + Navigation2DServer::get_singleton()->region_set_navpoly(region, navpoly); Quadrant::NavPoly np; - np.id = pid; + np.region = region; np.xform = xform; q.navpoly_ids[E->key()] = np; @@ -625,7 +629,7 @@ void TileMap::update_dirty_quadrants() { vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug if (debug_navigation_item.is_valid()) { - PoolVector<Vector2> navigation_polygon_vertices = navpoly->get_vertices(); + Vector<Vector2> navigation_polygon_vertices = navpoly->get_vertices(); int vsize = navigation_polygon_vertices.size(); if (vsize > 2) { @@ -634,7 +638,7 @@ void TileMap::update_dirty_quadrants() { vertices.resize(vsize); colors.resize(vsize); { - PoolVector<Vector2>::Read vr = navigation_polygon_vertices.read(); + const Vector2 *vr = navigation_polygon_vertices.ptr(); for (int j = 0; j < vsize; j++) { vertices.write[j] = vr[j]; colors.write[j] = debug_navigation_color; @@ -809,7 +813,7 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) { if (navigation) { for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) { - navigation->navpoly_remove(E->get().id); + Navigation2DServer::get_singleton()->region_set_map(E->get().region, RID()); } q.navpoly_ids.clear(); } @@ -849,7 +853,7 @@ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) { Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"]; const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord }; - Variant::CallError ce; + Callable::CallError ce; call("set_cell", args, 7, ce); } @@ -1203,12 +1207,12 @@ void TileMap::clear() { used_size_cache_dirty = true; } -void TileMap::_set_tile_data(const PoolVector<int> &p_data) { +void TileMap::_set_tile_data(const Vector<int> &p_data) { ERR_FAIL_COND(format > FORMAT_2); int c = p_data.size(); - PoolVector<int>::Read r = p_data.read(); + const int *r = p_data.ptr(); int offset = (format == FORMAT_2) ? 3 : 2; @@ -1251,11 +1255,11 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { } } -PoolVector<int> TileMap::_get_tile_data() const { +Vector<int> TileMap::_get_tile_data() const { - PoolVector<int> data; + Vector<int> data; data.resize(tile_map.size() * 3); - PoolVector<int>::Write w = data.write(); + int *w = data.ptrw(); // Save in highest format @@ -1277,8 +1281,6 @@ PoolVector<int> TileMap::_get_tile_data() const { idx += 3; } - w.release(); - return data; } @@ -1881,7 +1883,6 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map); ClassDB::bind_method(D_METHOD("_clear_quadrants"), &TileMap::_clear_quadrants); - ClassDB::bind_method(D_METHOD("_recreate_quadrants"), &TileMap::_recreate_quadrants); ClassDB::bind_method(D_METHOD("update_dirty_quadrants"), &TileMap::update_dirty_quadrants); ClassDB::bind_method(D_METHOD("update_bitmask_area", "position"), &TileMap::update_bitmask_area); @@ -1907,8 +1908,8 @@ void TileMap::_bind_methods() { ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_parent", PROPERTY_HINT_NONE, ""), "set_collision_use_parent", "get_collision_use_parent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 0875d197eb..d9490aae13 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -139,7 +139,7 @@ private: SelfList<Quadrant> dirty_list; struct NavPoly { - int id; + RID region; Transform2D xform; }; @@ -220,8 +220,8 @@ private: _FORCE_INLINE_ int _get_quadrant_size() const; - void _set_tile_data(const PoolVector<int> &p_data); - PoolVector<int> _get_tile_data() const; + void _set_tile_data(const Vector<int> &p_data); + Vector<int> _get_tile_data() const; void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size, p_size)); } int _get_old_cell_size() const { return cell_size.x; } diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 42d9f88a60..1cca45b422 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -34,24 +34,24 @@ #include "core/os/input.h" #include "core/os/os.h" -void TouchScreenButton::set_texture(const Ref<Texture> &p_texture) { +void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) { texture = p_texture; update(); } -Ref<Texture> TouchScreenButton::get_texture() const { +Ref<Texture2D> TouchScreenButton::get_texture() const { return texture; } -void TouchScreenButton::set_texture_pressed(const Ref<Texture> &p_texture_pressed) { +void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) { texture_pressed = p_texture_pressed; update(); } -Ref<Texture> TouchScreenButton::get_texture_pressed() const { +Ref<Texture2D> TouchScreenButton::get_texture_pressed() const { return texture_pressed; } @@ -69,12 +69,12 @@ Ref<BitMap> TouchScreenButton::get_bitmask() const { void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) { if (shape.is_valid()) - shape->disconnect("changed", this, "update"); + shape->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); shape = p_shape; if (shape.is_valid()) - shape->connect("changed", this, "update"); + shape->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); update(); } @@ -397,14 +397,14 @@ void TouchScreenButton::_bind_methods() { ClassDB::bind_method(D_METHOD("_input"), &TouchScreenButton::_input); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture_pressed", "get_texture_pressed"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_centered"), "set_shape_centered", "is_shape_centered"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shape_visible"), "set_shape_visible", "is_shape_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "passby_press"), "set_passby_press", "is_passby_press_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "action"), "set_action", "get_action"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Always,TouchScreen Only"), "set_visibility_mode", "get_visibility_mode"); ADD_SIGNAL(MethodInfo("pressed")); diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h index 28dba59402..42e93f7048 100644 --- a/scene/2d/touch_screen_button.h +++ b/scene/2d/touch_screen_button.h @@ -47,8 +47,8 @@ public: }; private: - Ref<Texture> texture; - Ref<Texture> texture_pressed; + Ref<Texture2D> texture; + Ref<Texture2D> texture_pressed; Ref<BitMap> bitmask; Ref<Shape2D> shape; bool shape_centered; @@ -79,11 +79,11 @@ public: virtual bool _edit_use_rect() const; #endif - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; - void set_texture_pressed(const Ref<Texture> &p_texture_pressed); - Ref<Texture> get_texture_pressed() const; + void set_texture_pressed(const Ref<Texture2D> &p_texture_pressed); + Ref<Texture2D> get_texture_pressed() const; void set_bitmask(const Ref<BitMap> &p_bitmask); Ref<BitMap> get_bitmask() const; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 0ac725b7dd..366de28386 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -224,7 +224,7 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { if (add) { - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed", varray(p_node), CONNECT_ONESHOT); + p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed), varray(p_node), CONNECT_ONESHOT); nodes[p_node] = meta; _change_node_state(p_node, false); } @@ -267,7 +267,7 @@ void VisibilityEnabler2D::_notification(int p_what) { if (!visible) _change_node_state(E->key(), true); - E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed"); + E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed)); } nodes.clear(); diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 67f57a1aa3..321926d841 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "area.h" + #include "scene/scene_string_names.h" #include "servers/audio_server.h" #include "servers/physics_server.h" @@ -147,7 +148,7 @@ void Area::_body_exit_tree(ObjectID p_id) { } } -void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape) { +void Area::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) { bool body_in = p_status == PhysicsServer::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -170,8 +171,8 @@ void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_bo E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_body_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -197,8 +198,8 @@ void Area::_body_inout(int p_status, const RID &p_body, int p_instance, int p_bo if (E->get().rc == 0) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_body_exit_tree)); if (E->get().in_tree) emit_signal(SceneStringNames::get_singleton()->body_exited, obj); } @@ -244,8 +245,8 @@ void Area::_clear_monitoring() { emit_signal(SceneStringNames::get_singleton()->body_exited, node); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_body_exit_tree)); } } @@ -274,8 +275,8 @@ void Area::_clear_monitoring() { emit_signal(SceneStringNames::get_singleton()->area_exited, obj); - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_area_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_area_exit_tree)); } } } @@ -340,7 +341,7 @@ void Area::_area_exit_tree(ObjectID p_id) { } } -void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape) { +void Area::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) { bool area_in = p_status == PhysicsServer::AREA_BODY_ADDED; ObjectID objid = p_instance; @@ -363,8 +364,8 @@ void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ar E->get().rc = 0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_area_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_area_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->area_entered, node); } @@ -390,8 +391,8 @@ void Area::_area_inout(int p_status, const RID &p_area, int p_instance, int p_ar if (E->get().rc == 0) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_area_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_area_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area::_area_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area::_area_exit_tree)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->area_exited, obj); } @@ -618,13 +619,6 @@ void Area::_validate_property(PropertyInfo &property) const { } void Area::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_body_enter_tree", "id"), &Area::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree", "id"), &Area::_body_exit_tree); - - ClassDB::bind_method(D_METHOD("_area_enter_tree", "id"), &Area::_area_enter_tree); - ClassDB::bind_method(D_METHOD("_area_exit_tree", "id"), &Area::_area_exit_tree); - ClassDB::bind_method(D_METHOD("set_space_override_mode", "enable"), &Area::set_space_override_mode); ClassDB::bind_method(D_METHOD("get_space_override_mode"), &Area::get_space_override_mode); @@ -706,11 +700,11 @@ void Area::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine"), "set_space_override_mode", "get_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point"), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); @@ -719,12 +713,12 @@ void Area::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_GROUP("Audio Bus", "audio_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus"); ADD_GROUP("Reverb Bus", "reverb_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "reverb_bus_enable"), "set_use_reverb_bus", "is_using_reverb_bus"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "reverb_bus_name", PROPERTY_HINT_ENUM, ""), "set_reverb_bus", "get_reverb_bus"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "reverb_bus_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_amount", "get_reverb_amount"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "reverb_bus_uniformity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_uniformity", "get_reverb_uniformity"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "reverb_bus_name", PROPERTY_HINT_ENUM, ""), "set_reverb_bus", "get_reverb_bus"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "reverb_bus_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_amount", "get_reverb_amount"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "reverb_bus_uniformity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_uniformity", "get_reverb_uniformity"); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_DISABLED); BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE); diff --git a/scene/3d/area.h b/scene/3d/area.h index ca66f41f60..7fe61430fa 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -62,7 +62,7 @@ private: bool monitorable; bool locked; - void _body_inout(int p_status, const RID &p_body, int p_instance, int p_body_shape, int p_area_shape); + void _body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape); void _body_enter_tree(ObjectID p_id); void _body_exit_tree(ObjectID p_id); @@ -94,7 +94,7 @@ private: Map<ObjectID, BodyState> body_map; - void _area_inout(int p_status, const RID &p_area, int p_instance, int p_area_shape, int p_self_shape); + void _area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape); void _area_enter_tree(ObjectID p_id); void _area_exit_tree(ObjectID p_id); diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 8d1556ef1c..bf85a8bd53 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -252,7 +252,7 @@ void ARVRController::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRController::get_rumble); ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRController::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); ADD_PROPERTY_DEFAULT("rumble", 0.0); ClassDB::bind_method(D_METHOD("get_mesh"), &ARVRController::get_mesh); @@ -544,7 +544,7 @@ String ARVROrigin::get_configuration_warning() const { void ARVROrigin::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &ARVROrigin::set_world_scale); ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVROrigin::get_world_scale); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); }; void ARVROrigin::set_tracked_camera(ARVRCamera *p_tracked_camera) { diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 596ef78fb5..855d254bd6 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -45,12 +45,12 @@ private: mutable real_t squared_gain; // temporary }; - PoolVector<Speaker> speakers; + Vector<Speaker> speakers; public: Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) { this->speakers.resize(speaker_count); - PoolVector<Speaker>::Write w = this->speakers.write(); + Speaker *w = this->speakers.ptrw(); for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) { w[speaker_num].direction = speaker_directions[speaker_num]; w[speaker_num].squared_gain = 0.0; @@ -66,11 +66,11 @@ public: } Vector3 get_speaker_direction(unsigned int index) const { - return this->speakers.read()[index].direction; + return this->speakers.ptr()[index].direction; } void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const { - PoolVector<Speaker>::Read r = this->speakers.read(); + const Speaker *r = this->speakers.ptr(); real_t sum_squared_gains = 0.0; for (unsigned int speaker_num = 0; speaker_num < (unsigned int)this->speakers.size(); speaker_num++) { real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers; @@ -98,11 +98,18 @@ static const Vector3 speaker_directions[7] = { void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, AudioStreamPlayer3D::Output &output) { unsigned int speaker_count; // only main speakers (no LFE) switch (AudioServer::get_singleton()->get_speaker_mode()) { - default: //fallthrough - case AudioServer::SPEAKER_MODE_STEREO: speaker_count = 2; break; - case AudioServer::SPEAKER_SURROUND_31: speaker_count = 3; break; - case AudioServer::SPEAKER_SURROUND_51: speaker_count = 5; break; - case AudioServer::SPEAKER_SURROUND_71: speaker_count = 7; break; + case AudioServer::SPEAKER_MODE_STEREO: + speaker_count = 2; + break; + case AudioServer::SPEAKER_SURROUND_31: + speaker_count = 3; + break; + case AudioServer::SPEAKER_SURROUND_51: + speaker_count = 5; + break; + case AudioServer::SPEAKER_SURROUND_71: + speaker_count = 7; + break; } Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes @@ -113,18 +120,19 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig case AudioServer::SPEAKER_SURROUND_71: output.vol[3].l = volumes[5]; // side-left output.vol[3].r = volumes[6]; // side-right - //fallthrough + [[fallthrough]]; case AudioServer::SPEAKER_SURROUND_51: output.vol[2].l = volumes[3]; // rear-left output.vol[2].r = volumes[4]; // rear-right - //fallthrough + [[fallthrough]]; case AudioServer::SPEAKER_SURROUND_31: output.vol[1].r = 1.0; // LFE - always full power output.vol[1].l = volumes[2]; // center - //fallthrough + [[fallthrough]]; case AudioServer::SPEAKER_MODE_STEREO: output.vol[0].r = volumes[1]; // front-right output.vol[0].l = volumes[0]; // front-left + break; } } @@ -1000,28 +1008,26 @@ void AudioStreamPlayer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback); - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer3D::_bus_layout_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,4096,1,or_greater"), "set_max_distance", "get_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,4096,1,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); ADD_GROUP("Emission Angle", "emission_angle"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db"); ADD_GROUP("Attenuation Filter", "attenuation_filter_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db"); ADD_GROUP("Doppler", "doppler_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); @@ -1068,7 +1074,7 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() { stream_paused_fade_out = false; velocity_tracker.instance(); - AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); + AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed)); set_disable_scale(true); } AudioStreamPlayer3D::~AudioStreamPlayer3D() { diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 071afd1a69..73b1d450f0 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#if 0 #include "baked_lightmap.h" #include "core/io/config_file.h" #include "core/io/resource_saver.h" @@ -46,12 +47,12 @@ AABB BakedLightmapData::get_bounds() const { return bounds; } -void BakedLightmapData::set_octree(const PoolVector<uint8_t> &p_octree) { +void BakedLightmapData::set_octree(const Vector<uint8_t> &p_octree) { VS::get_singleton()->lightmap_capture_set_octree(baked_light, p_octree); } -PoolVector<uint8_t> BakedLightmapData::get_octree() const { +Vector<uint8_t> BakedLightmapData::get_octree() const { return VS::get_singleton()->lightmap_capture_get_octree(baked_light); } @@ -86,7 +87,7 @@ float BakedLightmapData::get_energy() const { return energy; } -void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance) { +void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance) { ERR_FAIL_COND_MSG(p_lightmap.is_null(), "It's not a reference to a valid Texture object."); User user; @@ -105,9 +106,9 @@ NodePath BakedLightmapData::get_user_path(int p_user) const { ERR_FAIL_INDEX_V(p_user, users.size(), NodePath()); return users[p_user].path; } -Ref<Texture> BakedLightmapData::get_user_lightmap(int p_user) const { +Ref<Texture2D> BakedLightmapData::get_user_lightmap(int p_user) const { - ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Texture2D>()); return users[p_user].lightmap; } @@ -173,8 +174,8 @@ void BakedLightmapData::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "cell_space_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_space_transform", "get_cell_space_transform"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_subdiv", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_subdiv", "get_cell_subdiv"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "octree", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_octree", "get_octree"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "octree", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_octree", "get_octree"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data"); } @@ -368,7 +369,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi Ref<BakedLightmapData> new_light_data; new_light_data.instance(); - VoxelLightBaker baker; + Voxelizer baker; int bake_subdiv; int capture_subdiv; @@ -413,7 +414,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi } pmc = 0; - baker.begin_bake_light(VoxelLightBaker::BakeQuality(bake_quality), VoxelLightBaker::BakeMode(bake_mode), propagation, energy); + baker.begin_bake_light(Voxelizer::BakeQuality(bake_quality), Voxelizer::BakeMode(bake_mode), propagation, energy); for (List<PlotLight>::Element *E = light_list.front(); E; E = E->next()) { @@ -465,7 +466,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi used_mesh_names.insert(mesh_name); pmc++; - VoxelLightBaker::LightMapData lm; + Voxelizer::LightMapData lm; Error err; if (bake_step_function) { @@ -491,17 +492,16 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi Ref<Image> image; image.instance(); - uint32_t tex_flags = Texture::FLAGS_DEFAULT; if (hdr) { //just save a regular image - PoolVector<uint8_t> data; + Vector<uint8_t> data; int s = lm.light.size(); data.resize(lm.light.size() * 2); { - PoolVector<uint8_t>::Write w = data.write(); - PoolVector<float>::Read r = lm.light.read(); + uint8_t* w = data.ptrw(); + const float* r = lm.light.ptr(); uint16_t *hfw = (uint16_t *)w.ptr(); for (int i = 0; i < s; i++) { hfw[i] = Math::make_half_float(r[i]); @@ -513,13 +513,13 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi } else { //just save a regular image - PoolVector<uint8_t> data; + Vector<uint8_t> data; int s = lm.light.size(); data.resize(lm.light.size()); { - PoolVector<uint8_t>::Write w = data.write(); - PoolVector<float>::Read r = lm.light.read(); + uint8_t* w = data.ptrw(); + const float* r = lm.light.ptr(); for (int i = 0; i < s; i += 3) { Color c(r[i + 0], r[i + 1], r[i + 2]); c = c.to_srgb(); @@ -534,11 +534,10 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi //This texture is saved to SRGB for two reasons: // 1) first is so it looks better when doing the LINEAR->SRGB conversion (more accurate) // 2) So it can be used in the GLES2 backend, which does not support linkear workflow - tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR; } String image_path = save_path.plus_file(mesh_name); - Ref<Texture> texture; + Ref<Texture2D> texture; if (ResourceLoader::import) { @@ -583,7 +582,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi tex.instance(); } - tex->create_from_image(image, tex_flags); + tex->create_from_image(image); err = ResourceSaver::save(image_path, tex, ResourceSaver::FLAG_CHANGE_PATH); if (set_path) { @@ -628,7 +627,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi if (p_create_visual_debug) { MultiMeshInstance *mmi = memnew(MultiMeshInstance); - mmi->set_multimesh(baker.create_debug_multimesh(VoxelLightBaker::DEBUG_LIGHT)); + mmi->set_multimesh(baker.create_debug_multimesh(Voxelizer::DEBUG_LIGHT)); add_child(mmi); #ifdef TOOLS_ENABLED if (get_tree()->get_edited_scene_root() == this) { @@ -668,7 +667,7 @@ void BakedLightmap::_assign_lightmaps() { ERR_FAIL_COND(!light_data.is_valid()); for (int i = 0; i < light_data->get_user_count(); i++) { - Ref<Texture> lightmap = light_data->get_user_lightmap(i); + Ref<Texture2D> lightmap = light_data->get_user_lightmap(i); ERR_CONTINUE(!lightmap.is_valid()); Node *node = get_node(light_data->get_user_path(i)); @@ -776,8 +775,8 @@ String BakedLightmap::get_image_path() const { AABB BakedLightmap::get_aabb() const { return AABB(-extents, extents * 2); } -PoolVector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); +Vector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const { + return Vector<Face3>(); } void BakedLightmap::_bind_methods() { @@ -820,16 +819,16 @@ void BakedLightmap::_bind_methods() { ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ADD_GROUP("Bake", "bake_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_bake_cell_size", "get_bake_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_bake_cell_size", "get_bake_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_bake_quality", "get_bake_quality"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mode", PROPERTY_HINT_ENUM, "ConeTrace,RayTrace"), "set_bake_mode", "get_bake_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_energy", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_energy", "get_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_energy", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_energy", "get_energy"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_hdr"), "set_hdr", "is_hdr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "bake_extents"), "set_extents", "get_extents"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_default_texels_per_unit"), "set_bake_default_texels_per_unit", "get_bake_default_texels_per_unit"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_default_texels_per_unit"), "set_bake_default_texels_per_unit", "get_bake_default_texels_per_unit"); ADD_GROUP("Capture", "capture_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "capture_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_capture_cell_size", "get_capture_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "capture_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_capture_cell_size", "get_capture_cell_size"); ADD_GROUP("Data", ""); ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_path", PROPERTY_HINT_DIR), "set_image_path", "get_image_path"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_data", PROPERTY_HINT_RESOURCE_TYPE, "BakedLightmapData"), "set_light_data", "get_light_data"); @@ -862,3 +861,4 @@ BakedLightmap::BakedLightmap() { image_path = "."; set_disable_scale(true); } +#endif diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index 82354cc9f0..bc9e3f55ea 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#if 0 #ifndef BAKED_INDIRECT_LIGHT_H #define BAKED_INDIRECT_LIGHT_H @@ -47,7 +48,7 @@ class BakedLightmapData : public Resource { struct User { NodePath path; - Ref<Texture> lightmap; + Ref<Texture2D> lightmap; int instance_index; }; @@ -63,8 +64,8 @@ public: void set_bounds(const AABB &p_bounds); AABB get_bounds() const; - void set_octree(const PoolVector<uint8_t> &p_octree); - PoolVector<uint8_t> get_octree() const; + void set_octree(const Vector<uint8_t> &p_octree); + Vector<uint8_t> get_octree() const; void set_cell_space_transform(const Transform &p_xform); Transform get_cell_space_transform() const; @@ -75,10 +76,10 @@ public: void set_energy(float p_energy); float get_energy() const; - void add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance = -1); + void add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance = -1); int get_user_count() const; NodePath get_user_path(int p_user) const; - Ref<Texture> get_user_lightmap(int p_user) const; + Ref<Texture2D> get_user_lightmap(int p_user) const; int get_user_instance(int p_user) const; void clear_users(); @@ -201,7 +202,7 @@ public: String get_image_path() const; AABB get_aabb() const; - PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + Vector<Face3> get_faces(uint32_t p_usage_flags) const; BakeError bake(Node *p_from_node, bool p_create_visual_debug = false); BakedLightmap(); @@ -211,4 +212,5 @@ VARIANT_ENUM_CAST(BakedLightmap::BakeQuality); VARIANT_ENUM_CAST(BakedLightmap::BakeMode); VARIANT_ENUM_CAST(BakedLightmap::BakeError); +#endif #endif // BAKED_INDIRECT_LIGHT_H diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp index e94e174b92..b1cd9bfe8b 100644 --- a/scene/3d/bone_attachment.cpp +++ b/scene/3d/bone_attachment.cpp @@ -123,5 +123,5 @@ void BoneAttachment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bone_name", "bone_name"), &BoneAttachment::set_bone_name); ClassDB::bind_method(D_METHOD("get_bone_name"), &BoneAttachment::get_bone_name); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bone_name"), "set_bone_name", "get_bone_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bone_name"), "set_bone_name", "get_bone_name"); } diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 640189a26e..741712025c 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -445,6 +445,21 @@ Ref<Environment> Camera::get_environment() const { return environment; } +void Camera::set_effects(const Ref<CameraEffects> &p_effects) { + + effects = p_effects; + if (effects.is_valid()) + VS::get_singleton()->camera_set_camera_effects(camera, effects->get_rid()); + else + VS::get_singleton()->camera_set_camera_effects(camera, RID()); + _update_camera_mode(); +} + +Ref<CameraEffects> Camera::get_effects() const { + + return effects; +} + void Camera::set_keep_aspect_mode(KeepAspect p_aspect) { keep_aspect = p_aspect; VisualServer::get_singleton()->camera_set_use_vertical_aspect(camera, p_aspect == KEEP_WIDTH); @@ -512,6 +527,8 @@ void Camera::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cull_mask"), &Camera::get_cull_mask); ClassDB::bind_method(D_METHOD("set_environment", "env"), &Camera::set_environment); ClassDB::bind_method(D_METHOD("get_environment"), &Camera::get_environment); + ClassDB::bind_method(D_METHOD("set_effects", "env"), &Camera::set_effects); + ClassDB::bind_method(D_METHOD("get_effects"), &Camera::get_effects); ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode); ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode); ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking); @@ -527,16 +544,17 @@ void Camera::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "keep_aspect", PROPERTY_HINT_ENUM, "Keep Width,Keep Height"), "set_keep_aspect_mode", "get_keep_aspect_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_effects", "get_effects"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); ADD_PROPERTY(PropertyInfo(Variant::INT, "projection", PROPERTY_HINT_ENUM, "Perspective,Orthogonal,Frustum"), "set_projection", "get_projection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov", PROPERTY_HINT_RANGE, "1,179,0.1"), "set_fov", "get_fov"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size", PROPERTY_HINT_RANGE, "0.1,16384,0.01"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frustum_offset"), "set_frustum_offset", "get_frustum_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "near", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01,or_greater"), "set_znear", "get_znear"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "near", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01,or_greater"), "set_znear", "get_znear"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "far", PROPERTY_HINT_EXP_RANGE, "0.1,8192,0.1,or_greater"), "set_zfar", "get_zfar"); BIND_ENUM_CONSTANT(PROJECTION_PERSPECTIVE); BIND_ENUM_CONSTANT(PROJECTION_ORTHOGONAL); @@ -908,7 +926,7 @@ void ClippedCamera::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera::clear_exceptions); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); diff --git a/scene/3d/camera.h b/scene/3d/camera.h index e215783a58..6ac3ece798 100644 --- a/scene/3d/camera.h +++ b/scene/3d/camera.h @@ -82,6 +82,7 @@ private: uint32_t layers; Ref<Environment> environment; + Ref<CameraEffects> effects; virtual bool _can_gizmo_scale() const; @@ -157,6 +158,9 @@ public: void set_environment(const Ref<Environment> &p_environment); Ref<Environment> get_environment() const; + void set_effects(const Ref<CameraEffects> &p_effects); + Ref<CameraEffects> get_effects() const; + void set_keep_aspect_mode(KeepAspect p_aspect); KeepAspect get_keep_aspect_mode() const; diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index cc07072962..636b859477 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -53,11 +53,11 @@ void CollisionPolygon::_build_polygon() { for (int i = 0; i < decomp.size(); i++) { Ref<ConvexPolygonShape> convex = memnew(ConvexPolygonShape); - PoolVector<Vector3> cp; + Vector<Vector3> cp; int cs = decomp[i].size(); cp.resize(cs * 2); { - PoolVector<Vector3>::Write w = cp.write(); + Vector3 *w = cp.ptrw(); int idx = 0; for (int j = 0; j < cs; j++) { @@ -191,9 +191,9 @@ void CollisionPolygon::_bind_methods() { ClassDB::bind_method(D_METHOD("_is_editable_3d_polygon"), &CollisionPolygon::_is_editable_3d_polygon); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth"), "set_depth", "get_depth"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth"), "set_depth", "get_depth"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon"); } CollisionPolygon::CollisionPolygon() { diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index bf2816fd41..35e4a61cd6 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -33,9 +33,9 @@ #include "scene/resources/capsule_shape.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/ray_shape.h" #include "scene/resources/sphere_shape.h" +#include "scene/resources/world_margin_shape.h" #include "servers/visual_server.h" //TODO: Implement CylinderShape and HeightMapShape? #include "core/math/quick_hull.h" @@ -123,10 +123,6 @@ String CollisionShape::get_configuration_warning() const { return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it."); } - if (shape->is_class("PlaneShape")) { - return TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); - } - return String(); } @@ -141,7 +137,6 @@ void CollisionShape::_bind_methods() { ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape::make_convex_from_brothers); ClassDB::set_method_flags("CollisionShape", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("_shape_changed"), &CollisionShape::_shape_changed); ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape::_update_debug_shape); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), "set_shape", "get_shape"); @@ -152,12 +147,12 @@ void CollisionShape::set_shape(const Ref<Shape> &p_shape) { if (!shape.is_null()) { shape->unregister_owner(this); - shape->disconnect("changed", this, "_shape_changed"); + shape->disconnect("changed", callable_mp(this, &CollisionShape::_shape_changed)); } shape = p_shape; if (!shape.is_null()) { shape->register_owner(this); - shape->connect("changed", this, "_shape_changed"); + shape->connect("changed", callable_mp(this, &CollisionShape::_shape_changed)); } update_gizmo(); if (parent) { diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index aa7a413548..bde578d0af 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -39,9 +39,9 @@ AABB CPUParticles::get_aabb() const { return AABB(); } -PoolVector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> CPUParticles::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } void CPUParticles::set_emitting(bool p_emitting) { @@ -65,15 +65,15 @@ void CPUParticles::set_amount(int p_amount) { particles.resize(p_amount); { - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < p_amount; i++) { w[i].active = false; } } - particle_data.resize((12 + 4 + 1) * p_amount); - VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT, VS::MULTIMESH_CUSTOM_DATA_FLOAT); + particle_data.resize((12 + 4 + 4) * p_amount); + VS::get_singleton()->multimesh_allocate(multimesh, p_amount, VS::MULTIMESH_TRANSFORM_3D, true, true); particle_order.resize(p_amount); } @@ -209,14 +209,14 @@ String CPUParticles::get_configuration_warning() const { mesh_found = true; for (int j = 0; j < get_mesh()->get_surface_count(); j++) { anim_material_found = Object::cast_to<ShaderMaterial>(get_mesh()->surface_get_material(j).ptr()) != NULL; - SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_mesh()->surface_get_material(j).ptr()); - anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_mesh()->surface_get_material(j).ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); } } anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL; - SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr()); - anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); if (!mesh_found) { if (warnings != String()) @@ -228,7 +228,7 @@ String CPUParticles::get_configuration_warning() const { get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) { if (warnings != String()) warnings += "\n"; - warnings += "- " + TTR("CPUParticles animation requires the usage of a SpatialMaterial whose Billboard Mode is set to \"Particle Billboard\"."); + warnings += "- " + TTR("CPUParticles animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\"."); } return warnings; @@ -244,7 +244,7 @@ void CPUParticles::restart() { { int pc = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); for (int i = 0; i < pc; i++) { w[i].active = false; @@ -419,17 +419,17 @@ void CPUParticles::set_emission_box_extents(Vector3 p_extents) { emission_box_extents = p_extents; } -void CPUParticles::set_emission_points(const PoolVector<Vector3> &p_points) { +void CPUParticles::set_emission_points(const Vector<Vector3> &p_points) { emission_points = p_points; } -void CPUParticles::set_emission_normals(const PoolVector<Vector3> &p_normals) { +void CPUParticles::set_emission_normals(const Vector<Vector3> &p_normals) { emission_normals = p_normals; } -void CPUParticles::set_emission_colors(const PoolVector<Color> &p_colors) { +void CPUParticles::set_emission_colors(const Vector<Color> &p_colors) { emission_colors = p_colors; } @@ -442,16 +442,16 @@ Vector3 CPUParticles::get_emission_box_extents() const { return emission_box_extents; } -PoolVector<Vector3> CPUParticles::get_emission_points() const { +Vector<Vector3> CPUParticles::get_emission_points() const { return emission_points; } -PoolVector<Vector3> CPUParticles::get_emission_normals() const { +Vector<Vector3> CPUParticles::get_emission_normals() const { return emission_normals; } -PoolVector<Color> CPUParticles::get_emission_colors() const { +Vector<Color> CPUParticles::get_emission_colors() const { return emission_colors; } @@ -597,9 +597,9 @@ void CPUParticles::_particles_process(float p_delta) { p_delta *= speed_scale; int pcount = particles.size(); - PoolVector<Particle>::Write w = particles.write(); + Particle *w = particles.ptrw(); - Particle *parray = w.ptr(); + Particle *parray = w; float prev_time = time; time += p_delta; @@ -1017,140 +1017,125 @@ void CPUParticles::_particles_process(float p_delta) { } void CPUParticles::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { + int pc = particles.size(); - int pc = particles.size(); + int *ow; + int *order = NULL; - PoolVector<int>::Write ow; - int *order = NULL; + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.write(); - order = ow.ptr(); + for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); + } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { + Camera *c = get_viewport()->get_camera(); + if (c) { + Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close + + if (local_coords) { + + // will look different from Particles in editor as this is based on the camera in the scenetree + // and not the editor camera + dir = inv_emission_transform.xform(dir).normalized(); + } else { + dir = dir.normalized(); + } - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; - sorter.compare.particles = r.ptr(); + SortArray<int, SortAxis> sorter; + sorter.compare.particles = r; + sorter.compare.axis = dir; sorter.sort(order, pc); - } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { - Camera *c = get_viewport()->get_camera(); - if (c) { - Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close - - if (local_coords) { - - // will look different from Particles in editor as this is based on the camera in the scenetree - // and not the editor camera - dir = inv_emission_transform.xform(dir).normalized(); - } else { - dir = dir.normalized(); - } - - SortArray<int, SortAxis> sorter; - sorter.compare.particles = r.ptr(); - sorter.compare.axis = dir; - sorter.sort(order, pc); - } } } + } - for (int i = 0; i < pc; i++) { + for (int i = 0; i < pc; i++) { - int idx = order ? order[i] : i; + int idx = order ? order[i] : i; - Transform t = r[idx].transform; + Transform t = r[idx].transform; - if (!local_coords) { - t = inv_emission_transform * t; - } + if (!local_coords) { + t = inv_emission_transform * t; + } - if (r[idx].active) { - ptr[0] = t.basis.elements[0][0]; - ptr[1] = t.basis.elements[0][1]; - ptr[2] = t.basis.elements[0][2]; - ptr[3] = t.origin.x; - ptr[4] = t.basis.elements[1][0]; - ptr[5] = t.basis.elements[1][1]; - ptr[6] = t.basis.elements[1][2]; - ptr[7] = t.origin.y; - ptr[8] = t.basis.elements[2][0]; - ptr[9] = t.basis.elements[2][1]; - ptr[10] = t.basis.elements[2][2]; - ptr[11] = t.origin.z; - } else { - zeromem(ptr, sizeof(float) * 12); - } + if (r[idx].active) { + ptr[0] = t.basis.elements[0][0]; + ptr[1] = t.basis.elements[0][1]; + ptr[2] = t.basis.elements[0][2]; + ptr[3] = t.origin.x; + ptr[4] = t.basis.elements[1][0]; + ptr[5] = t.basis.elements[1][1]; + ptr[6] = t.basis.elements[1][2]; + ptr[7] = t.origin.y; + ptr[8] = t.basis.elements[2][0]; + ptr[9] = t.basis.elements[2][1]; + ptr[10] = t.basis.elements[2][2]; + ptr[11] = t.origin.z; + } else { + zeromem(ptr, sizeof(float) * 12); + } - Color c = r[idx].color; - uint8_t *data8 = (uint8_t *)&ptr[12]; - data8[0] = CLAMP(c.r * 255.0, 0, 255); - data8[1] = CLAMP(c.g * 255.0, 0, 255); - data8[2] = CLAMP(c.b * 255.0, 0, 255); - data8[3] = CLAMP(c.a * 255.0, 0, 255); + Color c = r[idx].color; - ptr[13] = r[idx].custom[0]; - ptr[14] = r[idx].custom[1]; - ptr[15] = r[idx].custom[2]; - ptr[16] = r[idx].custom[3]; + ptr[12] = c.r; + ptr[13] = c.g; + ptr[14] = c.b; + ptr[15] = c.a; - ptr += 17; - } + ptr[16] = r[idx].custom[0]; + ptr[17] = r[idx].custom[1]; + ptr[18] = r[idx].custom[2]; + ptr[19] = r[idx].custom[3]; - can_update = true; + ptr += 20; } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + can_update = true; } void CPUParticles::_set_redraw(bool p_redraw) { if (redraw == p_redraw) return; redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread"); + + { + MutexLock lock(update_mutex); + + if (redraw) { + VS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &CPUParticles::_update_render_thread)); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (VS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &CPUParticles::_update_render_thread))) { + VS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &CPUParticles::_update_render_thread)); + } + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_update_render_thread() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); + if (can_update) { - VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data); + VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); can_update = false; //wait for next time } - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_notification(int p_what) { @@ -1185,9 +1170,9 @@ void CPUParticles::_notification(int p_what) { int pc = particles.size(); - PoolVector<float>::Write w = particle_data.write(); - PoolVector<Particle>::Read r = particles.read(); - float *ptr = w.ptr(); + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; for (int i = 0; i < pc; i++) { @@ -1210,7 +1195,7 @@ void CPUParticles::_notification(int p_what) { zeromem(ptr, sizeof(float) * 12); } - ptr += 17; + ptr += 20; } can_update = true; @@ -1327,13 +1312,13 @@ void CPUParticles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -1397,74 +1382,72 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles::convert_from_particles); - ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles::_update_render_thread); - ADD_GROUP("Emission Shape", "emission_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_normals"), "set_emission_normals", "get_emission_normals"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION); ADD_GROUP("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); @@ -1556,16 +1539,8 @@ CPUParticles::CPUParticles() { can_update = false; set_color(Color(1, 1, 1, 1)); - -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif } CPUParticles::~CPUParticles() { VS::get_singleton()->free(multimesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif } diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index d5a549b976..231e1f1ad9 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -106,9 +106,9 @@ private: RID multimesh; - PoolVector<Particle> particles; - PoolVector<float> particle_data; - PoolVector<int> particle_order; + Vector<Particle> particles; + Vector<float> particle_data; + Vector<int> particle_order; struct SortLifetime { const Particle *particles; @@ -167,9 +167,9 @@ private: EmissionShape emission_shape; float emission_sphere_radius; Vector3 emission_box_extents; - PoolVector<Vector3> emission_points; - PoolVector<Vector3> emission_normals; - PoolVector<Color> emission_colors; + Vector<Vector3> emission_points; + Vector<Vector3> emission_normals; + Vector<Color> emission_colors; int emission_point_count; Vector3 gravity; @@ -178,7 +178,7 @@ private: void _particles_process(float p_delta); void _update_particle_data_buffer(); - Mutex *update_mutex; + Mutex update_mutex; void _update_render_thread(); @@ -191,7 +191,7 @@ protected: public: AABB get_aabb() const; - PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + Vector<Face3> get_faces(uint32_t p_usage_flags) const; void set_emitting(bool p_emitting); void set_amount(int p_amount); @@ -264,17 +264,17 @@ public: void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); void set_emission_box_extents(Vector3 p_extents); - void set_emission_points(const PoolVector<Vector3> &p_points); - void set_emission_normals(const PoolVector<Vector3> &p_normals); - void set_emission_colors(const PoolVector<Color> &p_colors); + void set_emission_points(const Vector<Vector3> &p_points); + void set_emission_normals(const Vector<Vector3> &p_normals); + void set_emission_colors(const Vector<Color> &p_colors); void set_emission_point_count(int p_count); EmissionShape get_emission_shape() const; float get_emission_sphere_radius() const; Vector3 get_emission_box_extents() const; - PoolVector<Vector3> get_emission_points() const; - PoolVector<Vector3> get_emission_normals() const; - PoolVector<Color> get_emission_colors() const; + Vector<Vector3> get_emission_points() const; + Vector<Vector3> get_emission_normals() const; + Vector<Color> get_emission_colors() const; int get_emission_point_count() const; void set_gravity(const Vector3 &p_gravity); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 99bc78f5d2..c3f039ae85 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -32,116 +32,183 @@ #include "core/os/os.h" +#include "core/method_bind_ext.gen.inc" #include "mesh_instance.h" -#include "voxel_light_baker.h" +#include "voxelizer.h" + +void GIProbeData::_set_data(const Dictionary &p_data) { + ERR_FAIL_COND(!p_data.has("bounds")); + ERR_FAIL_COND(!p_data.has("octree_size")); + ERR_FAIL_COND(!p_data.has("octree_cells")); + ERR_FAIL_COND(!p_data.has("octree_data")); + ERR_FAIL_COND(!p_data.has("octree_df") && !p_data.has("octree_df_png")); + ERR_FAIL_COND(!p_data.has("level_counts")); + ERR_FAIL_COND(!p_data.has("to_cell_xform")); + + AABB bounds = p_data["bounds"]; + Vector3 octree_size = p_data["octree_size"]; + Vector<uint8_t> octree_cells = p_data["octree_cells"]; + Vector<uint8_t> octree_data = p_data["octree_data"]; + + Vector<uint8_t> octree_df; + if (p_data.has("octree_df")) { + octree_df = p_data["octree_df"]; + } else if (p_data.has("octree_df_png")) { + Vector<uint8_t> octree_df_png = p_data["octree_df_png"]; + Ref<Image> img; + img.instance(); + Error err = img->load_png_from_buffer(octree_df_png); + ERR_FAIL_COND(err != OK); + ERR_FAIL_COND(img->get_format() != Image::FORMAT_L8); + octree_df = img->get_data(); + } + Vector<int> octree_levels = p_data["level_counts"]; + Transform to_cell_xform = p_data["to_cell_xform"]; + + allocate(to_cell_xform, bounds, octree_size, octree_cells, octree_data, octree_df, octree_levels); +} + +Dictionary GIProbeData::_get_data() const { + Dictionary d; + d["bounds"] = get_bounds(); + Vector3i otsize = get_octree_size(); + d["octree_size"] = Vector3(otsize); + d["octree_cells"] = get_octree_cells(); + d["octree_data"] = get_data_cells(); + if (otsize != Vector3i()) { + Ref<Image> img; + img.instance(); + img->create(otsize.x * otsize.y, otsize.z, false, Image::FORMAT_L8, get_distance_field()); + Vector<uint8_t> df_png = img->save_png_to_buffer(); + ERR_FAIL_COND_V(df_png.size() == 0, Dictionary()); + d["octree_df_png"] = df_png; + } else { + d["octree_df"] = Vector<uint8_t>(); + } -void GIProbeData::set_bounds(const AABB &p_bounds) { + d["level_counts"] = get_level_counts(); + d["to_cell_xform"] = get_to_cell_xform(); + return d; +} - VS::get_singleton()->gi_probe_set_bounds(probe, p_bounds); +void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { + VS::get_singleton()->gi_probe_allocate(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); + bounds = p_aabb; + to_cell_xform = p_to_cell_xform; + octree_size = p_octree_size; } AABB GIProbeData::get_bounds() const { - - return VS::get_singleton()->gi_probe_get_bounds(probe); + return bounds; } - -void GIProbeData::set_cell_size(float p_size) { - - VS::get_singleton()->gi_probe_set_cell_size(probe, p_size); +Vector3 GIProbeData::get_octree_size() const { + return octree_size; } - -float GIProbeData::get_cell_size() const { - - return VS::get_singleton()->gi_probe_get_cell_size(probe); +Vector<uint8_t> GIProbeData::get_octree_cells() const { + return VS::get_singleton()->gi_probe_get_octree_cells(probe); } - -void GIProbeData::set_to_cell_xform(const Transform &p_xform) { - - VS::get_singleton()->gi_probe_set_to_cell_xform(probe, p_xform); +Vector<uint8_t> GIProbeData::get_data_cells() const { + return VS::get_singleton()->gi_probe_get_data_cells(probe); +} +Vector<uint8_t> GIProbeData::get_distance_field() const { + return VS::get_singleton()->gi_probe_get_distance_field(probe); } +Vector<int> GIProbeData::get_level_counts() const { + return VS::get_singleton()->gi_probe_get_level_counts(probe); +} Transform GIProbeData::get_to_cell_xform() const { - - return VS::get_singleton()->gi_probe_get_to_cell_xform(probe); + return to_cell_xform; } -void GIProbeData::set_dynamic_data(const PoolVector<int> &p_data) { +void GIProbeData::set_dynamic_range(float p_range) { + VS::get_singleton()->gi_probe_set_dynamic_range(probe, p_range); + dynamic_range = p_range; +} - VS::get_singleton()->gi_probe_set_dynamic_data(probe, p_data); +float GIProbeData::get_dynamic_range() const { + return dynamic_range; } -PoolVector<int> GIProbeData::get_dynamic_data() const { - return VS::get_singleton()->gi_probe_get_dynamic_data(probe); +void GIProbeData::set_propagation(float p_propagation) { + VS::get_singleton()->gi_probe_set_propagation(probe, p_propagation); + propagation = p_propagation; } -void GIProbeData::set_dynamic_range(int p_range) { +float GIProbeData::get_propagation() const { + return propagation; +} - VS::get_singleton()->gi_probe_set_dynamic_range(probe, p_range); +void GIProbeData::set_anisotropy_strength(float p_anisotropy_strength) { + VS::get_singleton()->gi_probe_set_anisotropy_strength(probe, p_anisotropy_strength); + anisotropy_strength = p_anisotropy_strength; } -void GIProbeData::set_energy(float p_range) { +float GIProbeData::get_anisotropy_strength() const { + return anisotropy_strength; +} - VS::get_singleton()->gi_probe_set_energy(probe, p_range); +void GIProbeData::set_energy(float p_energy) { + VS::get_singleton()->gi_probe_set_energy(probe, p_energy); + energy = p_energy; } float GIProbeData::get_energy() const { - - return VS::get_singleton()->gi_probe_get_energy(probe); + return energy; } -void GIProbeData::set_bias(float p_range) { - - VS::get_singleton()->gi_probe_set_bias(probe, p_range); +void GIProbeData::set_ao(float p_ao) { + VS::get_singleton()->gi_probe_set_ao(probe, p_ao); + ao = p_ao; } -float GIProbeData::get_bias() const { - - return VS::get_singleton()->gi_probe_get_bias(probe); +float GIProbeData::get_ao() const { + return ao; } -void GIProbeData::set_normal_bias(float p_range) { - - VS::get_singleton()->gi_probe_set_normal_bias(probe, p_range); +void GIProbeData::set_ao_size(float p_ao_size) { + VS::get_singleton()->gi_probe_set_ao_size(probe, p_ao_size); + ao_size = p_ao_size; } -float GIProbeData::get_normal_bias() const { - - return VS::get_singleton()->gi_probe_get_normal_bias(probe); +float GIProbeData::get_ao_size() const { + return ao_size; } -void GIProbeData::set_propagation(float p_range) { +void GIProbeData::set_bias(float p_bias) { + VS::get_singleton()->gi_probe_set_bias(probe, p_bias); + bias = p_bias; +} - VS::get_singleton()->gi_probe_set_propagation(probe, p_range); +float GIProbeData::get_bias() const { + return bias; } -float GIProbeData::get_propagation() const { +void GIProbeData::set_normal_bias(float p_normal_bias) { + VS::get_singleton()->gi_probe_set_normal_bias(probe, p_normal_bias); + normal_bias = p_normal_bias; +} - return VS::get_singleton()->gi_probe_get_propagation(probe); +float GIProbeData::get_normal_bias() const { + return normal_bias; } void GIProbeData::set_interior(bool p_enable) { - VS::get_singleton()->gi_probe_set_interior(probe, p_enable); + interior = p_enable; } bool GIProbeData::is_interior() const { - - return VS::get_singleton()->gi_probe_is_interior(probe); + return interior; } -bool GIProbeData::is_compressed() const { - - return VS::get_singleton()->gi_probe_is_compressed(probe); +void GIProbeData::set_use_two_bounces(bool p_enable) { + VS::get_singleton()->gi_probe_set_use_two_bounces(probe, p_enable); + use_two_bounces = p_enable; } -void GIProbeData::set_compress(bool p_enable) { - - VS::get_singleton()->gi_probe_set_compress(probe, p_enable); -} - -int GIProbeData::get_dynamic_range() const { - - return VS::get_singleton()->gi_probe_get_dynamic_range(probe); +bool GIProbeData::is_using_two_bounces() const { + return use_two_bounces; } RID GIProbeData::get_rid() const { @@ -149,19 +216,24 @@ RID GIProbeData::get_rid() const { return probe; } +void GIProbeData::_validate_property(PropertyInfo &property) const { + if (property.name == "anisotropy_strength") { + bool anisotropy_enabled = ProjectSettings::get_singleton()->get("rendering/quality/gi_probes/anisotropic"); + if (!anisotropy_enabled) { + property.usage = PROPERTY_USAGE_NOEDITOR; + } + } +} + void GIProbeData::_bind_methods() { + ClassDB::bind_method(D_METHOD("allocate", "to_cell_xform", "aabb", "octree_size", "octree_cells", "data_cells", "distance_field", "level_counts"), &GIProbeData::allocate); - ClassDB::bind_method(D_METHOD("set_bounds", "bounds"), &GIProbeData::set_bounds); ClassDB::bind_method(D_METHOD("get_bounds"), &GIProbeData::get_bounds); - - ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &GIProbeData::set_cell_size); - ClassDB::bind_method(D_METHOD("get_cell_size"), &GIProbeData::get_cell_size); - - ClassDB::bind_method(D_METHOD("set_to_cell_xform", "to_cell_xform"), &GIProbeData::set_to_cell_xform); + ClassDB::bind_method(D_METHOD("get_octree_size"), &GIProbeData::get_octree_size); ClassDB::bind_method(D_METHOD("get_to_cell_xform"), &GIProbeData::get_to_cell_xform); - - ClassDB::bind_method(D_METHOD("set_dynamic_data", "dynamic_data"), &GIProbeData::set_dynamic_data); - ClassDB::bind_method(D_METHOD("get_dynamic_data"), &GIProbeData::get_dynamic_data); + ClassDB::bind_method(D_METHOD("get_octree_cells"), &GIProbeData::get_octree_cells); + ClassDB::bind_method(D_METHOD("get_data_cells"), &GIProbeData::get_data_cells); + ClassDB::bind_method(D_METHOD("get_level_counts"), &GIProbeData::get_level_counts); ClassDB::bind_method(D_METHOD("set_dynamic_range", "dynamic_range"), &GIProbeData::set_dynamic_range); ClassDB::bind_method(D_METHOD("get_dynamic_range"), &GIProbeData::get_dynamic_range); @@ -178,28 +250,50 @@ void GIProbeData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &GIProbeData::set_propagation); ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbeData::get_propagation); + ClassDB::bind_method(D_METHOD("set_anisotropy_strength", "strength"), &GIProbeData::set_anisotropy_strength); + ClassDB::bind_method(D_METHOD("get_anisotropy_strength"), &GIProbeData::get_anisotropy_strength); + + ClassDB::bind_method(D_METHOD("set_ao", "ao"), &GIProbeData::set_ao); + ClassDB::bind_method(D_METHOD("get_ao"), &GIProbeData::get_ao); + + ClassDB::bind_method(D_METHOD("set_ao_size", "strength"), &GIProbeData::set_ao_size); + ClassDB::bind_method(D_METHOD("get_ao_size"), &GIProbeData::get_ao_size); + ClassDB::bind_method(D_METHOD("set_interior", "interior"), &GIProbeData::set_interior); ClassDB::bind_method(D_METHOD("is_interior"), &GIProbeData::is_interior); - ClassDB::bind_method(D_METHOD("set_compress", "compress"), &GIProbeData::set_compress); - ClassDB::bind_method(D_METHOD("is_compressed"), &GIProbeData::is_compressed); + ClassDB::bind_method(D_METHOD("set_use_two_bounces", "enable"), &GIProbeData::set_use_two_bounces); + ClassDB::bind_method(D_METHOD("is_using_two_bounces"), &GIProbeData::is_using_two_bounces); + + ClassDB::bind_method(D_METHOD("_set_data", "data"), &GIProbeData::_set_data); + ClassDB::bind_method(D_METHOD("_get_data"), &GIProbeData::_get_data); - ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "to_cell_xform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_to_cell_xform", "get_to_cell_xform"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "dynamic_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_data", "get_dynamic_data"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_range", "get_dynamic_range"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bias", "get_bias"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_normal_bias", "get_normal_bias"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_propagation", "get_propagation"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_interior", "is_interior"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_compress", "is_compressed"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_dynamic_range", "get_dynamic_range"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_energy", "get_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_bias", "get_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_bias", PROPERTY_HINT_RANGE, "0,8,0.01"), "set_normal_bias", "get_normal_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "anisotropy_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_anisotropy_strength", "get_anisotropy_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ao", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao", "get_ao"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ao_size", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_size", "get_ao_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_two_bounces"), "set_use_two_bounces", "is_using_two_bounces"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior"); } GIProbeData::GIProbeData() { + ao = 0.0; + ao_size = 0.5; + dynamic_range = 4; + energy = 1.0; + bias = 1.5; + normal_bias = 0.0; + propagation = 0.7; + anisotropy_strength = 0.5; + interior = false; + probe = VS::get_singleton()->gi_probe_create(); } @@ -251,89 +345,6 @@ Vector3 GIProbe::get_extents() const { return extents; } -void GIProbe::set_dynamic_range(int p_dynamic_range) { - - dynamic_range = p_dynamic_range; -} -int GIProbe::get_dynamic_range() const { - - return dynamic_range; -} - -void GIProbe::set_energy(float p_energy) { - - energy = p_energy; - if (probe_data.is_valid()) { - probe_data->set_energy(energy); - } -} -float GIProbe::get_energy() const { - - return energy; -} - -void GIProbe::set_bias(float p_bias) { - - bias = p_bias; - if (probe_data.is_valid()) { - probe_data->set_bias(bias); - } -} -float GIProbe::get_bias() const { - - return bias; -} - -void GIProbe::set_normal_bias(float p_normal_bias) { - - normal_bias = p_normal_bias; - if (probe_data.is_valid()) { - probe_data->set_normal_bias(normal_bias); - } -} -float GIProbe::get_normal_bias() const { - - return normal_bias; -} - -void GIProbe::set_propagation(float p_propagation) { - - propagation = p_propagation; - if (probe_data.is_valid()) { - probe_data->set_propagation(propagation); - } -} -float GIProbe::get_propagation() const { - - return propagation; -} - -void GIProbe::set_interior(bool p_enable) { - - interior = p_enable; - if (probe_data.is_valid()) { - probe_data->set_interior(p_enable); - } -} - -bool GIProbe::is_interior() const { - - return interior; -} - -void GIProbe::set_compress(bool p_enable) { - - compress = p_enable; - if (probe_data.is_valid()) { - probe_data->set_compress(p_enable); - } -} - -bool GIProbe::is_compressed() const { - - return compress; -} - void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node); @@ -395,11 +406,36 @@ GIProbe::BakeBeginFunc GIProbe::bake_begin_function = NULL; GIProbe::BakeStepFunc GIProbe::bake_step_function = NULL; GIProbe::BakeEndFunc GIProbe::bake_end_function = NULL; +Vector3i GIProbe::get_estimated_cell_size() const { + static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; + int cell_subdiv = subdiv_value[subdiv]; + int axis_cell_size[3]; + AABB bounds = AABB(-extents, extents * 2.0); + int longest_axis = bounds.get_longest_axis_index(); + axis_cell_size[longest_axis] = 1 << cell_subdiv; + + for (int i = 0; i < 3; i++) { + + if (i == longest_axis) + continue; + + axis_cell_size[i] = axis_cell_size[longest_axis]; + float axis_size = bounds.size[longest_axis]; + + //shrink until fit subdiv + while (axis_size / 2.0 >= bounds.size[i]) { + axis_size /= 2.0; + axis_cell_size[i] >>= 1; + } + } + + return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]); +} void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { - static const int subdiv_value[SUBDIV_MAX] = { 7, 8, 9, 10 }; + static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; - VoxelLightBaker baker; + Voxelizer baker; baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0)); @@ -431,8 +467,6 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { //create the data for visual server - PoolVector<int> data = baker.create_gi_probe_data(); - if (p_create_visual_debug) { MultiMeshInstance *mmi = memnew(MultiMeshInstance); mmi->set_multimesh(baker.create_debug_multimesh()); @@ -454,24 +488,25 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { if (probe_data.is_null()) probe_data.instance(); - probe_data->set_bounds(AABB(-extents, extents * 2.0)); - probe_data->set_cell_size(baker.get_cell_size()); - probe_data->set_dynamic_data(data); - probe_data->set_dynamic_range(dynamic_range); - probe_data->set_energy(energy); - probe_data->set_bias(bias); - probe_data->set_normal_bias(normal_bias); - probe_data->set_propagation(propagation); - probe_data->set_interior(interior); - probe_data->set_compress(compress); - probe_data->set_to_cell_xform(baker.get_to_cell_space_xform()); + if (bake_step_function) { + bake_step_function(pmc++, RTR("Generating Distance Field")); + } + + Vector<uint8_t> df = baker.get_sdf_3d_image(); + + probe_data->allocate(baker.get_to_cell_space_xform(), AABB(-extents, extents * 2.0), baker.get_giprobe_octree_size(), baker.get_giprobe_octree_cells(), baker.get_giprobe_data_cells(), df, baker.get_giprobe_level_cell_count()); set_probe_data(probe_data); +#ifdef TOOLS_ENABLED + probe_data->set_edited(true); //so it gets saved +#endif } if (bake_end_function) { bake_end_function(); } + + _change_notify(); //bake property may have changed } void GIProbe::_debug_bake() { @@ -484,9 +519,9 @@ AABB GIProbe::get_aabb() const { return AABB(-extents, extents * 2); } -PoolVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } String GIProbe::get_configuration_warning() const { @@ -508,40 +543,12 @@ void GIProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GIProbe::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &GIProbe::get_extents); - ClassDB::bind_method(D_METHOD("set_dynamic_range", "max"), &GIProbe::set_dynamic_range); - ClassDB::bind_method(D_METHOD("get_dynamic_range"), &GIProbe::get_dynamic_range); - - ClassDB::bind_method(D_METHOD("set_energy", "max"), &GIProbe::set_energy); - ClassDB::bind_method(D_METHOD("get_energy"), &GIProbe::get_energy); - - ClassDB::bind_method(D_METHOD("set_bias", "max"), &GIProbe::set_bias); - ClassDB::bind_method(D_METHOD("get_bias"), &GIProbe::get_bias); - - ClassDB::bind_method(D_METHOD("set_normal_bias", "max"), &GIProbe::set_normal_bias); - ClassDB::bind_method(D_METHOD("get_normal_bias"), &GIProbe::get_normal_bias); - - ClassDB::bind_method(D_METHOD("set_propagation", "max"), &GIProbe::set_propagation); - ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbe::get_propagation); - - ClassDB::bind_method(D_METHOD("set_interior", "enable"), &GIProbe::set_interior); - ClassDB::bind_method(D_METHOD("is_interior"), &GIProbe::is_interior); - - ClassDB::bind_method(D_METHOD("set_compress", "enable"), &GIProbe::set_compress); - ClassDB::bind_method(D_METHOD("is_compressed"), &GIProbe::is_compressed); - ClassDB::bind_method(D_METHOD("bake", "from_node", "create_visual_debug"), &GIProbe::bake, DEFVAL(Variant()), DEFVAL(false)); ClassDB::bind_method(D_METHOD("debug_bake"), &GIProbe::_debug_bake); ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdiv", PROPERTY_HINT_ENUM, "64,128,256,512"), "set_subdiv", "get_subdiv"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_RANGE, "1,16,1"), "set_dynamic_range", "get_dynamic_range"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_bias", "get_bias"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_normal_bias", "get_normal_bias"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress"), "set_compress", "is_compressed"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "GIProbeData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_probe_data", "get_probe_data"); BIND_ENUM_CONSTANT(SUBDIV_64); @@ -554,14 +561,7 @@ void GIProbe::_bind_methods() { GIProbe::GIProbe() { subdiv = SUBDIV_128; - dynamic_range = 4; - energy = 1.0; - bias = 1.5; - normal_bias = 0.0; - propagation = 0.7; extents = Vector3(10, 10, 10); - interior = false; - compress = false; gi_probe = VS::get_singleton()->gi_probe_create(); set_disable_scale(true); diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 7c58f862e4..354eaad7c0 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -40,42 +40,67 @@ class GIProbeData : public Resource { RID probe; + void _set_data(const Dictionary &p_data); + Dictionary _get_data() const; + + Transform to_cell_xform; + AABB bounds; + Vector3 octree_size; + + float dynamic_range; + float energy; + float bias; + float normal_bias; + float propagation; + float anisotropy_strength; + float ao; + float ao_size; + bool interior; + bool use_two_bounces; + protected: static void _bind_methods(); + void _validate_property(PropertyInfo &property) const; public: - void set_bounds(const AABB &p_bounds); + void allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); AABB get_bounds() const; + Vector3 get_octree_size() const; + Vector<uint8_t> get_octree_cells() const; + Vector<uint8_t> get_data_cells() const; + Vector<uint8_t> get_distance_field() const; + Vector<int> get_level_counts() const; + Transform get_to_cell_xform() const; - void set_cell_size(float p_size); - float get_cell_size() const; + void set_dynamic_range(float p_range); + float get_dynamic_range() const; - void set_to_cell_xform(const Transform &p_xform); - Transform get_to_cell_xform() const; + void set_propagation(float p_propagation); + float get_propagation() const; - void set_dynamic_data(const PoolVector<int> &p_data); - PoolVector<int> get_dynamic_data() const; + void set_anisotropy_strength(float p_anisotropy_strength); + float get_anisotropy_strength() const; - void set_dynamic_range(int p_range); - int get_dynamic_range() const; + void set_ao(float p_ao); + float get_ao() const; - void set_propagation(float p_range); - float get_propagation() const; + void set_ao_size(float p_ao_size); + float get_ao_size() const; - void set_energy(float p_range); + void set_energy(float p_energy); float get_energy() const; - void set_bias(float p_range); + void set_bias(float p_bias); float get_bias() const; - void set_normal_bias(float p_range); + void set_normal_bias(float p_normal_bias); float get_normal_bias() const; void set_interior(bool p_enable); bool is_interior() const; - void set_compress(bool p_enable); - bool is_compressed() const; + void set_use_two_bounces(bool p_enable); + bool is_using_two_bounces() const; virtual RID get_rid() const; @@ -107,13 +132,6 @@ private: Subdiv subdiv; Vector3 extents; - int dynamic_range; - float energy; - float bias; - float normal_bias; - float propagation; - bool interior; - bool compress; struct PlotMesh { Ref<Material> override_material; @@ -141,32 +159,12 @@ public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; - - void set_dynamic_range(int p_dynamic_range); - int get_dynamic_range() const; - - void set_energy(float p_energy); - float get_energy() const; - - void set_bias(float p_bias); - float get_bias() const; - - void set_normal_bias(float p_normal_bias); - float get_normal_bias() const; - - void set_propagation(float p_propagation); - float get_propagation() const; - - void set_interior(bool p_enable); - bool is_interior() const; - - void set_compress(bool p_enable); - bool is_compressed() const; + Vector3i get_estimated_cell_size() const; void bake(Node *p_from_node = NULL, bool p_create_visual_debug = false); virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; virtual String get_configuration_warning() const; diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp index 0a1beaf3f4..f5b08b86e1 100644 --- a/scene/3d/immediate_geometry.cpp +++ b/scene/3d/immediate_geometry.cpp @@ -30,7 +30,7 @@ #include "immediate_geometry.h" -void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture) { +void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture) { VS::get_singleton()->immediate_begin(im, (VS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID()); if (p_texture.is_valid()) @@ -90,9 +90,9 @@ AABB ImmediateGeometry::get_aabb() const { return aabb; } -PoolVector<Face3> ImmediateGeometry::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> ImmediateGeometry::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) { @@ -144,7 +144,7 @@ void ImmediateGeometry::add_sphere(int p_lats, int p_lons, float p_radius, bool void ImmediateGeometry::_bind_methods() { - ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry::begin, DEFVAL(Ref<Texture>())); + ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry::begin, DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry::set_normal); ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry::set_tangent); ClassDB::bind_method(D_METHOD("set_color", "color"), &ImmediateGeometry::set_color); diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index f45ebd6724..77a20e8d4d 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -41,7 +41,7 @@ class ImmediateGeometry : public GeometryInstance { RID im; //a list of textures drawn need to be kept, to avoid references // in VisualServer from becoming invalid if the texture is no longer used - List<Ref<Texture> > cached_textures; + List<Ref<Texture2D> > cached_textures; bool empty; AABB aabb; @@ -49,7 +49,7 @@ protected: static void _bind_methods(); public: - void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture> &p_texture = Ref<Texture>()); + void begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture = Ref<Texture2D>()); void set_normal(const Vector3 &p_normal); void set_tangent(const Plane &p_tangent); void set_color(const Color &p_color); @@ -64,7 +64,7 @@ public: void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true); virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; ImmediateGeometry(); ~ImmediateGeometry(); diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp index baf5ac4be6..592d592a38 100644 --- a/scene/3d/interpolated_camera.cpp +++ b/scene/3d/interpolated_camera.cpp @@ -144,7 +144,7 @@ void InterpolatedCamera::_bind_methods() { ClassDB::bind_method(D_METHOD("is_interpolation_enabled"), &InterpolatedCamera::is_interpolation_enabled); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), "set_target_path", "get_target_path"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), "set_speed", "get_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed"), "set_speed", "get_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_interpolation_enabled", "is_interpolation_enabled"); } diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 593d0b95b7..7c922ce1cd 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -152,9 +152,9 @@ AABB Light::get_aabb() const { return AABB(); } -PoolVector<Face3> Light::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> Light::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } void Light::set_bake_mode(BakeMode p_mode) { @@ -253,17 +253,17 @@ void Light::_bind_methods() { ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_ENERGY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disable,Indirect,All"), "set_bake_mode", "get_bake_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); @@ -281,6 +281,7 @@ void Light::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_1_OFFSET); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_2_OFFSET); BIND_ENUM_CONSTANT(PARAM_SHADOW_SPLIT_3_OFFSET); + BIND_ENUM_CONSTANT(PARAM_SHADOW_FADE_START); BIND_ENUM_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS); BIND_ENUM_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE); @@ -325,8 +326,10 @@ Light::Light(VisualServer::LightType p_type) { set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1); set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2); set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); + set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0); set_param(PARAM_SHADOW_BIAS, 0.15); + set_param(PARAM_SHADOW_FADE_START, 1); set_disable_scale(true); } @@ -390,14 +393,15 @@ void DirectionalLight::_bind_methods() { ADD_GROUP("Directional Shadow", "directional_shadow_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), "set_shadow_mode", "get_shadow_mode"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_fade_start", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_FADE_START); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); @@ -413,6 +417,7 @@ DirectionalLight::DirectionalLight() : set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8); set_param(PARAM_SHADOW_BIAS, 0.1); set_param(PARAM_SHADOW_MAX_DISTANCE, 100); + set_param(PARAM_SHADOW_FADE_START, 0.8); set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); @@ -431,42 +436,24 @@ OmniLight::ShadowMode OmniLight::get_shadow_mode() const { return shadow_mode; } -void OmniLight::set_shadow_detail(ShadowDetail p_detail) { - - shadow_detail = p_detail; - VS::get_singleton()->light_omni_set_shadow_detail(light, VS::LightOmniShadowDetail(p_detail)); -} -OmniLight::ShadowDetail OmniLight::get_shadow_detail() const { - - return shadow_detail; -} - void OmniLight::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight::set_shadow_mode); ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight::get_shadow_mode); - ClassDB::bind_method(D_METHOD("set_shadow_detail", "detail"), &OmniLight::set_shadow_detail); - ClassDB::bind_method(D_METHOD("get_shadow_detail"), &OmniLight::get_shadow_detail); - ADD_GROUP("Omni", "omni_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "omni_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "omni_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION); ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_mode", PROPERTY_HINT_ENUM, "Dual Paraboloid,Cube"), "set_shadow_mode", "get_shadow_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "omni_shadow_detail", PROPERTY_HINT_ENUM, "Vertical,Horizontal"), "set_shadow_detail", "get_shadow_detail"); BIND_ENUM_CONSTANT(SHADOW_DUAL_PARABOLOID); BIND_ENUM_CONSTANT(SHADOW_CUBE); - - BIND_ENUM_CONSTANT(SHADOW_DETAIL_VERTICAL); - BIND_ENUM_CONSTANT(SHADOW_DETAIL_HORIZONTAL); } OmniLight::OmniLight() : Light(VisualServer::LIGHT_OMNI) { set_shadow_mode(SHADOW_CUBE); - set_shadow_detail(SHADOW_DETAIL_HORIZONTAL); } String SpotLight::get_configuration_warning() const { @@ -486,8 +473,8 @@ String SpotLight::get_configuration_warning() const { void SpotLight::_bind_methods() { ADD_GROUP("Spot", "spot_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_param", "get_param", PARAM_SPOT_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "spot_angle_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_SPOT_ATTENUATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_param", "get_param", PARAM_SPOT_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_SPOT_ATTENUATION); } diff --git a/scene/3d/light.h b/scene/3d/light.h index 272ee8d7a9..16e0c47083 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -54,6 +54,7 @@ public: PARAM_SHADOW_SPLIT_1_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET, PARAM_SHADOW_SPLIT_2_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET, PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET, + PARAM_SHADOW_FADE_START = VS::LIGHT_PARAM_SHADOW_FADE_START, PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS, PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, @@ -123,7 +124,7 @@ public: BakeMode get_bake_mode() const; virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; Light(); ~Light(); @@ -183,15 +184,8 @@ public: SHADOW_CUBE, }; - // omni light - enum ShadowDetail { - SHADOW_DETAIL_VERTICAL, - SHADOW_DETAIL_HORIZONTAL - }; - private: ShadowMode shadow_mode; - ShadowDetail shadow_detail; protected: static void _bind_methods(); @@ -200,14 +194,10 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; - void set_shadow_detail(ShadowDetail p_detail); - ShadowDetail get_shadow_detail() const; - OmniLight(); }; VARIANT_ENUM_CAST(OmniLight::ShadowMode) -VARIANT_ENUM_CAST(OmniLight::ShadowDetail) class SpotLight : public Light { diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index e14fa9e9af..4ca139ebbc 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -34,7 +34,6 @@ #include "core/core_string_names.h" #include "physics_body.h" #include "scene/resources/material.h" -#include "scene/scene_string_names.h" #include "skeleton.h" bool MeshInstance::_set(const StringName &p_name, const Variant &p_value) { @@ -96,12 +95,12 @@ void MeshInstance::_get_property_list(List<PropertyInfo> *p_list) const { ls.sort(); for (List<String>::Element *E = ls.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::REAL, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001")); + p_list->push_back(PropertyInfo(Variant::FLOAT, E->get(), PROPERTY_HINT_RANGE, "0,1,0.00001")); } if (mesh.is_valid()) { for (int i = 0; i < mesh->get_surface_count(); i++) { - p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial")); + p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE)); } } } @@ -112,7 +111,7 @@ void MeshInstance::set_mesh(const Ref<Mesh> &p_mesh) { return; if (mesh.is_valid()) { - mesh->disconnect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed); + mesh->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance::_mesh_changed)); materials.clear(); } @@ -129,7 +128,7 @@ void MeshInstance::set_mesh(const Ref<Mesh> &p_mesh) { blend_shape_tracks["blend_shapes/" + String(mesh->get_blend_shape_name(i))] = mt; } - mesh->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_mesh_changed); + mesh->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance::_mesh_changed)); materials.resize(mesh->get_surface_count()); set_base(mesh->get_rid()); @@ -204,13 +203,13 @@ AABB MeshInstance::get_aabb() const { return AABB(); } -PoolVector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const { if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING))) - return PoolVector<Face3>(); + return Vector<Face3>(); if (mesh.is_null()) - return PoolVector<Face3>(); + return Vector<Face3>(); return mesh->get_faces(); } @@ -355,12 +354,12 @@ void MeshInstance::create_debug_tangents() { if (lines.size()) { - Ref<SpatialMaterial> sm; + Ref<StandardMaterial3D> sm; sm.instance(); - sm->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - sm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - sm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + sm->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + sm->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + sm->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); Ref<ArrayMesh> am; am.instance(); @@ -403,14 +402,15 @@ void MeshInstance::_bind_methods() { ClassDB::set_method_flags("MeshInstance", "create_trimesh_collision", METHOD_FLAGS_DEFAULT); ClassDB::bind_method(D_METHOD("create_convex_collision"), &MeshInstance::create_convex_collision); ClassDB::set_method_flags("MeshInstance", "create_convex_collision", METHOD_FLAGS_DEFAULT); - ClassDB::bind_method(D_METHOD("_mesh_changed"), &MeshInstance::_mesh_changed); ClassDB::bind_method(D_METHOD("create_debug_tangents"), &MeshInstance::create_debug_tangents); ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); + ADD_GROUP("Skeleton", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path"); + ADD_GROUP("", ""); } MeshInstance::MeshInstance() { diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index fd5f60a5d7..d49d9ed98f 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -94,7 +94,7 @@ public: void create_debug_tangents(); virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; MeshInstance(); ~MeshInstance(); diff --git a/scene/3d/multimesh_instance.cpp b/scene/3d/multimesh_instance.cpp index 245dbdaf58..075eb0a1ec 100644 --- a/scene/3d/multimesh_instance.cpp +++ b/scene/3d/multimesh_instance.cpp @@ -51,9 +51,9 @@ Ref<MultiMesh> MultiMeshInstance::get_multimesh() const { return multimesh; } -PoolVector<Face3> MultiMeshInstance::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> MultiMeshInstance::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } AABB MultiMeshInstance::get_aabb() const { diff --git a/scene/3d/multimesh_instance.h b/scene/3d/multimesh_instance.h index 855bd54910..2b59c3b96c 100644 --- a/scene/3d/multimesh_instance.h +++ b/scene/3d/multimesh_instance.h @@ -44,7 +44,7 @@ protected: // bind helpers public: - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; void set_multimesh(const Ref<MultiMesh> &p_multimesh); Ref<MultiMesh> get_multimesh() const; diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index 4a82fe0080..8c543bc97f 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -30,669 +30,33 @@ #include "navigation.h" -#define USE_ENTRY_POINT +#include "servers/navigation_server.h" -void Navigation::_navmesh_link(int p_id) { +Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const { - ERR_FAIL_COND(!navmesh_map.has(p_id)); - NavMesh &nm = navmesh_map[p_id]; - ERR_FAIL_COND(nm.linked); - ERR_FAIL_COND(nm.navmesh.is_null()); - - PoolVector<Vector3> vertices = nm.navmesh->get_vertices(); - int len = vertices.size(); - if (len == 0) - return; - - PoolVector<Vector3>::Read r = vertices.read(); - - for (int i = 0; i < nm.navmesh->get_polygon_count(); i++) { - - //build - - List<Polygon>::Element *P = nm.polygons.push_back(Polygon()); - Polygon &p = P->get(); - p.owner = &nm; - - Vector<int> poly = nm.navmesh->get_polygon(i); - int plen = poly.size(); - const int *indices = poly.ptr(); - bool valid = true; - p.edges.resize(plen); - - Vector3 center; - float sum = 0; - - for (int j = 0; j < plen; j++) { - - int idx = indices[j]; - if (idx < 0 || idx >= len) { - valid = false; - break; - } - - Polygon::Edge e; - Vector3 ep = nm.xform.xform(r[idx]); - center += ep; - e.point = _get_point(ep); - p.edges.write[j] = e; - - if (j >= 2) { - Vector3 epa = nm.xform.xform(r[indices[j - 2]]); - Vector3 epb = nm.xform.xform(r[indices[j - 1]]); - - sum += up.dot((epb - epa).cross(ep - epa)); - } - } - - p.clockwise = sum > 0; - - if (!valid) { - nm.polygons.pop_back(); - ERR_CONTINUE(!valid); - } - - p.center = center; - if (plen != 0) { - p.center /= plen; - } - - //connect - - for (int j = 0; j < plen; j++) { - - int next = (j + 1) % plen; - EdgeKey ek(p.edges[j].point, p.edges[next].point); - - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - if (!C) { - - Connection c; - c.A = &p; - c.A_edge = j; - c.B = NULL; - c.B_edge = -1; - connections[ek] = c; - } else { - - if (C->get().B != NULL) { - ConnectionPending pending; - pending.polygon = &p; - pending.edge = j; - p.edges.write[j].P = C->get().pending.push_back(pending); - continue; - } - - C->get().B = &p; - C->get().B_edge = j; - C->get().A->edges.write[C->get().A_edge].C = &p; - C->get().A->edges.write[C->get().A_edge].C_edge = j; - p.edges.write[j].C = C->get().A; - p.edges.write[j].C_edge = C->get().A_edge; - //connection successful. - } - } - } - - nm.linked = true; + return NavigationServer::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); } -void Navigation::_navmesh_unlink(int p_id) { - - ERR_FAIL_COND(!navmesh_map.has(p_id)); - NavMesh &nm = navmesh_map[p_id]; - ERR_FAIL_COND(!nm.linked); - - for (List<Polygon>::Element *E = nm.polygons.front(); E; E = E->next()) { - - Polygon &p = E->get(); - - int ec = p.edges.size(); - Polygon::Edge *edges = p.edges.ptrw(); - - for (int i = 0; i < ec; i++) { - int next = (i + 1) % ec; - - EdgeKey ek(edges[i].point, edges[next].point); - Map<EdgeKey, Connection>::Element *C = connections.find(ek); - - ERR_CONTINUE(!C); - - if (edges[i].P) { - C->get().pending.erase(edges[i].P); - edges[i].P = NULL; - } else if (C->get().B) { - //disconnect - - C->get().B->edges.write[C->get().B_edge].C = NULL; - C->get().B->edges.write[C->get().B_edge].C_edge = -1; - C->get().A->edges.write[C->get().A_edge].C = NULL; - C->get().A->edges.write[C->get().A_edge].C_edge = -1; - - if (C->get().A == &E->get()) { - - C->get().A = C->get().B; - C->get().A_edge = C->get().B_edge; - } - C->get().B = NULL; - C->get().B_edge = -1; - - if (C->get().pending.size()) { - //reconnect if something is pending - ConnectionPending cp = C->get().pending.front()->get(); - C->get().pending.pop_front(); - - C->get().B = cp.polygon; - C->get().B_edge = cp.edge; - C->get().A->edges.write[C->get().A_edge].C = cp.polygon; - C->get().A->edges.write[C->get().A_edge].C_edge = cp.edge; - cp.polygon->edges.write[cp.edge].C = C->get().A; - cp.polygon->edges.write[cp.edge].C_edge = C->get().A_edge; - cp.polygon->edges.write[cp.edge].P = NULL; - } - - } else { - connections.erase(C); - //erase - } - } - } - - nm.polygons.clear(); - - nm.linked = false; +Vector3 Navigation::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const { + return NavigationServer::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision); } -int Navigation::navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner) { - - int id = last_id++; - NavMesh nm; - nm.linked = false; - nm.navmesh = p_mesh; - nm.xform = p_xform; - nm.owner = p_owner; - navmesh_map[id] = nm; - - _navmesh_link(id); - - return id; +Vector3 Navigation::get_closest_point(const Vector3 &p_point) const { + return NavigationServer::get_singleton()->map_get_closest_point(map, p_point); } -void Navigation::navmesh_set_transform(int p_id, const Transform &p_xform) { - - ERR_FAIL_COND(!navmesh_map.has(p_id)); - NavMesh &nm = navmesh_map[p_id]; - if (nm.xform == p_xform) - return; //bleh - _navmesh_unlink(p_id); - nm.xform = p_xform; - _navmesh_link(p_id); +Vector3 Navigation::get_closest_point_normal(const Vector3 &p_point) const { + return NavigationServer::get_singleton()->map_get_closest_point_normal(map, p_point); } -void Navigation::navmesh_remove(int p_id) { - ERR_FAIL_COND_MSG(!navmesh_map.has(p_id), "Trying to remove nonexisting navmesh with id: " + itos(p_id)); - _navmesh_unlink(p_id); - navmesh_map.erase(p_id); -} - -void Navigation::_clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly) { - - Vector3 from = path[path.size() - 1]; - - if (from.distance_to(p_to_point) < CMP_EPSILON) - return; - Plane cut_plane; - cut_plane.normal = (from - p_to_point).cross(up); - if (cut_plane.normal == Vector3()) - return; - cut_plane.normal.normalize(); - cut_plane.d = cut_plane.normal.dot(from); - - while (from_poly != p_to_poly) { - - int pe = from_poly->prev_edge; - Vector3 a = _get_vertex(from_poly->edges[pe].point); - Vector3 b = _get_vertex(from_poly->edges[(pe + 1) % from_poly->edges.size()].point); - - from_poly = from_poly->edges[pe].C; - ERR_FAIL_COND(!from_poly); - - if (a.distance_to(b) > CMP_EPSILON) { - - Vector3 inters; - if (cut_plane.intersects_segment(a, b, &inters)) { - if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) { - path.push_back(inters); - } - } - } - } -} - -Vector<Vector3> Navigation::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) { - - Polygon *begin_poly = NULL; - Polygon *end_poly = NULL; - Vector3 begin_point; - Vector3 end_point; - float begin_d = 1e20; - float end_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point)); - Vector3 spoint = f.get_closest_point_to(p_start); - float dpoint = spoint.distance_to(p_start); - if (dpoint < begin_d) { - begin_d = dpoint; - begin_poly = &p; - begin_point = spoint; - } - - spoint = f.get_closest_point_to(p_end); - dpoint = spoint.distance_to(p_end); - if (dpoint < end_d) { - end_d = dpoint; - end_poly = &p; - end_point = spoint; - } - } - - p.prev_edge = -1; - } - } - - if (!begin_poly || !end_poly) { - - return Vector<Vector3>(); //no path - } - - if (begin_poly == end_poly) { - - Vector<Vector3> path; - path.resize(2); - path.write[0] = begin_point; - path.write[1] = end_point; - return path; - } - - bool found_route = false; - - List<Polygon *> open_list; - - for (int i = 0; i < begin_poly->edges.size(); i++) { - - if (begin_poly->edges[i].C) { - - begin_poly->edges[i].C->prev_edge = begin_poly->edges[i].C_edge; -#ifdef USE_ENTRY_POINT - Vector3 edge[2] = { - _get_vertex(begin_poly->edges[i].point), - _get_vertex(begin_poly->edges[(i + 1) % begin_poly->edges.size()].point) - }; - - Vector3 entry = Geometry::get_closest_point_to_segment(begin_poly->entry, edge); - begin_poly->edges[i].C->distance = begin_point.distance_to(entry); - begin_poly->edges[i].C->entry = entry; -#else - begin_poly->edges[i].C->distance = begin_poly->center.distance_to(begin_poly->edges[i].C->center); -#endif - open_list.push_back(begin_poly->edges[i].C); - } - } - - while (!found_route) { - - if (open_list.size() == 0) { - break; - } - //check open list - - List<Polygon *>::Element *least_cost_poly = NULL; - float least_cost = 1e30; - - //this could be faster (cache previous results) - for (List<Polygon *>::Element *E = open_list.front(); E; E = E->next()) { - - Polygon *p = E->get(); - - float cost = p->distance; -#ifdef USE_ENTRY_POINT - cost += p->entry.distance_to(end_point); -#else - cost += p->center.distance_to(end_point); -#endif - if (cost < least_cost) { - least_cost_poly = E; - least_cost = cost; - } - } - - Polygon *p = least_cost_poly->get(); - //open the neighbours for search - - if (p == end_poly) { - //oh my reached end! stop algorithm - found_route = true; - break; - } - - for (int i = 0; i < p->edges.size(); i++) { - - Polygon::Edge &e = p->edges.write[i]; - - if (!e.C) - continue; - -#ifdef USE_ENTRY_POINT - Vector3 edge[2] = { - _get_vertex(p->edges[i].point), - _get_vertex(p->edges[(i + 1) % p->edges.size()].point) - }; - - Vector3 entry = Geometry::get_closest_point_to_segment(p->entry, edge); - float distance = p->entry.distance_to(entry) + p->distance; -#else - float distance = p->center.distance_to(e.C->center) + p->distance; -#endif - - if (e.C->prev_edge != -1) { - //oh this was visited already, can we win the cost? - - if (e.C->distance > distance) { - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = entry; -#endif - } - } else { - //add to open neighbours - - e.C->prev_edge = e.C_edge; - e.C->distance = distance; -#ifdef USE_ENTRY_POINT - e.C->entry = entry; -#endif - open_list.push_back(e.C); - } - } - - open_list.erase(least_cost_poly); - } - - if (found_route) { - - Vector<Vector3> path; - - if (p_optimize) { - //string pulling - - Polygon *apex_poly = end_poly; - Vector3 apex_point = end_point; - Vector3 portal_left = apex_point; - Vector3 portal_right = apex_point; - Polygon *left_poly = end_poly; - Polygon *right_poly = end_poly; - Polygon *p = end_poly; - path.push_back(end_point); - - while (p) { - - Vector3 left; - Vector3 right; - -#define CLOCK_TANGENT(m_a, m_b, m_c) (((m_a) - (m_c)).cross((m_a) - (m_b))) - - if (p == begin_poly) { - left = begin_point; - right = begin_point; - } else { - int prev = p->prev_edge; - int prev_n = (p->prev_edge + 1) % p->edges.size(); - left = _get_vertex(p->edges[prev].point); - right = _get_vertex(p->edges[prev_n].point); - - //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){ - if (p->clockwise) { - SWAP(left, right); - } - } - - bool skip = false; - - if (CLOCK_TANGENT(apex_point, portal_left, left).dot(up) >= 0) { - //process - if (portal_left == apex_point || CLOCK_TANGENT(apex_point, left, portal_right).dot(up) > 0) { - left_poly = p; - portal_left = left; - } else { - - _clip_path(path, apex_poly, portal_right, right_poly); - - apex_point = portal_right; - p = right_poly; - left_poly = p; - apex_poly = p; - portal_left = apex_point; - portal_right = apex_point; - path.push_back(apex_point); - skip = true; - } - } - - if (!skip && CLOCK_TANGENT(apex_point, portal_right, right).dot(up) <= 0) { - //process - if (portal_right == apex_point || CLOCK_TANGENT(apex_point, right, portal_left).dot(up) < 0) { - right_poly = p; - portal_right = right; - } else { - - _clip_path(path, apex_poly, portal_left, left_poly); - - apex_point = portal_left; - p = left_poly; - right_poly = p; - apex_poly = p; - portal_right = apex_point; - portal_left = apex_point; - path.push_back(apex_point); - } - } - - if (p != begin_poly) - p = p->edges[p->prev_edge].C; - else - p = NULL; - } - - if (path[path.size() - 1] != begin_point) - path.push_back(begin_point); - - path.invert(); - - } else { - //midpoints - Polygon *p = end_poly; - - path.push_back(end_point); - while (true) { - int prev = p->prev_edge; -#ifdef USE_ENTRY_POINT - Vector3 point = p->entry; -#else - int prev_n = (p->prev_edge + 1) % p->edges.size(); - Vector3 point = (_get_vertex(p->edges[prev].point) + _get_vertex(p->edges[prev_n].point)) * 0.5; -#endif - path.push_back(point); - p = p->edges[prev].C; - if (p == begin_poly) - break; - } - - path.push_back(begin_point); - - path.invert(); - } - - return path; - } - - return Vector<Vector3>(); -} - -Vector3 Navigation::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision) { - - bool use_collision = p_use_collision; - Vector3 closest_point; - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point)); - Vector3 inters; - if (f.intersects_segment(p_from, p_to, &inters)) { - - if (!use_collision) { - closest_point = inters; - use_collision = true; - closest_point_d = p_from.distance_to(inters); - } else if (closest_point_d > inters.distance_to(p_from)) { - - closest_point = inters; - closest_point_d = p_from.distance_to(inters); - } - } - } - - if (!use_collision) { - - for (int i = 0; i < p.edges.size(); i++) { - - Vector3 a, b; - - Geometry::get_closest_points_between_segments(p_from, p_to, _get_vertex(p.edges[i].point), _get_vertex(p.edges[(i + 1) % p.edges.size()].point), a, b); - - float d = a.distance_to(b); - if (d < closest_point_d) { - - closest_point_d = d; - closest_point = b; - } - } - } - } - } - - return closest_point; -} - -Vector3 Navigation::get_closest_point(const Vector3 &p_point) { - - Vector3 closest_point; - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point)); - Vector3 inters = f.get_closest_point_to(p_point); - float d = inters.distance_to(p_point); - if (d < closest_point_d) { - closest_point = inters; - closest_point_d = d; - } - } - } - } - - return closest_point; -} - -Vector3 Navigation::get_closest_point_normal(const Vector3 &p_point) { - - Vector3 closest_point; - Vector3 closest_normal; - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point)); - Vector3 inters = f.get_closest_point_to(p_point); - float d = inters.distance_to(p_point); - if (d < closest_point_d) { - closest_point = inters; - closest_point_d = d; - closest_normal = f.get_plane().normal; - } - } - } - } - - return closest_normal; -} - -Object *Navigation::get_closest_point_owner(const Vector3 &p_point) { - - Vector3 closest_point; - Object *owner = NULL; - float closest_point_d = 1e20; - - for (Map<int, NavMesh>::Element *E = navmesh_map.front(); E; E = E->next()) { - - if (!E->get().linked) - continue; - for (List<Polygon>::Element *F = E->get().polygons.front(); F; F = F->next()) { - - Polygon &p = F->get(); - for (int i = 2; i < p.edges.size(); i++) { - - Face3 f(_get_vertex(p.edges[0].point), _get_vertex(p.edges[i - 1].point), _get_vertex(p.edges[i].point)); - Vector3 inters = f.get_closest_point_to(p_point); - float d = inters.distance_to(p_point); - if (d < closest_point_d) { - closest_point = inters; - closest_point_d = d; - owner = E->get().owner; - } - } - } - } - - return owner; +RID Navigation::get_closest_point_owner(const Vector3 &p_point) const { + return NavigationServer::get_singleton()->map_get_closest_point_owner(map, p_point); } void Navigation::set_up_vector(const Vector3 &p_up) { up = p_up; + NavigationServer::get_singleton()->map_set_up(map, up); } Vector3 Navigation::get_up_vector() const { @@ -700,11 +64,19 @@ Vector3 Navigation::get_up_vector() const { return up; } +void Navigation::set_cell_size(float p_cell_size) { + cell_size = p_cell_size; + NavigationServer::get_singleton()->map_set_cell_size(map, cell_size); +} + +void Navigation::set_edge_connection_margin(float p_edge_connection_margin) { + edge_connection_margin = p_edge_connection_margin; + NavigationServer::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); +} + void Navigation::_bind_methods() { - ClassDB::bind_method(D_METHOD("navmesh_add", "mesh", "xform", "owner"), &Navigation::navmesh_add, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("navmesh_set_transform", "id", "xform"), &Navigation::navmesh_set_transform); - ClassDB::bind_method(D_METHOD("navmesh_remove", "id"), &Navigation::navmesh_remove); + ClassDB::bind_method(D_METHOD("get_rid"), &Navigation::get_rid); ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation::get_simple_path, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation::get_closest_point_to_segment, DEFVAL(false)); @@ -715,13 +87,39 @@ void Navigation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation::set_up_vector); ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation::get_up_vector); + ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation::set_cell_size); + ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation::get_cell_size); + + ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation::set_edge_connection_margin); + ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation::get_edge_connection_margin); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); +} + +void Navigation::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + NavigationServer::get_singleton()->map_set_active(map, true); + } break; + case NOTIFICATION_EXIT_TREE: { + + NavigationServer::get_singleton()->map_set_active(map, false); + } break; + } } Navigation::Navigation() { - ERR_FAIL_COND(sizeof(Point) != 8); - cell_size = 0.01; //one centimeter - last_id = 1; + map = NavigationServer::get_singleton()->map_create(); + + set_cell_size(0.3); + set_edge_connection_margin(5.0); // Five meters, depends alot on the agents radius + up = Vector3(0, 1, 0); } + +Navigation::~Navigation() { + NavigationServer::get_singleton()->free(map); +} diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index 31dbc9d4b5..08f306611f 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -31,154 +31,49 @@ #ifndef NAVIGATION_H #define NAVIGATION_H -#include "scene/3d/navigation_mesh.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/spatial.h" class Navigation : public Spatial { GDCLASS(Navigation, Spatial); - union Point { - - struct { - int64_t x : 21; - int64_t y : 22; - int64_t z : 21; - }; - - uint64_t key; - bool operator<(const Point &p_key) const { return key < p_key.key; } - }; - - struct EdgeKey { - - Point a; - Point b; - - bool operator<(const EdgeKey &p_key) const { - return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key); - }; - - EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) : - a(p_a), - b(p_b) { - if (a.key > b.key) { - SWAP(a, b); - } - } - }; - - struct NavMesh; - struct Polygon; - - struct ConnectionPending { - - Polygon *polygon; - int edge; - }; - - struct Polygon { - - struct Edge { - Point point; - Polygon *C; //connection - int C_edge; - List<ConnectionPending>::Element *P; - Edge() { - C = NULL; - C_edge = -1; - P = NULL; - } - }; - - Vector<Edge> edges; - - Vector3 center; - Vector3 entry; - - float distance; - int prev_edge; - bool clockwise; - - NavMesh *owner; - }; - - struct Connection { - - Polygon *A; - int A_edge; - Polygon *B; - int B_edge; - - List<ConnectionPending> pending; - - Connection() { - A = NULL; - B = NULL; - A_edge = -1; - B_edge = -1; - } - }; - - Map<EdgeKey, Connection> connections; - - struct NavMesh { - - Object *owner; - Transform xform; - bool linked; - Ref<NavigationMesh> navmesh; - List<Polygon> polygons; - }; - - _FORCE_INLINE_ Point _get_point(const Vector3 &p_pos) const { - - int x = int(Math::floor(p_pos.x / cell_size)); - int y = int(Math::floor(p_pos.y / cell_size)); - int z = int(Math::floor(p_pos.z / cell_size)); - - Point p; - p.key = 0; - p.x = x; - p.y = y; - p.z = z; - return p; - } - - _FORCE_INLINE_ Vector3 _get_vertex(const Point &p_point) const { - - return Vector3(p_point.x, p_point.y, p_point.z) * cell_size; - } - - void _navmesh_link(int p_id); - void _navmesh_unlink(int p_id); - - float cell_size; - Map<int, NavMesh> navmesh_map; - int last_id; + RID map; Vector3 up; - void _clip_path(Vector<Vector3> &path, Polygon *from_poly, const Vector3 &p_to_point, Polygon *p_to_poly); + real_t cell_size; + real_t edge_connection_margin; protected: static void _bind_methods(); + void _notification(int p_what); public: + RID get_rid() const { + return map; + } + void set_up_vector(const Vector3 &p_up); Vector3 get_up_vector() const; - //API should be as dynamic as possible - int navmesh_add(const Ref<NavigationMesh> &p_mesh, const Transform &p_xform, Object *p_owner = NULL); - void navmesh_set_transform(int p_id, const Transform &p_xform); - void navmesh_remove(int p_id); + void set_cell_size(float p_cell_size); + float get_cell_size() const { + return cell_size; + } + + void set_edge_connection_margin(float p_edge_connection_margin); + float get_edge_connection_margin() const { + return edge_connection_margin; + } - Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true); - Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool &p_use_collision = false); - Vector3 get_closest_point(const Vector3 &p_point); - Vector3 get_closest_point_normal(const Vector3 &p_point); - Object *get_closest_point_owner(const Vector3 &p_point); + Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const; + Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const; + Vector3 get_closest_point(const Vector3 &p_point) const; + Vector3 get_closest_point_normal(const Vector3 &p_point) const; + RID get_closest_point_owner(const Vector3 &p_point) const; Navigation(); + ~Navigation(); }; #endif // NAVIGATION_H diff --git a/scene/3d/navigation_agent.cpp b/scene/3d/navigation_agent.cpp new file mode 100644 index 0000000000..728fc947e9 --- /dev/null +++ b/scene/3d/navigation_agent.cpp @@ -0,0 +1,361 @@ +/*************************************************************************/ +/* navigation_agent.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_agent.h" + +#include "core/engine.h" +#include "scene/3d/navigation.h" +#include "servers/navigation_server.h" + +void NavigationAgent::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance); + ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance); + + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationAgent::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &NavigationAgent::get_radius); + + ClassDB::bind_method(D_METHOD("set_agent_height_offset", "agent_height_offset"), &NavigationAgent::set_agent_height_offset); + ClassDB::bind_method(D_METHOD("get_agent_height_offset"), &NavigationAgent::get_agent_height_offset); + + ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent::set_ignore_y); + ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent::get_ignore_y); + + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent::set_navigation_node); + ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent::get_navigation_node); + + ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent::set_neighbor_dist); + ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent::get_neighbor_dist); + + ClassDB::bind_method(D_METHOD("set_max_neighbors", "max_neighbors"), &NavigationAgent::set_max_neighbors); + ClassDB::bind_method(D_METHOD("get_max_neighbors"), &NavigationAgent::get_max_neighbors); + + ClassDB::bind_method(D_METHOD("set_time_horizon", "time_horizon"), &NavigationAgent::set_time_horizon); + ClassDB::bind_method(D_METHOD("get_time_horizon"), &NavigationAgent::get_time_horizon); + + ClassDB::bind_method(D_METHOD("set_max_speed", "max_speed"), &NavigationAgent::set_max_speed); + ClassDB::bind_method(D_METHOD("get_max_speed"), &NavigationAgent::get_max_speed); + + ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent::set_path_max_distance); + ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent::get_path_max_distance); + + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent::set_target_location); + ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent::get_target_location); + ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent::get_next_location); + ClassDB::bind_method(D_METHOD("distance_to_target"), &NavigationAgent::distance_to_target); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &NavigationAgent::set_velocity); + ClassDB::bind_method(D_METHOD("get_nav_path"), &NavigationAgent::get_nav_path); + ClassDB::bind_method(D_METHOD("get_nav_path_index"), &NavigationAgent::get_nav_path_index); + ClassDB::bind_method(D_METHOD("is_target_reached"), &NavigationAgent::is_target_reached); + ClassDB::bind_method(D_METHOD("is_target_reachable"), &NavigationAgent::is_target_reachable); + ClassDB::bind_method(D_METHOD("is_navigation_finished"), &NavigationAgent::is_navigation_finished); + ClassDB::bind_method(D_METHOD("get_final_location"), &NavigationAgent::get_final_location); + + ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent::_avoidance_done); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_target_desired_distance", "get_target_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01"), "set_agent_height_offset", "get_agent_height_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_neighbor_dist", "get_neighbor_dist"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_time_horizon", "get_time_horizon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y"); + + ADD_SIGNAL(MethodInfo("path_changed")); + ADD_SIGNAL(MethodInfo("target_reached")); + ADD_SIGNAL(MethodInfo("navigation_finished")); + ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity"))); +} + +void NavigationAgent::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + + agent_parent = Object::cast_to<Spatial>(get_parent()); + + NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); + + // Search the navigation node and set it + { + Navigation *nav = NULL; + Node *p = get_parent(); + while (p != NULL) { + nav = Object::cast_to<Navigation>(p); + if (nav != NULL) + p = NULL; + else + p = p->get_parent(); + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + agent_parent = NULL; + set_navigation(NULL); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (agent_parent) { + + NavigationServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin); + if (!target_reached) { + if (distance_to_target() < target_desired_distance) { + emit_signal("target_reached"); + target_reached = true; + } + } + } + } break; + } +} + +NavigationAgent::NavigationAgent() : + agent_parent(NULL), + navigation(NULL), + agent(RID()), + target_desired_distance(1.0), + navigation_height_offset(0.0), + path_max_distance(3.0), + velocity_submitted(false), + target_reached(false), + navigation_finished(true) { + agent = NavigationServer::get_singleton()->agent_create(); + set_neighbor_dist(50.0); + set_max_neighbors(10); + set_time_horizon(5.0); + set_radius(1.0); + set_max_speed(10.0); + set_ignore_y(true); +} + +NavigationAgent::~NavigationAgent() { + NavigationServer::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationAgent::set_navigation(Navigation *p_nav) { + if (navigation == p_nav) + return; // Pointless + + navigation = p_nav; + NavigationServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid()); +} + +void NavigationAgent::set_navigation_node(Node *p_nav) { + Navigation *nav = Object::cast_to<Navigation>(p_nav); + ERR_FAIL_COND(nav == NULL); + set_navigation(nav); +} + +Node *NavigationAgent::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +void NavigationAgent::set_target_desired_distance(real_t p_dd) { + target_desired_distance = p_dd; +} + +void NavigationAgent::set_radius(real_t p_radius) { + radius = p_radius; + NavigationServer::get_singleton()->agent_set_radius(agent, radius); +} + +void NavigationAgent::set_agent_height_offset(real_t p_hh) { + navigation_height_offset = p_hh; +} + +void NavigationAgent::set_ignore_y(bool p_ignore_y) { + ignore_y = p_ignore_y; + NavigationServer::get_singleton()->agent_set_ignore_y(agent, ignore_y); +} + +void NavigationAgent::set_neighbor_dist(real_t p_dist) { + neighbor_dist = p_dist; + NavigationServer::get_singleton()->agent_set_neighbor_dist(agent, neighbor_dist); +} + +void NavigationAgent::set_max_neighbors(int p_count) { + max_neighbors = p_count; + NavigationServer::get_singleton()->agent_set_max_neighbors(agent, max_neighbors); +} + +void NavigationAgent::set_time_horizon(real_t p_time) { + time_horizon = p_time; + NavigationServer::get_singleton()->agent_set_time_horizon(agent, time_horizon); +} + +void NavigationAgent::set_max_speed(real_t p_max_speed) { + max_speed = p_max_speed; + NavigationServer::get_singleton()->agent_set_max_speed(agent, max_speed); +} + +void NavigationAgent::set_path_max_distance(real_t p_pmd) { + path_max_distance = p_pmd; +} + +real_t NavigationAgent::get_path_max_distance() { + return path_max_distance; +} + +void NavigationAgent::set_target_location(Vector3 p_location) { + target_location = p_location; + navigation_path.clear(); + target_reached = false; + navigation_finished = false; +} + +Vector3 NavigationAgent::get_target_location() const { + return target_location; +} + +Vector3 NavigationAgent::get_next_location() { + update_navigation(); + if (navigation_path.size() == 0) { + ERR_FAIL_COND_V(agent_parent == NULL, Vector3()); + return agent_parent->get_global_transform().origin; + } else { + return navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0); + } +} + +real_t NavigationAgent::distance_to_target() const { + ERR_FAIL_COND_V(agent_parent == NULL, 0.0); + return agent_parent->get_global_transform().origin.distance_to(target_location); +} + +bool NavigationAgent::is_target_reached() const { + return target_reached; +} + +bool NavigationAgent::is_target_reachable() { + return target_desired_distance >= get_final_location().distance_to(target_location); +} + +bool NavigationAgent::is_navigation_finished() { + update_navigation(); + return navigation_finished; +} + +Vector3 NavigationAgent::get_final_location() { + update_navigation(); + if (navigation_path.size() == 0) { + return Vector3(); + } + return navigation_path[navigation_path.size() - 1]; +} + +void NavigationAgent::set_velocity(Vector3 p_velocity) { + target_velocity = p_velocity; + NavigationServer::get_singleton()->agent_set_target_velocity(agent, target_velocity); + NavigationServer::get_singleton()->agent_set_velocity(agent, prev_safe_velocity); + velocity_submitted = true; +} + +void NavigationAgent::_avoidance_done(Vector3 p_new_velocity) { + prev_safe_velocity = p_new_velocity; + + if (!velocity_submitted) { + target_velocity = Vector3(); + return; + } + velocity_submitted = false; + + emit_signal("velocity_computed", p_new_velocity); +} + +String NavigationAgent::get_configuration_warning() const { + if (!Object::cast_to<Spatial>(get_parent())) { + return TTR("The NavigationAgent can be used only under a spatial node."); + } + + return String(); +} + +void NavigationAgent::update_navigation() { + + if (agent_parent == NULL) return; + if (navigation == NULL) return; + if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return; + + update_frame_id = Engine::get_singleton()->get_physics_frames(); + + Vector3 o = agent_parent->get_global_transform().origin; + + bool reload_path = false; + + if (NavigationServer::get_singleton()->agent_is_map_changed(agent)) { + reload_path = true; + } else if (navigation_path.size() == 0) { + reload_path = true; + } else { + // Check if too far from the navigation path + if (nav_path_index > 0) { + Vector3 segment[2]; + segment[0] = navigation_path[nav_path_index - 1]; + segment[1] = navigation_path[nav_path_index]; + segment[0].y -= navigation_height_offset; + segment[1].y -= navigation_height_offset; + Vector3 p = Geometry::get_closest_point_to_segment(o, segment); + if (o.distance_to(p) >= path_max_distance) { + // To faraway, reload path + reload_path = true; + } + } + } + + if (reload_path) { + navigation_path = NavigationServer::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_finished = false; + nav_path_index = 0; + emit_signal("path_changed"); + } + + if (navigation_path.size() == 0) + return; + + // Check if we can advance the navigation path + if (navigation_finished == false) { + // Advances to the next far away location. + while (o.distance_to(navigation_path[nav_path_index] - Vector3(0, navigation_height_offset, 0)) < target_desired_distance) { + nav_path_index += 1; + if (nav_path_index == navigation_path.size()) { + nav_path_index -= 1; + navigation_finished = true; + emit_signal("navigation_finished"); + break; + } + } + } +} diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h new file mode 100644 index 0000000000..200d5db475 --- /dev/null +++ b/scene/3d/navigation_agent.h @@ -0,0 +1,162 @@ +/*************************************************************************/ +/* navigation_agent.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_AGENT_H +#define NAVIGATION_AGENT_H + +#include "core/vector.h" +#include "scene/main/node.h" + +class Spatial; +class Navigation; + +class NavigationAgent : public Node { + GDCLASS(NavigationAgent, Node); + + Spatial *agent_parent; + Navigation *navigation; + + RID agent; + + real_t target_desired_distance; + real_t radius; + real_t navigation_height_offset; + bool ignore_y; + real_t neighbor_dist; + int max_neighbors; + real_t time_horizon; + real_t max_speed; + + real_t path_max_distance; + + Vector3 target_location; + Vector<Vector3> navigation_path; + int nav_path_index; + bool velocity_submitted; + Vector3 prev_safe_velocity; + /// The submitted target velocity + Vector3 target_velocity; + bool target_reached; + bool navigation_finished; + // No initialized on purpose + uint32_t update_frame_id; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationAgent(); + virtual ~NavigationAgent(); + + void set_navigation(Navigation *p_nav); + const Navigation *get_navigation() const { + return navigation; + } + + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; + + RID get_rid() const { + return agent; + } + + void set_target_desired_distance(real_t p_dd); + real_t get_target_desired_distance() const { + return target_desired_distance; + } + + void set_radius(real_t p_radius); + real_t get_radius() const { + return radius; + } + + void set_agent_height_offset(real_t p_hh); + real_t get_agent_height_offset() const { + return navigation_height_offset; + } + + void set_ignore_y(bool p_ignore_y); + bool get_ignore_y() const { + return ignore_y; + } + + void set_neighbor_dist(real_t p_dist); + real_t get_neighbor_dist() const { + return neighbor_dist; + } + + void set_max_neighbors(int p_count); + int get_max_neighbors() const { + return max_neighbors; + } + + void set_time_horizon(real_t p_time); + real_t get_time_horizon() const { + return time_horizon; + } + + void set_max_speed(real_t p_max_speed); + real_t get_max_speed() const { + return max_speed; + } + + void set_path_max_distance(real_t p_pmd); + real_t get_path_max_distance(); + + void set_target_location(Vector3 p_location); + Vector3 get_target_location() const; + + Vector3 get_next_location(); + + Vector<Vector3> get_nav_path() const { + return navigation_path; + } + + int get_nav_path_index() const { + return nav_path_index; + } + + real_t distance_to_target() const; + bool is_target_reached() const; + bool is_target_reachable(); + bool is_navigation_finished(); + Vector3 get_final_location(); + + void set_velocity(Vector3 p_velocity); + void _avoidance_done(Vector3 p_new_velocity); + + virtual String get_configuration_warning() const; + +private: + void update_navigation(); +}; + +#endif diff --git a/scene/3d/navigation_obstacle.cpp b/scene/3d/navigation_obstacle.cpp new file mode 100644 index 0000000000..befc41eee5 --- /dev/null +++ b/scene/3d/navigation_obstacle.cpp @@ -0,0 +1,163 @@ +/*************************************************************************/ +/* navigation_obstacle.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_obstacle.h" + +#include "scene/3d/collision_shape.h" +#include "scene/3d/navigation.h" +#include "scene/3d/physics_body.h" +#include "servers/navigation_server.h" + +void NavigationObstacle::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle::set_navigation_node); + ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle::get_navigation_node); +} + +void NavigationObstacle::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + + update_agent_shape(); + + // Search the navigation node and set it + { + Navigation *nav = NULL; + Node *p = get_parent(); + while (p != NULL) { + nav = Object::cast_to<Navigation>(p); + if (nav != NULL) + p = NULL; + else + p = p->get_parent(); + } + + set_navigation(nav); + } + + set_physics_process_internal(true); + } break; + case NOTIFICATION_EXIT_TREE: { + set_navigation(NULL); + set_physics_process_internal(false); + } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + Spatial *spatial = Object::cast_to<Spatial>(get_parent()); + if (spatial) { + NavigationServer::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin); + } + + PhysicsBody *rigid = Object::cast_to<PhysicsBody>(get_parent()); + if (rigid) { + + Vector3 v = rigid->get_linear_velocity(); + NavigationServer::get_singleton()->agent_set_velocity(agent, v); + NavigationServer::get_singleton()->agent_set_target_velocity(agent, v); + } + + } break; + } +} + +NavigationObstacle::NavigationObstacle() : + navigation(NULL), + agent(RID()) { + agent = NavigationServer::get_singleton()->agent_create(); +} + +NavigationObstacle::~NavigationObstacle() { + NavigationServer::get_singleton()->free(agent); + agent = RID(); // Pointless +} + +void NavigationObstacle::set_navigation(Navigation *p_nav) { + if (navigation == p_nav) + return; // Pointless + + navigation = p_nav; + NavigationServer::get_singleton()->agent_set_map(agent, navigation == NULL ? RID() : navigation->get_rid()); +} + +void NavigationObstacle::set_navigation_node(Node *p_nav) { + Navigation *nav = Object::cast_to<Navigation>(p_nav); + ERR_FAIL_COND(nav == NULL); + set_navigation(nav); +} + +Node *NavigationObstacle::get_navigation_node() const { + return Object::cast_to<Node>(navigation); +} + +String NavigationObstacle::get_configuration_warning() const { + if (!Object::cast_to<Spatial>(get_parent())) { + + return TTR("The NavigationObstacle only serves to provide collision avoidance to a spatial object."); + } + + return String(); +} + +void NavigationObstacle::update_agent_shape() { + Node *node = get_parent(); + + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < node->get_child_count(); i++) { + // For each collision shape + CollisionShape *cs = Object::cast_to<CollisionShape>(node->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().origin.length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Vector3 s = cs->get_global_transform().basis.get_scale(); + r *= MAX(s.x, MAX(s.y, s.z)); + // Takes the biggest radius + radius = MAX(radius, r); + } + } + Spatial *spa = Object::cast_to<Spatial>(node); + if (spa) { + Vector3 s = spa->get_global_transform().basis.get_scale(); + radius *= MAX(s.x, MAX(s.y, s.z)); + } + + if (radius == 0.0) + radius = 1.0; // Never a 0 radius + + // Initialize the Agent as an object + NavigationServer::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + NavigationServer::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer::get_singleton()->agent_set_radius(agent, radius); + NavigationServer::get_singleton()->agent_set_max_speed(agent, 0.0); +} diff --git a/scene/3d/navigation_obstacle.h b/scene/3d/navigation_obstacle.h new file mode 100644 index 0000000000..7257a43150 --- /dev/null +++ b/scene/3d/navigation_obstacle.h @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* navigation_obstacle.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_OBSTACLE_H +#define NAVIGATION_OBSTACLE_H + +#include "scene/main/node.h" + +class Navigation; + +class NavigationObstacle : public Node { + GDCLASS(NavigationObstacle, Node); + + Navigation *navigation; + + RID agent; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + NavigationObstacle(); + virtual ~NavigationObstacle(); + + void set_navigation(Navigation *p_nav); + const Navigation *get_navigation() const { + return navigation; + } + + void set_navigation_node(Node *p_nav); + Node *get_navigation_node() const; + + RID get_rid() const { + return agent; + } + + virtual String get_configuration_warning() const; + +private: + void update_agent_shape(); +}; + +#endif diff --git a/scene/3d/navigation_region.cpp b/scene/3d/navigation_region.cpp new file mode 100644 index 0000000000..d96d095797 --- /dev/null +++ b/scene/3d/navigation_region.cpp @@ -0,0 +1,258 @@ +/*************************************************************************/ +/* navigation_region.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "navigation_region.h" +#include "core/os/thread.h" +#include "mesh_instance.h" +#include "navigation.h" +#include "servers/navigation_server.h" + +void NavigationRegion::set_enabled(bool p_enabled) { + + if (enabled == p_enabled) + return; + enabled = p_enabled; + + if (!is_inside_tree()) + return; + + if (!enabled) { + + NavigationServer::get_singleton()->region_set_map(region, RID()); + } else { + + if (navigation) { + + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + } + } + + if (debug_view) { + MeshInstance *dm = Object::cast_to<MeshInstance>(debug_view); + if (is_enabled()) { + dm->set_material_override(get_tree()->get_debug_navigation_material()); + } else { + dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + } + } + + update_gizmo(); +} + +bool NavigationRegion::is_enabled() const { + + return enabled; +} + +///////////////////////////// + +void NavigationRegion::_notification(int p_what) { + + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + + Spatial *c = this; + while (c) { + + navigation = Object::cast_to<Navigation>(c); + if (navigation) { + + if (enabled) { + + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + } + break; + } + + c = c->get_parent_spatial(); + } + + if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { + + MeshInstance *dm = memnew(MeshInstance); + dm->set_mesh(navmesh->get_debug_mesh()); + if (is_enabled()) { + dm->set_material_override(get_tree()->get_debug_navigation_material()); + } else { + dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); + } + add_child(dm); + debug_view = dm; + } + + } break; + case NOTIFICATION_TRANSFORM_CHANGED: { + + NavigationServer::get_singleton()->region_set_transform(region, get_global_transform()); + + } break; + case NOTIFICATION_EXIT_TREE: { + + if (navigation) { + + NavigationServer::get_singleton()->region_set_map(region, RID()); + } + + if (debug_view) { + debug_view->queue_delete(); + debug_view = NULL; + } + navigation = NULL; + } break; + } +} + +void NavigationRegion::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) { + + if (p_navmesh == navmesh) + return; + + if (navmesh.is_valid()) { + navmesh->remove_change_receptor(this); + } + + navmesh = p_navmesh; + + if (navmesh.is_valid()) { + navmesh->add_change_receptor(this); + } + + NavigationServer::get_singleton()->region_set_navmesh(region, p_navmesh); + + if (debug_view && navmesh.is_valid()) { + Object::cast_to<MeshInstance>(debug_view)->set_mesh(navmesh->get_debug_mesh()); + } + + emit_signal("navigation_mesh_changed"); + + update_gizmo(); + update_configuration_warning(); +} + +Ref<NavigationMesh> NavigationRegion::get_navigation_mesh() const { + + return navmesh; +} + +struct BakeThreadsArgs { + NavigationRegion *nav_mesh_instance; +}; + +void _bake_navigation_mesh(void *p_user_data) { + BakeThreadsArgs *args = static_cast<BakeThreadsArgs *>(p_user_data); + + if (args->nav_mesh_instance->get_navigation_mesh().is_valid()) { + Ref<NavigationMesh> nav_mesh = args->nav_mesh_instance->get_navigation_mesh()->duplicate(); + + NavigationServer::get_singleton()->region_bake_navmesh(nav_mesh, args->nav_mesh_instance); + args->nav_mesh_instance->call_deferred("_bake_finished", nav_mesh); + memdelete(args); + } else { + + ERR_PRINT("Can't bake the navigation mesh if the `NavigationMesh` resource doesn't exist"); + args->nav_mesh_instance->call_deferred("_bake_finished", Ref<NavigationMesh>()); + memdelete(args); + } +} + +void NavigationRegion::bake_navigation_mesh() { + ERR_FAIL_COND(bake_thread != NULL); + + BakeThreadsArgs *args = memnew(BakeThreadsArgs); + args->nav_mesh_instance = this; + + bake_thread = Thread::create(_bake_navigation_mesh, args); + ERR_FAIL_COND(bake_thread == NULL); +} + +void NavigationRegion::_bake_finished(Ref<NavigationMesh> p_nav_mesh) { + set_navigation_mesh(p_nav_mesh); + bake_thread = NULL; +} + +String NavigationRegion::get_configuration_warning() const { + + if (!is_visible_in_tree() || !is_inside_tree()) + return String(); + + if (!navmesh.is_valid()) { + return TTR("A NavigationMesh resource must be set or created for this node to work."); + } + const Spatial *c = this; + while (c) { + + if (Object::cast_to<Navigation>(c)) + return String(); + + c = Object::cast_to<Spatial>(c->get_parent()); + } + + return TTR("NavigationRegion must be a child or grandchild to a Navigation node. It only provides navigation data."); +} + +void NavigationRegion::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationRegion::set_navigation_mesh); + ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationRegion::get_navigation_mesh); + + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion::is_enabled); + + ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion::bake_navigation_mesh); + ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion::_bake_finished); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + + ADD_SIGNAL(MethodInfo("navigation_mesh_changed")); + ADD_SIGNAL(MethodInfo("bake_finished")); +} + +void NavigationRegion::_changed_callback(Object *p_changed, const char *p_prop) { + update_gizmo(); + update_configuration_warning(); +} + +NavigationRegion::NavigationRegion() { + + enabled = true; + set_notify_transform(true); + region = NavigationServer::get_singleton()->region_create(); + + navigation = NULL; + debug_view = NULL; + bake_thread = NULL; +} + +NavigationRegion::~NavigationRegion() { + if (navmesh.is_valid()) + navmesh->remove_change_receptor(this); + NavigationServer::get_singleton()->free(region); +} diff --git a/scene/3d/navigation_region.h b/scene/3d/navigation_region.h new file mode 100644 index 0000000000..f215e92c97 --- /dev/null +++ b/scene/3d/navigation_region.h @@ -0,0 +1,75 @@ +/*************************************************************************/ +/* navigation_region.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NAVIGATION_REGION_H +#define NAVIGATION_REGION_H + +#include "scene/3d/spatial.h" +#include "scene/resources/mesh.h" +#include "scene/resources/navigation_mesh.h" + +class Navigation; + +class NavigationRegion : public Spatial { + + GDCLASS(NavigationRegion, Spatial); + + bool enabled; + RID region; + Ref<NavigationMesh> navmesh; + + Navigation *navigation; + Node *debug_view; + Thread *bake_thread; + +protected: + void _notification(int p_what); + static void _bind_methods(); + void _changed_callback(Object *p_changed, const char *p_prop); + +public: + void set_enabled(bool p_enabled); + bool is_enabled() const; + + void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh); + Ref<NavigationMesh> get_navigation_mesh() const; + + /// Bakes the navigation mesh in a dedicated thread; once done, automatically + /// sets the new navigation mesh and emits a signal + void bake_navigation_mesh(); + void _bake_finished(Ref<NavigationMesh> p_nav_mesh); + + String get_configuration_warning() const; + + NavigationRegion(); + ~NavigationRegion(); +}; + +#endif // NAVIGATION_REGION_H diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index add563d991..e502b0c037 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -39,9 +39,9 @@ AABB Particles::get_aabb() const { return AABB(); } -PoolVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> Particles::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } void Particles::set_emitting(bool p_emitting) { @@ -254,16 +254,16 @@ String Particles::get_configuration_warning() const { meshes_found = true; for (int j = 0; j < draw_passes[i]->get_surface_count(); j++) { anim_material_found = Object::cast_to<ShaderMaterial>(draw_passes[i]->surface_get_material(j).ptr()) != NULL; - SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(draw_passes[i]->surface_get_material(j).ptr()); - anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(draw_passes[i]->surface_get_material(j).ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); } if (anim_material_found) break; } } anim_material_found = anim_material_found || Object::cast_to<ShaderMaterial>(get_material_override().ptr()) != NULL; - SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(get_material_override().ptr()); - anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); + StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(get_material_override().ptr()); + anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); if (!meshes_found) { if (warnings != String()) @@ -282,7 +282,7 @@ String Particles::get_configuration_warning() const { process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { if (warnings != String()) warnings += "\n"; - warnings += "- " + TTR("Particles animation requires the usage of a SpatialMaterial whose Billboard Mode is set to \"Particle Billboard\"."); + warnings += "- " + TTR("Particles animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\"."); } } @@ -386,12 +386,12 @@ void Particles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emitting"), "set_emitting", "is_emitting"); ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_EXP_RANGE, "1,1000000,1"), "set_amount", "get_amount"); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_EXP_RANGE, "0.01,600.0,0.01,or_greater"), "set_lifetime", "get_lifetime"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "preprocess", PROPERTY_HINT_EXP_RANGE, "0.00,600.0,0.01"), "set_pre_process_time", "get_pre_process_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); diff --git a/scene/3d/particles.h b/scene/3d/particles.h index 69be7da29a..95c6de15ec 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -78,7 +78,7 @@ protected: public: AABB get_aabb() const; - PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + Vector<Face3> get_faces(uint32_t p_usage_flags) const; void set_emitting(bool p_emitting); void set_amount(int p_amount); diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index ac012de1ab..f93485d79f 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -59,13 +59,13 @@ void Path::_curve_changed() { void Path::set_curve(const Ref<Curve3D> &p_curve) { if (curve.is_valid()) { - curve->disconnect("changed", this, "_curve_changed"); + curve->disconnect("changed", callable_mp(this, &Path::_curve_changed)); } curve = p_curve; if (curve.is_valid()) { - curve->connect("changed", this, "_curve_changed"); + curve->connect("changed", callable_mp(this, &Path::_curve_changed)); } _curve_changed(); } @@ -79,7 +79,6 @@ void Path::_bind_methods() { ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path::set_curve); ClassDB::bind_method(D_METHOD("get_curve"), &Path::get_curve); - ClassDB::bind_method(D_METHOD("_curve_changed"), &Path::_curve_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve3D"), "set_curve", "get_curve"); @@ -297,10 +296,10 @@ void PathFollow::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow::set_loop); ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow::has_loop); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "h_offset"), "set_h_offset", "get_h_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_offset"), "set_v_offset", "get_v_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cubic_interp"), "set_cubic_interpolation", "get_cubic_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index caeae90238..eba45a5604 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -36,15 +36,14 @@ #include "core/method_bind_ext.gen.inc" #include "core/object.h" #include "core/rid.h" +#include "scene/3d/collision_shape.h" #include "scene/scene_string_names.h" +#include "servers/navigation_server.h" #ifdef TOOLS_ENABLED #include "editor/plugins/spatial_editor_plugin.h" #endif -void PhysicsBody::_notification(int p_what) { -} - Vector3 PhysicsBody::get_linear_velocity() const { return Vector3(); @@ -179,74 +178,17 @@ PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : collision_mask = 1; } -#ifndef DISABLE_DEPRECATED -void StaticBody::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} - -real_t StaticBody::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void StaticBody::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1."); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} - -real_t StaticBody::get_bounce() const { - - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif - void StaticBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &StaticBody::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -283,27 +225,13 @@ void StaticBody::_bind_methods() { ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody::get_constant_angular_velocity); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &StaticBody::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &StaticBody::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &StaticBody::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &StaticBody::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &StaticBody::_reload_physics_characteristics); - ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody::remove_collision_exception_with); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); @@ -393,8 +321,8 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, //E->get().rc=0; E->get().in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree, make_binds(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree, make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody::_body_enter_tree), make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody::_body_exit_tree), make_binds(objid)); if (E->get().in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -420,8 +348,8 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, if (E->get().shapes.empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody::_body_exit_tree)); if (in_tree) emit_signal(SceneStringNames::get_singleton()->body_exited, node); } @@ -619,70 +547,17 @@ real_t RigidBody::get_weight() const { return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)); } -#ifndef DISABLE_DEPRECATED -void RigidBody::set_friction(real_t p_friction) { - - if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND(p_friction < 0 || p_friction > 1); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_friction(p_friction); -} -real_t RigidBody::get_friction() const { - - WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); - - if (physics_material_override.is_null()) { - return 1; - } - - return physics_material_override->get_friction(); -} - -void RigidBody::set_bounce(real_t p_bounce) { - - if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that - return; - } - - WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - - ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); - - if (physics_material_override.is_null()) { - physics_material_override.instance(); - set_physics_material_override(physics_material_override); - } - physics_material_override->set_bounce(p_bounce); -} -real_t RigidBody::get_bounce() const { - WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); - if (physics_material_override.is_null()) { - return 0; - } - - return physics_material_override->get_bounce(); -} -#endif // DISABLE_DEPRECATED - void RigidBody::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { if (physics_material_override.is_valid()) { - if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics")) - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody::_reload_physics_characteristics)); + } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, this, "_reload_physics_characteristics"); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody::_reload_physics_characteristics)); } _reload_physics_characteristics(); } @@ -862,9 +737,8 @@ void RigidBody::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - - node->disconnect(SceneStringNames::get_singleton()->tree_entered, this, SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, SceneStringNames::get_singleton()->_body_exit_tree); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody::_body_exit_tree)); } } @@ -936,19 +810,9 @@ void RigidBody::_bind_methods() { ClassDB::bind_method(D_METHOD("set_weight", "weight"), &RigidBody::set_weight); ClassDB::bind_method(D_METHOD("get_weight"), &RigidBody::get_weight); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_friction", "friction"), &RigidBody::set_friction); - ClassDB::bind_method(D_METHOD("get_friction"), &RigidBody::get_friction); - - ClassDB::bind_method(D_METHOD("set_bounce", "bounce"), &RigidBody::set_bounce); - ClassDB::bind_method(D_METHOD("get_bounce"), &RigidBody::get_bounce); -#endif // DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody::get_physics_material_override); - ClassDB::bind_method(D_METHOD("_reload_physics_characteristics"), &RigidBody::_reload_physics_characteristics); - ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidBody::set_linear_velocity); ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidBody::get_linear_velocity); @@ -993,8 +857,6 @@ void RigidBody::_bind_methods() { ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody::is_able_to_sleep); ClassDB::bind_method(D_METHOD("_direct_state_changed"), &RigidBody::_direct_state_changed); - ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree); - ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree); ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody::set_axis_lock); ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody::get_axis_lock); @@ -1004,14 +866,10 @@ void RigidBody::_bind_methods() { BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); -#ifndef DISABLE_DEPRECATED - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); -#endif // DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "continuous_cd"), "set_use_continuous_collision_detection", "is_using_continuous_collision_detection"); ADD_PROPERTY(PropertyInfo(Variant::INT, "contacts_reported", PROPERTY_HINT_RANGE, "0,64,1,or_greater"), "set_max_contacts_reported", "get_max_contacts_reported"); @@ -1027,10 +885,10 @@ void RigidBody::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_GROUP("Angular", "angular_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); @@ -1104,6 +962,14 @@ Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion, bool p_inf return Ref<KinematicCollision>(); } +Vector3 KinematicBody::get_linear_velocity() const { + return linear_velocity; +} + +Vector3 KinematicBody::get_angular_velocity() const { + return angular_velocity; +} + bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { Transform gt = get_global_transform(); @@ -1399,6 +1265,8 @@ void KinematicBody::_notification(int p_what) { void KinematicBody::_bind_methods() { + ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody::_direct_state_changed); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); @@ -1424,7 +1292,18 @@ void KinematicBody::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_y", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_z", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_LINEAR_Z); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); +} + +void KinematicBody::_direct_state_changed(Object *p_state) { +#ifdef DEBUG_ENABLED + PhysicsDirectBodyState *state = Object::cast_to<PhysicsDirectBodyState>(p_state); +#else + PhysicsDirectBodyState *state = (PhysicsDirectBodyState *)p_state; //trust it +#endif + + linear_velocity = state->get_linear_velocity(); + angular_velocity = state->get_angular_velocity(); } KinematicBody::KinematicBody() : @@ -1435,6 +1314,8 @@ KinematicBody::KinematicBody() : on_floor = false; on_ceiling = false; on_wall = false; + + PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); } KinematicBody::~KinematicBody() { @@ -1471,7 +1352,7 @@ Object *KinematicCollision::get_local_shape() const { Object *KinematicCollision::get_collider() const { - if (collision.collider) { + if (collision.collider.is_valid()) { return ObjectDB::get_instance(collision.collider); } @@ -1535,7 +1416,7 @@ void KinematicCollision::_bind_methods() { } KinematicCollision::KinematicCollision() { - collision.collider = 0; + collision.collider_shape = 0; collision.local_shape = 0; owner = NULL; @@ -1562,6 +1443,24 @@ void PhysicalBone::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) PhysicsServer::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse); } +void PhysicalBone::reset_physics_simulation_state() { + if (simulate_physics) { + _start_physics_simulation(); + } else { + _stop_physics_simulation(); + } +} + +void PhysicalBone::reset_to_rest_position() { + if (parent_skeleton) { + if (-1 == bone_id) { + set_global_transform(parent_skeleton->get_global_transform() * body_offset); + } else { + set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset); + } + } +} + bool PhysicalBone::PinJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { if (JointData::_set(p_name, p_value, j)) { return true; @@ -1610,9 +1509,9 @@ bool PhysicalBone::PinJointData::_get(const StringName &p_name, Variant &r_ret) void PhysicalBone::PinJointData::_get_property_list(List<PropertyInfo> *p_list) const { JointData::_get_property_list(p_list); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01")); } bool PhysicalBone::ConeJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -1677,11 +1576,11 @@ bool PhysicalBone::ConeJointData::_get(const StringName &p_name, Variant &r_ret) void PhysicalBone::ConeJointData::_get_property_list(List<PropertyInfo> *p_list) const { JointData::_get_property_list(p_list); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/swing_span", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_lesser,or_greater")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/swing_span", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1,or_lesser,or_greater")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); } bool PhysicalBone::HingeJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -1754,11 +1653,11 @@ void PhysicalBone::HingeJointData::_get_property_list(List<PropertyInfo> *p_list JointData::_get_property_list(p_list); p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/angular_limit_enabled")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01")); } bool PhysicalBone::SliderJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -1858,17 +1757,17 @@ bool PhysicalBone::SliderJointData::_get(const StringName &p_name, Variant &r_re void PhysicalBone::SliderJointData::_get_property_list(List<PropertyInfo> *p_list) const { JointData::_get_property_list(p_list); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_upper")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_lower")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/linear_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/linear_limit_upper")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/linear_limit_lower")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/linear_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/linear_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/angular_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/angular_limit_damping", PROPERTY_HINT_RANGE, "0,16.0,0.01")); } bool PhysicalBone::SixDOFJointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -2082,26 +1981,26 @@ void PhysicalBone::SixDOFJointData::_get_property_list(List<PropertyInfo> *p_lis const StringName axis_names[] = { "x", "y", "z" }; for (int i = 0; i < 3; ++i) { p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/linear_limit_enabled")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_upper")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_lower")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_limit_upper")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_limit_lower")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/linear_spring_enabled")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_stiffness")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_spring_damping")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_equilibrium_point")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/linear_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_spring_stiffness")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_spring_damping")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_equilibrium_point")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/linear_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_limit_enabled")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/erp")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_limit_upper", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_limit_lower", PROPERTY_HINT_RANGE, "-180,180,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_limit_softness", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_damping", PROPERTY_HINT_RANGE, "0.01,16,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/erp")); p_list->push_back(PropertyInfo(Variant::BOOL, "joint_constraints/" + axis_names[i] + "/angular_spring_enabled")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_stiffness")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_spring_damping")); - p_list->push_back(PropertyInfo(Variant::REAL, "joint_constraints/" + axis_names[i] + "/angular_equilibrium_point")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_spring_stiffness")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_spring_damping")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "joint_constraints/" + axis_names[i] + "/angular_equilibrium_point")); } } @@ -2150,10 +2049,10 @@ void PhysicalBone::_get_property_list(List<PropertyInfo> *p_list) const { names += parent->get_bone_name(i); } - p_list->push_back(PropertyInfo(Variant::STRING, "bone_name", PROPERTY_HINT_ENUM, names)); + p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name", PROPERTY_HINT_ENUM, names)); } else { - p_list->push_back(PropertyInfo(Variant::STRING, "bone_name")); + p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name")); } if (joint_data) { @@ -2167,7 +2066,7 @@ void PhysicalBone::_notification(int p_what) { parent_skeleton = find_skeleton_parent(get_parent()); update_bone_id(); reset_to_rest_position(); - _reset_physics_simulation_state(); + reset_physics_simulation_state(); if (!joint.is_valid() && joint_data) { _reload_joint(); } @@ -2238,8 +2137,6 @@ void PhysicalBone::_bind_methods() { ClassDB::bind_method(D_METHOD("set_body_offset", "offset"), &PhysicalBone::set_body_offset); ClassDB::bind_method(D_METHOD("get_body_offset"), &PhysicalBone::get_body_offset); - ClassDB::bind_method(D_METHOD("is_static_body"), &PhysicalBone::is_static_body); - ClassDB::bind_method(D_METHOD("get_simulate_physics"), &PhysicalBone::get_simulate_physics); ClassDB::bind_method(D_METHOD("is_simulating_physics"), &PhysicalBone::is_simulating_physics); @@ -2267,11 +2164,11 @@ void PhysicalBone::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_weight", "get_weight"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_weight", "get_weight"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); @@ -2508,26 +2405,13 @@ const Transform &PhysicalBone::get_joint_offset() const { return joint_offset; } -void PhysicalBone::set_static_body(bool p_static) { - - static_body = p_static; - - set_as_toplevel(!static_body); - - _reset_physics_simulation_state(); -} - -bool PhysicalBone::is_static_body() { - return static_body; -} - void PhysicalBone::set_simulate_physics(bool p_simulate) { if (simulate_physics == p_simulate) { return; } simulate_physics = p_simulate; - _reset_physics_simulation_state(); + reset_physics_simulation_state(); } bool PhysicalBone::get_simulate_physics() { @@ -2535,7 +2419,7 @@ bool PhysicalBone::get_simulate_physics() { } bool PhysicalBone::is_simulating_physics() { - return _internal_simulate_physics && !_internal_static_body; + return _internal_simulate_physics; } void PhysicalBone::set_bone_name(const String &p_name) { @@ -2618,8 +2502,6 @@ PhysicalBone::PhysicalBone() : #endif joint_data(NULL), parent_skeleton(NULL), - static_body(false), - _internal_static_body(false), simulate_physics(false), _internal_simulate_physics(false), bone_id(-1), @@ -2629,8 +2511,7 @@ PhysicalBone::PhysicalBone() : friction(1), gravity_scale(1) { - set_static_body(static_body); - _reset_physics_simulation_state(); + reset_physics_simulation_state(); } PhysicalBone::~PhysicalBone() { @@ -2657,8 +2538,7 @@ void PhysicalBone::update_bone_id() { parent_skeleton->bind_physical_bone_to_bone(bone_id, this); _fix_joint_offset(); - _internal_static_body = !static_body; // Force staticness reset - _reset_staticness_state(); + reset_physics_simulation_state(); } } @@ -2680,49 +2560,6 @@ void PhysicalBone::update_offset() { #endif } -void PhysicalBone::reset_to_rest_position() { - if (parent_skeleton) { - if (-1 == bone_id) { - set_global_transform(parent_skeleton->get_global_transform() * body_offset); - } else { - set_global_transform(parent_skeleton->get_global_transform() * parent_skeleton->get_bone_global_pose(bone_id) * body_offset); - } - } -} - -void PhysicalBone::_reset_physics_simulation_state() { - if (simulate_physics && !static_body) { - _start_physics_simulation(); - } else { - _stop_physics_simulation(); - } - - _reset_staticness_state(); -} - -void PhysicalBone::_reset_staticness_state() { - - if (parent_skeleton && -1 != bone_id) { - if (static_body && simulate_physics) { // With this check I'm sure the position of this body is updated only when it's necessary - - if (_internal_static_body) { - return; - } - - parent_skeleton->bind_child_node_to_bone(bone_id, this); - _internal_static_body = true; - } else { - - if (!_internal_static_body) { - return; - } - - parent_skeleton->unbind_child_node_from_bone(bone_id, this); - _internal_static_body = false; - } - } -} - void PhysicalBone::_start_physics_simulation() { if (_internal_simulate_physics || !parent_skeleton) { return; @@ -2732,17 +2569,27 @@ void PhysicalBone::_start_physics_simulation() { PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); + set_as_toplevel(true); _internal_simulate_physics = true; } void PhysicalBone::_stop_physics_simulation() { - if (!_internal_simulate_physics || !parent_skeleton) { + if (!parent_skeleton) { return; } - PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC); - PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0); - PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0); - PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, ""); - parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false); - _internal_simulate_physics = false; + if (parent_skeleton->get_animate_physical_bones()) { + PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_KINEMATIC); + PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); + PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); + } else { + PhysicsServer::get_singleton()->body_set_mode(get_rid(), PhysicsServer::BODY_MODE_STATIC); + PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), 0); + PhysicsServer::get_singleton()->body_set_collision_mask(get_rid(), 0); + } + if (_internal_simulate_physics) { + PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, ""); + parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false); + set_as_toplevel(false); + _internal_simulate_physics = false; + } } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 05bcbe22f0..5362baf8ee 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -49,7 +49,6 @@ class PhysicsBody : public CollisionObject { protected: static void _bind_methods(); - void _notification(int p_what); PhysicsBody(PhysicsServer::BodyMode p_mode); public: @@ -89,14 +88,6 @@ protected: static void _bind_methods(); public: -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif - void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -205,14 +196,6 @@ public: void set_weight(real_t p_weight); real_t get_weight() const; -#ifndef DISABLE_DEPRECATED - void set_friction(real_t p_friction); - real_t get_friction() const; - - void set_bounce(real_t p_bounce); - real_t get_bounce() const; -#endif - void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -296,6 +279,9 @@ public: }; private: + Vector3 linear_velocity; + Vector3 angular_velocity; + uint16_t locked_axis; float margin; @@ -319,7 +305,12 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual void _direct_state_changed(Object *p_state); + public: + virtual Vector3 get_linear_velocity() const; + virtual Vector3 get_angular_velocity() const; + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false); bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia); @@ -562,8 +553,6 @@ private: Skeleton *parent_skeleton; Transform body_offset; Transform body_offset_inverse; - bool static_body; - bool _internal_static_body; bool simulate_physics; bool _internal_simulate_physics; int bone_id; @@ -613,9 +602,6 @@ public: void set_body_offset(const Transform &p_offset); const Transform &get_body_offset() const; - void set_static_body(bool p_static); - bool is_static_body(); - void set_simulate_physics(bool p_simulate); bool get_simulate_physics(); bool is_simulating_physics(); @@ -641,16 +627,15 @@ public: void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse); + void reset_physics_simulation_state(); + void reset_to_rest_position(); + PhysicalBone(); ~PhysicalBone(); private: void update_bone_id(); void update_offset(); - void reset_to_rest_position(); - - void _reset_physics_simulation_state(); - void _reset_staticness_state(); void _start_physics_simulation(); void _stop_physics_simulation(); diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp index eacc6bcc0f..0699e366e0 100644 --- a/scene/3d/physics_joint.cpp +++ b/scene/3d/physics_joint.cpp @@ -172,9 +172,9 @@ void PinJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &PinJoint::set_param); ClassDB::bind_method(D_METHOD("get_param", "param"), &PinJoint::get_param); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01"), "set_param", "get_param", PARAM_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01"), "set_param", "get_param", PARAM_IMPULSE_CLAMP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/damping", PROPERTY_HINT_RANGE, "0.01,8.0,0.01"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/impulse_clamp", PROPERTY_HINT_RANGE, "0.0,64.0,0.01"), "set_param", "get_param", PARAM_IMPULSE_CLAMP); BIND_ENUM_CONSTANT(PARAM_BIAS); BIND_ENUM_CONSTANT(PARAM_DAMPING); @@ -257,18 +257,18 @@ void HingeJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_lower_limit", "lower_limit"), &HingeJoint::_set_lower_limit); ClassDB::bind_method(D_METHOD("_get_lower_limit"), &HingeJoint::_get_lower_limit); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "params/bias", PROPERTY_HINT_RANGE, "0.00,0.99,0.01"), "set_param", "get_param", PARAM_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "params/bias", PROPERTY_HINT_RANGE, "0.00,0.99,0.01"), "set_param", "get_param", PARAM_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit/enable"), "set_flag", "get_flag", FLAG_USE_LIMIT); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit/upper", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_upper_limit", "_get_upper_limit"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit/lower", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_lower_limit", "_get_lower_limit"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_LIMIT_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_RELAXATION); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit/upper", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_upper_limit", "_get_upper_limit"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit/lower", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_lower_limit", "_get_lower_limit"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/bias", PROPERTY_HINT_RANGE, "0.01,0.99,0.01"), "set_param", "get_param", PARAM_LIMIT_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/relaxation", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param", "get_param", PARAM_LIMIT_RELAXATION); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "motor/enable"), "set_flag", "get_flag", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_lesser"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "motor/max_impulse", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), "set_param", "get_param", PARAM_MOTOR_MAX_IMPULSE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/target_velocity", PROPERTY_HINT_RANGE, "-200,200,0.01,or_greater,or_lesser"), "set_param", "get_param", PARAM_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "motor/max_impulse", PROPERTY_HINT_RANGE, "0.01,1024,0.01"), "set_param", "get_param", PARAM_MOTOR_MAX_IMPULSE); BIND_ENUM_CONSTANT(PARAM_BIAS); BIND_ENUM_CONSTANT(PARAM_LIMIT_UPPER); @@ -392,29 +392,29 @@ void SliderJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_lower_limit_angular", "lower_limit_angular"), &SliderJoint::_set_lower_limit_angular); ClassDB::bind_method(D_METHOD("_get_lower_limit_angular"), &SliderJoint::_get_lower_limit_angular); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit/upper_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_UPPER); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit/lower_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_LOWER); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_DAMPING); - - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_upper_limit_angular", "_get_upper_limit_angular"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_lower_limit_angular", "_get_lower_limit_angular"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/upper_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_UPPER); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/lower_distance", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_LOWER); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_LIMIT_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_MOTION_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_LINEAR_ORTHOGONAL_DAMPING); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_upper_limit_angular", "_get_upper_limit_angular"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_lower_limit_angular", "_get_lower_limit_angular"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_LIMIT_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motion/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_MOTION_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/restitution", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_ortho/damping", PROPERTY_HINT_RANGE, "0,16.0,0.01"), "set_param", "get_param", PARAM_ANGULAR_ORTHOGONAL_DAMPING); BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_UPPER); BIND_ENUM_CONSTANT(PARAM_LINEAR_LIMIT_LOWER); @@ -541,12 +541,12 @@ void ConeTwistJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_twist_span", "twist_span"), &ConeTwistJoint::_set_twist_span); ClassDB::bind_method(D_METHOD("_get_twist_span"), &ConeTwistJoint::_get_twist_span); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "swing_span", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_swing_span", "_get_swing_span"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1"), "_set_twist_span", "_get_twist_span"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "swing_span", PROPERTY_HINT_RANGE, "-180,180,0.1"), "_set_swing_span", "_get_swing_span"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "twist_span", PROPERTY_HINT_RANGE, "-40000,40000,0.1"), "_set_twist_span", "_get_twist_span"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_RELAXATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_BIAS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "softness", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "relaxation", PROPERTY_HINT_RANGE, "0.01,16.0,0.01"), "set_param", "get_param", PARAM_RELAXATION); BIND_ENUM_CONSTANT(PARAM_SWING_SPAN); BIND_ENUM_CONSTANT(PARAM_TWIST_SPAN); @@ -711,92 +711,92 @@ void Generic6DOFJoint::_bind_methods() { ClassDB::bind_method(D_METHOD("get_precision"), &Generic6DOFJoint::get_precision); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/upper_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/lower_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/upper_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/lower_distance"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_LIMIT); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_x", "_get_angular_hi_limit_x"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_x", "_get_angular_lo_limit_x"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_FORCE_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_x/erp"), "set_param_x", "get_param_x", PARAM_ANGULAR_ERP); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_x", "_get_angular_hi_limit_x"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_x", "_get_angular_lo_limit_x"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_ANGULAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/erp"), "set_param_x", "get_param_x", PARAM_ANGULAR_ERP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/upper_distance"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/lower_distance"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_LIMIT); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_y", "_get_angular_hi_limit_y"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_y", "_get_angular_lo_limit_y"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_FORCE_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_y/erp"), "set_param_y", "get_param_y", PARAM_ANGULAR_ERP); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_y", "_get_angular_hi_limit_y"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_y", "_get_angular_lo_limit_y"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/erp"), "set_param_y", "get_param_y", PARAM_ANGULAR_ERP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/upper_distance"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/lower_distance"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_LIMIT); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_z", "_get_angular_hi_limit_z"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_z", "_get_angular_lo_limit_z"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_FORCE_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_limit_z/erp"), "set_param_z", "get_param_z", PARAM_ANGULAR_ERP); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_z", "_get_angular_hi_limit_z"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_z", "_get_angular_lo_limit_z"); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_ANGULAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/erp"), "set_param_z", "get_param_z", PARAM_ANGULAR_ERP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); ADD_PROPERTY(PropertyInfo(Variant::INT, "precision", PROPERTY_HINT_RANGE, "1,99999,1"), "set_precision", "get_precision"); diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index fbe3cd7a3e..be1426f13c 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -80,7 +80,7 @@ bool RayCast::is_colliding() const { } Object *RayCast::get_collider() const { - if (against == 0) + if (against.is_null()) return NULL; return ObjectDB::get_instance(against); @@ -186,7 +186,7 @@ void RayCast::_notification(int p_what) { _update_raycast_state(); if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) { if (debug_material.is_valid()) { - Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material); + Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material); line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6)); } } @@ -219,7 +219,7 @@ void RayCast::_update_raycast_state() { against_shape = rr.shape; } else { collided = false; - against = 0; + against = ObjectID(); against_shape = 0; } } @@ -333,11 +333,10 @@ void RayCast::_bind_methods() { void RayCast::_create_debug_shape() { if (!debug_material.is_valid()) { - debug_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); + debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); - Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material); - line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - line_material->set_line_width(3.0); + Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D> >(debug_material); + line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); line_material->set_albedo(Color(1.0, 0.8, 0.6)); } @@ -363,8 +362,7 @@ void RayCast::_update_debug_shape() { return; Ref<ArrayMesh> mesh = mi->get_mesh(); - if (mesh->get_surface_count() > 0) - mesh->surface_remove(0); + mesh->clear_surfaces(); Array a; a.resize(Mesh::ARRAY_MAX); @@ -395,7 +393,7 @@ void RayCast::_clear_debug_shape() { RayCast::RayCast() { enabled = false; - against = 0; + collided = false; against_shape = 0; collision_mask = 1; diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 2a5a84741f..3cf8e43ec2 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -186,9 +186,9 @@ AABB ReflectionProbe::get_aabb() const { aabb.size = origin_offset + extents; return aabb; } -PoolVector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } void ReflectionProbe::_validate_property(PropertyInfo &property) const { @@ -239,8 +239,8 @@ void ReflectionProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("get_update_mode"), &ReflectionProbe::get_update_mode); ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once,Always"), "set_update_mode", "get_update_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,16384,0.1,or_greater"), "set_max_distance", "get_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,16384,0.1,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset"), "set_origin_offset", "get_origin_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "box_projection"), "set_enable_box_projection", "is_box_projection_enabled"); @@ -250,8 +250,8 @@ void ReflectionProbe::_bind_methods() { ADD_GROUP("Interior", "interior_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior_enable"), "set_as_interior", "is_set_as_interior"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "interior_ambient_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_interior_ambient", "get_interior_ambient"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "interior_ambient_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_interior_ambient_energy", "get_interior_ambient_energy"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "interior_ambient_contrib", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_interior_ambient_probe_contribution", "get_interior_ambient_probe_contribution"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interior_ambient_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_interior_ambient_energy", "get_interior_ambient_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interior_ambient_contrib", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_interior_ambient_probe_contribution", "get_interior_ambient_probe_contribution"); BIND_ENUM_CONSTANT(UPDATE_ONCE); BIND_ENUM_CONSTANT(UPDATE_ALWAYS); diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 28ca680e9f..57c1b0a320 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -103,7 +103,7 @@ public: UpdateMode get_update_mode() const; virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; ReflectionProbe(); ~ReflectionProbe(); diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index 983af7a9ec..9ef43647ba 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -31,7 +31,7 @@ #include "remote_transform.h" void RemoteTransform::_update_cache() { - cache = 0; + cache = ObjectID(); if (has_node(remote_node)) { Node *node = get_node(remote_node); if (!node || this == node || node->is_a_parent_of(this) || this->is_a_parent_of(node)) { @@ -47,7 +47,7 @@ void RemoteTransform::_update_remote() { if (!is_inside_tree()) return; - if (!cache) + if (cache.is_null()) return; Spatial *n = Object::cast_to<Spatial>(ObjectDB::get_instance(cache)); @@ -114,7 +114,7 @@ void RemoteTransform::_notification(int p_what) { if (!is_inside_tree()) break; - if (cache) { + if (cache.is_valid()) { _update_remote(); } @@ -219,6 +219,5 @@ RemoteTransform::RemoteTransform() { update_remote_rotation = true; update_remote_scale = true; - cache = 0; set_notify_transform(true); } diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 17e67c47d1..b2252bcb04 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -30,8 +30,8 @@ #include "skeleton.h" +#include "core/engine.h" #include "core/message_queue.h" - #include "core/project_settings.h" #include "scene/3d/physics_body.h" #include "scene/resources/surface_tool.h" @@ -40,6 +40,7 @@ void SkinReference::_skin_changed() { if (skeleton_node) { skeleton_node->_make_dirty(); } + skeleton_version = 0; } void SkinReference::_bind_methods() { @@ -137,7 +138,7 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const { else if (what == "bound_children") { Array children; - for (const List<uint32_t>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) { + for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) { Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); @@ -301,7 +302,7 @@ void Skeleton::_notification(int p_what) { b.global_pose_override_amount = 0.0; } - for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) { + for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) { Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); @@ -321,10 +322,49 @@ void Skeleton::_notification(int p_what) { if (E->get()->bind_count != bind_count) { VS::get_singleton()->skeleton_allocate(skeleton, bind_count); E->get()->bind_count = bind_count; + E->get()->skin_bone_indices.resize(bind_count); + E->get()->skin_bone_indices_ptrs = E->get()->skin_bone_indices.ptrw(); + } + + if (E->get()->skeleton_version != version) { + + for (uint32_t i = 0; i < bind_count; i++) { + StringName bind_name = skin->get_bind_name(i); + + if (bind_name != StringName()) { + //bind name used, use this + bool found = false; + for (int j = 0; j < len; j++) { + if (bonesptr[j].name == bind_name) { + E->get()->skin_bone_indices_ptrs[i] = j; + found = true; + break; + } + } + + if (!found) { + ERR_PRINT("Skin bind #" + itos(i) + " contains named bind '" + String(bind_name) + "' but Skeleton has no bone by that name."); + E->get()->skin_bone_indices_ptrs[i] = 0; + } + } else if (skin->get_bind_bone(i) >= 0) { + int bind_index = skin->get_bind_bone(i); + if (bind_index >= len) { + ERR_PRINT("Skin bind #" + itos(i) + " contains bone index bind: " + itos(bind_index) + " , which is greater than the skeleton bone count: " + itos(len) + "."); + E->get()->skin_bone_indices_ptrs[i] = 0; + } else { + E->get()->skin_bone_indices_ptrs[i] = bind_index; + } + } else { + ERR_PRINT("Skin bind #" + itos(i) + " does not contain a name nor a bone index."); + E->get()->skin_bone_indices_ptrs[i] = 0; + } + } + + E->get()->skeleton_version = version; } for (uint32_t i = 0; i < bind_count; i++) { - uint32_t bone_index = skin->get_bind_bone(i); + uint32_t bone_index = E->get()->skin_bone_indices_ptrs[i]; ERR_CONTINUE(bone_index >= (uint32_t)len); vs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i)); } @@ -332,6 +372,27 @@ void Skeleton::_notification(int p_what) { dirty = false; } break; + +#ifndef _3D_DISABLED + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + // This is active only if the skeleton animates the physical bones + // and the state of the bone is not active. + if (animate_physical_bones) { + for (int i = 0; i < bones.size(); i += 1) { + if (bones[i].physical_bone) { + if (bones[i].physical_bone->is_simulating_physics() == false) { + bones[i].physical_bone->reset_to_rest_position(); + } + } + } + } + } break; + case NOTIFICATION_READY: { + if (Engine::get_singleton()->is_editor_hint()) { + set_physics_process_internal(true); + } + } break; +#endif } } @@ -366,6 +427,7 @@ void Skeleton::add_bone(const String &p_name) { b.name = p_name; bones.push_back(b); process_order_dirty = true; + version++; _make_dirty(); update_gizmo(); } @@ -483,9 +545,9 @@ void Skeleton::bind_child_node_to_bone(int p_bone, Node *p_node) { ERR_FAIL_NULL(p_node); ERR_FAIL_INDEX(p_bone, bones.size()); - uint32_t id = p_node->get_instance_id(); + ObjectID id = p_node->get_instance_id(); - for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { + for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { if (E->get() == id) return; // already here @@ -498,14 +560,14 @@ void Skeleton::unbind_child_node_from_bone(int p_bone, Node *p_node) { ERR_FAIL_NULL(p_node); ERR_FAIL_INDEX(p_bone, bones.size()); - uint32_t id = p_node->get_instance_id(); + ObjectID id = p_node->get_instance_id(); bones.write[p_bone].nodes_bound.erase(id); } void Skeleton::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const { ERR_FAIL_INDEX(p_bone, bones.size()); - for (const List<uint32_t>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { + for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) { Object *obj = ObjectDB::get_instance(E->get()); ERR_CONTINUE(!obj); @@ -517,7 +579,7 @@ void Skeleton::clear_bones() { bones.clear(); process_order_dirty = true; - + version++; _make_dirty(); } @@ -584,6 +646,27 @@ void Skeleton::localize_rests() { #ifndef _3D_DISABLED +void Skeleton::set_animate_physical_bones(bool p_animate) { + animate_physical_bones = p_animate; + + if (Engine::get_singleton()->is_editor_hint() == false) { + bool sim = false; + for (int i = 0; i < bones.size(); i += 1) { + if (bones[i].physical_bone) { + bones[i].physical_bone->reset_physics_simulation_state(); + if (bones[i].physical_bone->is_simulating_physics()) { + sim = true; + } + } + } + set_physics_process_internal(sim == false && p_animate); + } +} + +bool Skeleton::get_animate_physical_bones() const { + return animate_physical_bones; +} + void Skeleton::bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone) { ERR_FAIL_INDEX(p_bone, bones.size()); ERR_FAIL_COND(bones[p_bone].physical_bone); @@ -653,12 +736,14 @@ void _pb_stop_simulation(Node *p_node) { PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node); if (pb) { pb->set_simulate_physics(false); - pb->set_static_body(false); } } void Skeleton::physical_bones_stop_simulation() { _pb_stop_simulation(this); + if (Engine::get_singleton()->is_editor_hint() == false && animate_physical_bones) { + set_physics_process_internal(true); + } } void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector<int> &p_sim_bones) { @@ -669,24 +754,17 @@ void _pb_start_simulation(const Skeleton *p_skeleton, Node *p_node, const Vector PhysicalBone *pb = Object::cast_to<PhysicalBone>(p_node); if (pb) { - bool sim = false; for (int i = p_sim_bones.size() - 1; 0 <= i; --i) { if (p_sim_bones[i] == pb->get_bone_id() || p_skeleton->is_bone_parent_of(pb->get_bone_id(), p_sim_bones[i])) { - sim = true; + pb->set_simulate_physics(true); break; } } - - pb->set_simulate_physics(true); - if (sim) { - pb->set_static_body(false); - } else { - pb->set_static_body(true); - } } } void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) { + set_physics_process_internal(false); Vector<int> sim_bones; if (p_bones.size() <= 0) { @@ -695,7 +773,8 @@ void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) { sim_bones.resize(p_bones.size()); int c = 0; for (int i = sim_bones.size() - 1; 0 <= i; --i) { - if (Variant::STRING == p_bones.get(i).get_type()) { + Variant::Type type = p_bones.get(i).get_type(); + if (Variant::STRING == type || Variant::STRING_NAME == type) { int bone_id = find_bone(p_bones.get(i)); if (bone_id != -1) sim_bones.write[c++] = bone_id; @@ -791,8 +870,10 @@ Ref<SkinReference> Skeleton::register_skin(const Ref<Skin> &p_skin) { skin_bindings.insert(skin_ref.operator->()); - skin->connect("changed", skin_ref.operator->(), "_skin_changed"); - _make_dirty(); + skin->connect_compat("changed", skin_ref.operator->(), "_skin_changed"); + + _make_dirty(); //skin needs to be updated, so update skeleton + return skin_ref; } @@ -836,11 +917,15 @@ void Skeleton::_bind_methods() { #ifndef _3D_DISABLED + ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton::set_animate_physical_bones); + ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton::get_animate_physical_bones); + ClassDB::bind_method(D_METHOD("physical_bones_stop_simulation"), &Skeleton::physical_bones_stop_simulation); ClassDB::bind_method(D_METHOD("physical_bones_start_simulation", "bones"), &Skeleton::physical_bones_start_simulation_on, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("physical_bones_add_collision_exception", "exception"), &Skeleton::physical_bones_add_collision_exception); ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &Skeleton::physical_bones_remove_collision_exception); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones"); #endif // _3D_DISABLED BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON); @@ -848,7 +933,9 @@ void Skeleton::_bind_methods() { Skeleton::Skeleton() { + animate_physical_bones = true; dirty = false; + version = 1; process_order_dirty = true; } diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index 056f70e22b..76fd96f30a 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -51,6 +51,9 @@ class SkinReference : public Reference { RID skeleton; Ref<Skin> skin; uint32_t bind_count = 0; + uint64_t skeleton_version = 0; + Vector<uint32_t> skin_bone_indices; + uint32_t *skin_bone_indices_ptrs; void _skin_changed(); protected: @@ -99,7 +102,7 @@ private: PhysicalBone *cache_parent_physical_bone; #endif // _3D_DISABLED - List<uint32_t> nodes_bound; + List<ObjectID> nodes_bound; Bone() { parent = -1; @@ -115,6 +118,7 @@ private: } }; + bool animate_physical_bones; Vector<Bone> bones; Vector<int> process_order; bool process_order_dirty; @@ -122,6 +126,8 @@ private: void _make_dirty(); bool dirty; + uint64_t version; + // bind helpers Array _get_bound_child_nodes_to_bone(int p_bone) const { @@ -199,6 +205,9 @@ public: #ifndef _3D_DISABLED // Physical bone API + void set_animate_physical_bones(bool p_animate); + bool get_animate_physical_bones() const; + void bind_physical_bone_to_bone(int p_bone, PhysicalBone *p_physical_bone); void unbind_physical_bone_from_bone(int p_bone); diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index ef13985bf4..3859a278ef 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -47,7 +47,10 @@ void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) { mesh = p_mesh; surface = p_surface; - +#ifndef _MSC_VER +#warning Softbody is not working, needs to be redone considering that these functions no longer exist +#endif +#if 0 const uint32_t surface_format = VS::get_singleton()->mesh_surface_get_format(mesh, surface); const int surface_vertex_len = VS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface); const int surface_index_len = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface); @@ -57,6 +60,7 @@ void SoftBodyVisualServerHandler::prepare(RID p_mesh, int p_surface) { stride = VS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets); offset_vertices = surface_offsets[VS::ARRAY_VERTEX]; offset_normal = surface_offsets[VS::ARRAY_NORMAL]; +#endif } void SoftBodyVisualServerHandler::clear() { @@ -69,11 +73,11 @@ void SoftBodyVisualServerHandler::clear() { } void SoftBodyVisualServerHandler::open() { - write_buffer = buffer.write(); + write_buffer = buffer.ptrw(); } void SoftBodyVisualServerHandler::close() { - write_buffer.release(); + //write_buffer.release(); } void SoftBodyVisualServerHandler::commit_changes() { @@ -145,7 +149,7 @@ bool SoftBody::_get(const StringName &p_name, Variant &r_ret) const { if ("pinned_points" == which) { Array arr_ret; const int pinned_points_indices_size = pinned_points.size(); - PoolVector<PinnedPoint>::Read r = pinned_points.read(); + const PinnedPoint *r = pinned_points.ptr(); arr_ret.resize(pinned_points_indices_size); for (int i = 0; i < pinned_points_indices_size; ++i) { @@ -170,7 +174,7 @@ void SoftBody::_get_property_list(List<PropertyInfo> *p_list) const { const int pinned_points_indices_size = pinned_points.size(); - p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "pinned_points")); + p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "pinned_points")); for (int i = 0; i < pinned_points_indices_size; ++i) { p_list->push_back(PropertyInfo(Variant::INT, "attachments/" + itos(i) + "/point_index")); @@ -184,7 +188,7 @@ bool SoftBody::_set_property_pinned_points_indices(const Array &p_indices) { const int p_indices_size = p_indices.size(); { // Remove the pined points on physics server that will be removed by resize - PoolVector<PinnedPoint>::Read r = pinned_points.read(); + const PinnedPoint *r = pinned_points.ptr(); if (p_indices_size < pinned_points.size()) { for (int i = pinned_points.size() - 1; i >= p_indices_size; --i) { pin_point(r[i].point_index, false); @@ -194,7 +198,7 @@ bool SoftBody::_set_property_pinned_points_indices(const Array &p_indices) { pinned_points.resize(p_indices_size); - PoolVector<PinnedPoint>::Write w = pinned_points.write(); + PinnedPoint *w = pinned_points.ptrw(); int point_index; for (int i = 0; i < p_indices_size; ++i) { point_index = p_indices.get(i); @@ -214,11 +218,11 @@ bool SoftBody::_set_property_pinned_points_attachment(int p_item, const String & } if ("spatial_attachment_path" == p_what) { - PoolVector<PinnedPoint>::Write w = pinned_points.write(); + PinnedPoint *w = pinned_points.ptrw(); pin_point(w[p_item].point_index, true, p_value); _make_cache_dirty(); } else if ("offset" == p_what) { - PoolVector<PinnedPoint>::Write w = pinned_points.write(); + PinnedPoint *w = pinned_points.ptrw(); w[p_item].offset = p_value; } else { return false; @@ -231,7 +235,7 @@ bool SoftBody::_get_property_pinned_points(int p_item, const String &p_what, Var if (pinned_points.size() <= p_item) { return false; } - PoolVector<PinnedPoint>::Read r = pinned_points.read(); + const PinnedPoint *r = pinned_points.ptr(); if ("point_index" == p_what) { r_ret = r[p_item].point_index; @@ -247,7 +251,7 @@ bool SoftBody::_get_property_pinned_points(int p_item, const String &p_what, Var } void SoftBody::_changed_callback(Object *p_changed, const char *p_prop) { - update_physics_server(); + prepare_physics_server(); _reset_points_offsets(); #ifdef TOOLS_ENABLED if (p_changed == this) { @@ -267,7 +271,7 @@ void SoftBody::_notification(int p_what) { RID space = get_world()->get_space(); PhysicsServer::get_singleton()->soft_body_set_space(physics_rid, space); - update_physics_server(); + prepare_physics_server(); } break; case NOTIFICATION_READY: { if (!parent_collision_ignore.is_empty()) @@ -290,21 +294,6 @@ void SoftBody::_notification(int p_what) { set_notify_transform(true); } break; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - - if (!simulation_started) - return; - - _update_cache_pin_points_datas(); - // Submit bone attachment - const int pinned_points_indices_size = pinned_points.size(); - PoolVector<PinnedPoint>::Read r = pinned_points.read(); - for (int i = 0; i < pinned_points_indices_size; ++i) { - if (r[i].spatial_attachment) { - PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset)); - } - } - } break; case NOTIFICATION_VISIBILITY_CHANGED: { _update_pickable(); @@ -330,8 +319,6 @@ void SoftBody::_notification(int p_what) { void SoftBody::_bind_methods() { - ClassDB::bind_method(D_METHOD("_draw_soft_mesh"), &SoftBody::_draw_soft_mesh); - ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody::get_collision_mask); @@ -387,14 +374,14 @@ void SoftBody::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "parent_collision_ignore", PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE, "Parent collision object"), "set_parent_collision_ignore", "get_parent_collision_ignore"); ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable"); } @@ -421,6 +408,21 @@ String SoftBody::get_configuration_warning() const { return warning; } +void SoftBody::_update_physics_server() { + if (!simulation_started) + return; + + _update_cache_pin_points_datas(); + // Submit bone attachment + const int pinned_points_indices_size = pinned_points.size(); + const PinnedPoint *r = pinned_points.ptr(); + for (int i = 0; i < pinned_points_indices_size; ++i) { + if (r[i].spatial_attachment) { + PhysicsServer::get_singleton()->soft_body_move_point(physics_rid, r[i].point_index, r[i].spatial_attachment->get_global_transform().xform(r[i].offset)); + } + } +} + void SoftBody::_draw_soft_mesh() { if (get_mesh().is_null()) return; @@ -435,6 +437,8 @@ void SoftBody::_draw_soft_mesh() { call_deferred("set_transform", Transform()); } + _update_physics_server(); + visual_server_handler.open(); PhysicsServer::get_singleton()->soft_body_update_visual_server(physics_rid, &visual_server_handler); visual_server_handler.close(); @@ -442,7 +446,7 @@ void SoftBody::_draw_soft_mesh() { visual_server_handler.commit_changes(); } -void SoftBody::update_physics_server() { +void SoftBody::prepare_physics_server() { if (Engine::get_singleton()->is_editor_hint()) { @@ -458,12 +462,12 @@ void SoftBody::update_physics_server() { become_mesh_owner(); PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh()); - VS::get_singleton()->connect("frame_pre_draw", this, "_draw_soft_mesh"); + VS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftBody::_draw_soft_mesh)); } else { PhysicsServer::get_singleton()->soft_body_set_mesh(physics_rid, NULL); - if (VS::get_singleton()->is_connected("frame_pre_draw", this, "_draw_soft_mesh")) { - VS::get_singleton()->disconnect("frame_pre_draw", this, "_draw_soft_mesh"); + if (VS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftBody::_draw_soft_mesh))) { + VS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftBody::_draw_soft_mesh)); } } } @@ -483,14 +487,15 @@ void SoftBody::become_mesh_owner() { // Get current mesh array and create new mesh array with necessary flag for softbody Array surface_arrays = mesh->surface_get_arrays(0); Array surface_blend_arrays = mesh->surface_get_blend_shape_arrays(0); + Dictionary surface_lods = mesh->surface_get_lods(0); uint32_t surface_format = mesh->surface_get_format(0); - surface_format &= ~(Mesh::ARRAY_COMPRESS_VERTEX | Mesh::ARRAY_COMPRESS_NORMAL); + surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL); surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; Ref<ArrayMesh> soft_mesh; soft_mesh.instance(); - soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_format); + soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format); soft_mesh->surface_set_material(0, mesh->surface_get_material(0)); set_mesh(soft_mesh); @@ -552,15 +557,14 @@ const NodePath &SoftBody::get_parent_collision_ignore() const { return parent_collision_ignore; } -void SoftBody::set_pinned_points_indices(PoolVector<SoftBody::PinnedPoint> p_pinned_points_indices) { +void SoftBody::set_pinned_points_indices(Vector<SoftBody::PinnedPoint> p_pinned_points_indices) { pinned_points = p_pinned_points_indices; - PoolVector<PinnedPoint>::Read w = pinned_points.read(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { pin_point(p_pinned_points_indices[i].point_index, true); } } -PoolVector<SoftBody::PinnedPoint> SoftBody::get_pinned_points_indices() { +Vector<SoftBody::PinnedPoint> SoftBody::get_pinned_points_indices() { return pinned_points; } @@ -706,8 +710,6 @@ SoftBody::SoftBody() : ray_pickable(true) { PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); - //set_notify_transform(true); - set_physics_process_internal(true); } SoftBody::~SoftBody() { @@ -716,7 +718,7 @@ SoftBody::~SoftBody() { void SoftBody::reset_softbody_pin() { PhysicsServer::get_singleton()->soft_body_remove_all_pinned_points(physics_rid); - PoolVector<PinnedPoint>::Read pps = pinned_points.read(); + const PinnedPoint *pps = pinned_points.ptr(); for (int i = pinned_points.size() - 1; 0 < i; --i) { PhysicsServer::get_singleton()->soft_body_pin_point(physics_rid, pps[i].point_index, true); } @@ -732,7 +734,7 @@ void SoftBody::_update_cache_pin_points_datas() { pinned_points_cache_dirty = false; - PoolVector<PinnedPoint>::Write w = pinned_points.write(); + PinnedPoint *w = pinned_points.ptrw(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { if (!w[i].spatial_attachment_path.is_empty()) { @@ -781,8 +783,8 @@ void SoftBody::_reset_points_offsets() { if (!Engine::get_singleton()->is_editor_hint()) return; - PoolVector<PinnedPoint>::Read r = pinned_points.read(); - PoolVector<PinnedPoint>::Write w = pinned_points.write(); + const PinnedPoint *r = pinned_points.ptr(); + PinnedPoint *w = pinned_points.ptrw(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { if (!r[i].spatial_attachment) @@ -808,13 +810,13 @@ int SoftBody::_get_pinned_point(int p_point_index, SoftBody::PinnedPoint *&r_poi r_point = NULL; return -1; } else { - r_point = const_cast<SoftBody::PinnedPoint *>(&pinned_points.read()[id]); + r_point = const_cast<SoftBody::PinnedPoint *>(&pinned_points.ptr()[id]); return id; } } int SoftBody::_has_pinned_point(int p_point_index) const { - PoolVector<PinnedPoint>::Read r = pinned_points.read(); + const PinnedPoint *r = pinned_points.ptr(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { if (p_point_index == r[i].point_index) { return i; diff --git a/scene/3d/soft_body.h b/scene/3d/soft_body.h index 629c2e42a5..d6c35a5989 100644 --- a/scene/3d/soft_body.h +++ b/scene/3d/soft_body.h @@ -41,12 +41,12 @@ class SoftBodyVisualServerHandler { RID mesh; int surface; - PoolVector<uint8_t> buffer; + Vector<uint8_t> buffer; uint32_t stride; uint32_t offset_vertices; uint32_t offset_normal; - PoolVector<uint8_t>::Write write_buffer; + uint8_t *write_buffer; private: SoftBodyVisualServerHandler(); @@ -87,7 +87,7 @@ private: uint32_t collision_mask; uint32_t collision_layer; NodePath parent_collision_ignore; - PoolVector<PinnedPoint> pinned_points; + Vector<PinnedPoint> pinned_points; bool simulation_started; bool pinned_points_cache_dirty; @@ -116,10 +116,11 @@ protected: virtual String get_configuration_warning() const; protected: + void _update_physics_server(); void _draw_soft_mesh(); public: - void update_physics_server(); + void prepare_physics_server(); void become_mesh_owner(); void set_collision_mask(uint32_t p_mask); @@ -137,8 +138,8 @@ public: void set_parent_collision_ignore(const NodePath &p_parent_collision_ignore); const NodePath &get_parent_collision_ignore() const; - void set_pinned_points_indices(PoolVector<PinnedPoint> p_pinned_points_indices); - PoolVector<PinnedPoint> get_pinned_points_indices(); + void set_pinned_points_indices(Vector<PinnedPoint> p_pinned_points_indices); + Vector<PinnedPoint> get_pinned_points_indices(); void set_simulation_precision(int p_simulation_precision); int get_simulation_precision(); diff --git a/scene/3d/spring_arm.cpp b/scene/3d/spring_arm.cpp index bce0535d64..ce277dae5b 100644 --- a/scene/3d/spring_arm.cpp +++ b/scene/3d/spring_arm.cpp @@ -81,8 +81,8 @@ void SpringArm::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), "set_shape", "get_shape"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "spring_length"), "set_length", "get_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spring_length"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); } float SpringArm::get_length() const { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index a4c81b864d..fd22076091 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "sprite_3d.h" + #include "core/core_string_names.h" #include "scene/scene_string_names.h" @@ -177,8 +178,6 @@ void SpriteBase3D::_im_update() { _draw(); pending_update = false; - - //texture->draw_rect_region(ci,dst_rect,src_rect,modulate); } void SpriteBase3D::_queue_update() { @@ -197,18 +196,18 @@ AABB SpriteBase3D::get_aabb() const { return aabb; } -PoolVector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const { +Vector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); + return Vector<Face3>(); } Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) return triangle_mesh; - PoolVector<Vector3> faces; + Vector<Vector3> faces; faces.resize(6); - PoolVector<Vector3>::Write facesw = faces.write(); + Vector3 *facesw = faces.ptrw(); Rect2 final_rect = get_item_rect(); @@ -254,8 +253,6 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { facesw[j] = vtx; } - facesw.release(); - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); @@ -286,14 +283,14 @@ SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const { return alpha_cut; } -void SpriteBase3D::set_billboard_mode(SpatialMaterial::BillboardMode p_mode) { +void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) { ERR_FAIL_INDEX(p_mode, 3); billboard_mode = p_mode; _queue_update(); } -SpatialMaterial::BillboardMode SpriteBase3D::get_billboard_mode() const { +StandardMaterial3D::BillboardMode SpriteBase3D::get_billboard_mode() const { return billboard_mode; } @@ -336,16 +333,13 @@ void SpriteBase3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_rect"), &SpriteBase3D::get_item_rect); ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &SpriteBase3D::generate_triangle_mesh); - ClassDB::bind_method(D_METHOD("_queue_update"), &SpriteBase3D::_queue_update); - ClassDB::bind_method(D_METHOD("_im_update"), &SpriteBase3D::_im_update); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_v"), "set_flip_v", "is_flipped_v"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_opacity", "get_opacity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_opacity", "get_opacity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X-Axis,Y-Axis,Z-Axis"), "set_axis", "get_axis"); ADD_GROUP("Flags", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard"), "set_billboard_mode", "get_billboard_mode"); @@ -377,7 +371,7 @@ SpriteBase3D::SpriteBase3D() { flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED; alpha_cut = ALPHA_CUT_DISABLED; - billboard_mode = SpatialMaterial::BILLBOARD_DISABLED; + billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED; axis = Vector3::AXIS_Z; pixel_size = 0.01; modulate = Color(1, 1, 1, 1); @@ -480,10 +474,10 @@ void Sprite3D::_draw() { tangent = Plane(1, 0, 0, 1); } - RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y); + RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y); VS::get_singleton()->immediate_set_material(immediate, mat); - VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid()); + VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLES, texture->get_rid()); int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); @@ -504,15 +498,18 @@ void Sprite3D::_draw() { AABB aabb; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 6; i++) { + + static const int index[6] = { 0, 1, 2, 0, 2, 3 }; + VS::get_singleton()->immediate_normal(immediate, normal); VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); Vector3 vtx; - vtx[x_axis] = vertices[i][0]; - vtx[y_axis] = vertices[i][1]; + vtx[x_axis] = vertices[index[i]][0]; + vtx[y_axis] = vertices[index[i]][1]; VS::get_singleton()->immediate_vertex(immediate, vtx); if (i == 0) { aabb.position = vtx; @@ -525,22 +522,25 @@ void Sprite3D::_draw() { VS::get_singleton()->immediate_end(immediate); } -void Sprite3D::set_texture(const Ref<Texture> &p_texture) { +void Sprite3D::_texture_changed() { + _queue_update(); +} + +void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) { if (p_texture == texture) return; if (texture.is_valid()) { - texture->disconnect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_queue_update); + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed)); } texture = p_texture; if (texture.is_valid()) { - texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites - texture->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->_queue_update); + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed)); } _queue_update(); } -Ref<Texture> Sprite3D::get_texture() const { +Ref<Texture2D> Sprite3D::get_texture() const { return texture; } @@ -691,7 +691,7 @@ void Sprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes); ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_GROUP("Animation", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); @@ -731,7 +731,7 @@ void AnimatedSprite3D::_draw() { return; } - Ref<Texture> texture = frames->get_frame(animation, frame); + Ref<Texture2D> texture = frames->get_frame(animation, frame); if (!texture.is_valid()) return; //no texuture no life Vector2 tsize = texture->get_size(); @@ -808,11 +808,11 @@ void AnimatedSprite3D::_draw() { tangent = Plane(1, 0, 0, -1); } - RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == SpatialMaterial::BILLBOARD_ENABLED, get_billboard_mode() == SpatialMaterial::BILLBOARD_FIXED_Y); + RID mat = StandardMaterial3D::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS, get_billboard_mode() == StandardMaterial3D::BILLBOARD_ENABLED, get_billboard_mode() == StandardMaterial3D::BILLBOARD_FIXED_Y); VS::get_singleton()->immediate_set_material(immediate, mat); - VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid()); + VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLES, texture->get_rid()); int x_axis = ((axis + 1) % 3); int y_axis = ((axis + 2) % 3); @@ -833,15 +833,21 @@ void AnimatedSprite3D::_draw() { AABB aabb; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 6; i++) { + + static const int indices[6] = { + 0, 1, 2, + 0, 2, 3 + }; + VS::get_singleton()->immediate_normal(immediate, normal); VS::get_singleton()->immediate_tangent(immediate, tangent); VS::get_singleton()->immediate_color(immediate, color); VS::get_singleton()->immediate_uv(immediate, uvs[i]); Vector3 vtx; - vtx[x_axis] = vertices[i][0]; - vtx[y_axis] = vertices[i][1]; + vtx[x_axis] = vertices[indices[i]][0]; + vtx[y_axis] = vertices[indices[i]][1]; VS::get_singleton()->immediate_vertex(immediate, vtx); if (i == 0) { aabb.position = vtx; @@ -946,10 +952,10 @@ void AnimatedSprite3D::_notification(int p_what) { void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { if (frames.is_valid()) - frames->disconnect("changed", this, "_res_changed"); + frames->disconnect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed)); frames = p_frames; if (frames.is_valid()) - frames->connect("changed", this, "_res_changed"); + frames->connect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed)); if (!frames.is_valid()) { frame = 0; @@ -1003,7 +1009,7 @@ Rect2 AnimatedSprite3D::get_item_rect() const { return Rect2(0, 0, 1, 1); } - Ref<Texture> t; + Ref<Texture2D> t; if (animation) t = frames->get_frame(animation, frame); if (t.is_null()) @@ -1119,12 +1125,10 @@ void AnimatedSprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_frame", "frame"), &AnimatedSprite3D::set_frame); ClassDB::bind_method(D_METHOD("get_frame"), &AnimatedSprite3D::get_frame); - ClassDB::bind_method(D_METHOD("_res_changed"), &AnimatedSprite3D::_res_changed); - ADD_SIGNAL(MethodInfo("frame_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE, "SpriteFrames"), "set_sprite_frames", "get_sprite_frames"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing"), "_set_playing", "_is_playing"); } diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index ddbade147c..082884c83b 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -80,7 +80,7 @@ private: bool flags[FLAG_MAX]; AlphaCutMode alpha_cut; - SpatialMaterial::BillboardMode billboard_mode; + StandardMaterial3D::BillboardMode billboard_mode; bool pending_update; void _im_update(); @@ -131,13 +131,13 @@ public: void set_alpha_cut_mode(AlphaCutMode p_mode); AlphaCutMode get_alpha_cut_mode() const; - void set_billboard_mode(SpatialMaterial::BillboardMode p_mode); - SpatialMaterial::BillboardMode get_billboard_mode() const; + void set_billboard_mode(StandardMaterial3D::BillboardMode p_mode); + StandardMaterial3D::BillboardMode get_billboard_mode() const; virtual Rect2 get_item_rect() const = 0; virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; Ref<TriangleMesh> generate_triangle_mesh() const; SpriteBase3D(); @@ -147,7 +147,7 @@ public: class Sprite3D : public SpriteBase3D { GDCLASS(Sprite3D, SpriteBase3D); - Ref<Texture> texture; + Ref<Texture2D> texture; bool region; Rect2 region_rect; @@ -157,6 +157,8 @@ class Sprite3D : public SpriteBase3D { int vframes; int hframes; + void _texture_changed(); + protected: virtual void _draw(); static void _bind_methods(); @@ -164,8 +166,8 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - void set_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture() const; void set_region(bool p_region); bool is_region() const; diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 92b17d5056..c249d844d1 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -282,24 +282,24 @@ void VehicleWheel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_steering"), &VehicleWheel::get_steering); ADD_GROUP("Per-Wheel Motion", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering"); ADD_GROUP("VehicleBody Motion", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_traction"), "set_use_as_traction", "is_used_as_traction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_steering"), "set_use_as_steering", "is_used_as_steering"); ADD_GROUP("Wheel", "wheel_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_roll_influence"), "set_roll_influence", "get_roll_influence"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_radius"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_rest_length"), "set_suspension_rest_length", "get_suspension_rest_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_friction_slip"), "set_friction_slip", "get_friction_slip"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wheel_roll_influence"), "set_roll_influence", "get_roll_influence"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wheel_radius"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wheel_rest_length"), "set_suspension_rest_length", "get_suspension_rest_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wheel_friction_slip"), "set_friction_slip", "get_friction_slip"); ADD_GROUP("Suspension", "suspension_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "suspension_travel"), "set_suspension_travel", "get_suspension_travel"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "suspension_stiffness"), "set_suspension_stiffness", "get_suspension_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "suspension_max_force"), "set_suspension_max_force", "get_suspension_max_force"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "suspension_travel"), "set_suspension_travel", "get_suspension_travel"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "suspension_stiffness"), "set_suspension_stiffness", "get_suspension_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "suspension_max_force"), "set_suspension_max_force", "get_suspension_max_force"); ADD_GROUP("Damping", "damping_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_compression"), "set_damping_compression", "get_damping_compression"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_compression"), "set_damping_compression", "get_damping_compression"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_relaxation"), "set_damping_relaxation", "get_damping_relaxation"); } void VehicleWheel::set_engine_force(float p_engine_force) { @@ -364,9 +364,8 @@ VehicleWheel::VehicleWheel() { steers = false; engine_traction = false; - m_steering = real_t(0.); - //m_engineForce = real_t(0.); + m_engineForce = real_t(0.); m_rotation = real_t(0.); m_deltaRotation = real_t(0.); m_brake = real_t(0.); @@ -975,9 +974,9 @@ void VehicleBody::_bind_methods() { ClassDB::bind_method(D_METHOD("get_steering"), &VehicleBody::get_steering); ADD_GROUP("Motion", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "engine_force", PROPERTY_HINT_RANGE, "0.00,1024.0,0.01,or_greater"), "set_engine_force", "get_engine_force"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "brake", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_brake", "get_brake"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "steering", PROPERTY_HINT_RANGE, "-180,180.0,0.01"), "set_steering", "get_steering"); } VehicleBody::VehicleBody() { diff --git a/scene/3d/visibility_notifier.cpp b/scene/3d/visibility_notifier.cpp index 510442dc1c..986607f18d 100644 --- a/scene/3d/visibility_notifier.cpp +++ b/scene/3d/visibility_notifier.cpp @@ -170,7 +170,7 @@ void VisibilityEnabler::_find_nodes(Node *p_node) { if (add) { - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed", varray(p_node), CONNECT_ONESHOT); + p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler::_node_removed), varray(p_node), CONNECT_ONESHOT); nodes[p_node] = meta; _change_node_state(p_node, false); } @@ -208,7 +208,7 @@ void VisibilityEnabler::_notification(int p_what) { if (!visible) _change_node_state(E->key(), true); - E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, this, "_node_removed"); + E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler::_node_removed)); } nodes.clear(); @@ -247,7 +247,6 @@ void VisibilityEnabler::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler::set_enabler); ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler::is_enabler_enabled); - ClassDB::bind_method(D_METHOD("_node_removed"), &VisibilityEnabler::_node_removed); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "pause_animations"), "set_enabler", "is_enabler_enabled", ENABLER_PAUSE_ANIMATIONS); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "freeze_bodies"), "set_enabler", "is_enabler_enabled", ENABLER_FREEZE_BODIES); diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 4574dfac5f..105ce9ca74 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -294,10 +294,11 @@ void GeometryInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance::get_aabb); ADD_GROUP("Geometry", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial"), "set_material_override", "get_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_in_baked_light"), "set_flag", "get_flag", FLAG_USE_BAKED_LIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_dynamic_gi"), "set_flag", "get_flag", FLAG_USE_DYNAMIC_GI); ADD_GROUP("LOD", "lod_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_min_distance", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_min_distance", "get_lod_min_distance"); @@ -313,6 +314,7 @@ void GeometryInstance::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY); BIND_ENUM_CONSTANT(FLAG_USE_BAKED_LIGHT); + BIND_ENUM_CONSTANT(FLAG_USE_DYNAMIC_GI); BIND_ENUM_CONSTANT(FLAG_DRAW_NEXT_FRAME_IF_VISIBLE); BIND_ENUM_CONSTANT(FLAG_MAX); } diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index f115748952..fee6787c87 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -63,7 +63,7 @@ public: RID get_instance() const; virtual AABB get_aabb() const = 0; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const = 0; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const = 0; virtual AABB get_transformed_aabb() const; // helper @@ -87,6 +87,7 @@ class GeometryInstance : public VisualInstance { public: enum Flags { FLAG_USE_BAKED_LIGHT = VS::INSTANCE_FLAG_USE_BAKED_LIGHT, + FLAG_USE_DYNAMIC_GI = VS::INSTANCE_FLAG_USE_DYNAMIC_GI, FLAG_DRAW_NEXT_FRAME_IF_VISIBLE = VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, FLAG_MAX = VS::INSTANCE_FLAG_MAX, }; diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp deleted file mode 100644 index c1ec59d49f..0000000000 --- a/scene/3d/voxel_light_baker.cpp +++ /dev/null @@ -1,2486 +0,0 @@ -/*************************************************************************/ -/* voxel_light_baker.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "voxel_light_baker.h" - -#include "core/os/os.h" -#include "core/os/threaded_array_processor.h" - -#include <stdlib.h> - -#define FINDMINMAX(x0, x1, x2, min, max) \ - min = max = x0; \ - if (x1 < min) min = x1; \ - if (x1 > max) max = x1; \ - if (x2 < min) min = x2; \ - if (x2 > max) max = x2; - -static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) { - int q; - Vector3 vmin, vmax; - for (q = 0; q <= 2; q++) { - if (normal[q] > 0.0f) { - vmin[q] = -maxbox[q]; - vmax[q] = maxbox[q]; - } else { - vmin[q] = maxbox[q]; - vmax[q] = -maxbox[q]; - } - } - if (normal.dot(vmin) + d > 0.0f) return false; - if (normal.dot(vmax) + d >= 0.0f) return true; - - return false; -} - -/*======================== X-tests ========================*/ -#define AXISTEST_X01(a, b, fa, fb) \ - p0 = a * v0.y - b * v0.z; \ - p2 = a * v2.y - b * v2.z; \ - if (p0 < p2) { \ - min = p0; \ - max = p2; \ - } else { \ - min = p2; \ - max = p0; \ - } \ - rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ - if (min > rad || max < -rad) return false; - -#define AXISTEST_X2(a, b, fa, fb) \ - p0 = a * v0.y - b * v0.z; \ - p1 = a * v1.y - b * v1.z; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ - if (min > rad || max < -rad) return false; - -/*======================== Y-tests ========================*/ -#define AXISTEST_Y02(a, b, fa, fb) \ - p0 = -a * v0.x + b * v0.z; \ - p2 = -a * v2.x + b * v2.z; \ - if (p0 < p2) { \ - min = p0; \ - max = p2; \ - } else { \ - min = p2; \ - max = p0; \ - } \ - rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ - if (min > rad || max < -rad) return false; - -#define AXISTEST_Y1(a, b, fa, fb) \ - p0 = -a * v0.x + b * v0.z; \ - p1 = -a * v1.x + b * v1.z; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ - if (min > rad || max < -rad) return false; - -/*======================== Z-tests ========================*/ - -#define AXISTEST_Z12(a, b, fa, fb) \ - p1 = a * v1.x - b * v1.y; \ - p2 = a * v2.x - b * v2.y; \ - if (p2 < p1) { \ - min = p2; \ - max = p1; \ - } else { \ - min = p1; \ - max = p2; \ - } \ - rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ - if (min > rad || max < -rad) return false; - -#define AXISTEST_Z0(a, b, fa, fb) \ - p0 = a * v0.x - b * v0.y; \ - p1 = a * v1.x - b * v1.y; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ - if (min > rad || max < -rad) return false; - -static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) { - - /* use separating axis theorem to test overlap between triangle and box */ - /* need to test for overlap in these directions: */ - /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ - /* we do not even need to test these) */ - /* 2) normal of the triangle */ - /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ - /* this gives 3x3=9 more tests */ - Vector3 v0, v1, v2; - float min, max, d, p0, p1, p2, rad, fex, fey, fez; - Vector3 normal, e0, e1, e2; - - /* This is the fastest branch on Sun */ - /* move everything so that the boxcenter is in (0,0,0) */ - - v0 = triverts[0] - boxcenter; - v1 = triverts[1] - boxcenter; - v2 = triverts[2] - boxcenter; - - /* compute triangle edges */ - e0 = v1 - v0; /* tri edge 0 */ - e1 = v2 - v1; /* tri edge 1 */ - e2 = v0 - v2; /* tri edge 2 */ - - /* Bullet 3: */ - /* test the 9 tests first (this was faster) */ - fex = Math::abs(e0.x); - fey = Math::abs(e0.y); - fez = Math::abs(e0.z); - AXISTEST_X01(e0.z, e0.y, fez, fey); - AXISTEST_Y02(e0.z, e0.x, fez, fex); - AXISTEST_Z12(e0.y, e0.x, fey, fex); - - fex = Math::abs(e1.x); - fey = Math::abs(e1.y); - fez = Math::abs(e1.z); - AXISTEST_X01(e1.z, e1.y, fez, fey); - AXISTEST_Y02(e1.z, e1.x, fez, fex); - AXISTEST_Z0(e1.y, e1.x, fey, fex); - - fex = Math::abs(e2.x); - fey = Math::abs(e2.y); - fez = Math::abs(e2.z); - AXISTEST_X2(e2.z, e2.y, fez, fey); - AXISTEST_Y1(e2.z, e2.x, fez, fex); - AXISTEST_Z12(e2.y, e2.x, fey, fex); - - /* Bullet 1: */ - /* first test overlap in the {x,y,z}-directions */ - /* find min, max of the triangle each direction, and test for overlap in */ - /* that direction -- this is equivalent to testing a minimal AABB around */ - /* the triangle against the AABB */ - - /* test in X-direction */ - FINDMINMAX(v0.x, v1.x, v2.x, min, max); - if (min > boxhalfsize.x || max < -boxhalfsize.x) return false; - - /* test in Y-direction */ - FINDMINMAX(v0.y, v1.y, v2.y, min, max); - if (min > boxhalfsize.y || max < -boxhalfsize.y) return false; - - /* test in Z-direction */ - FINDMINMAX(v0.z, v1.z, v2.z, min, max); - if (min > boxhalfsize.z || max < -boxhalfsize.z) return false; - - /* Bullet 2: */ - /* test if the box intersects the plane of the triangle */ - /* compute plane equation of triangle: normal*x+d=0 */ - normal = e0.cross(e1); - d = -normal.dot(v0); /* plane eq: normal.x+d=0 */ - return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */ -} - -static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) { - - if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) { - r_uv = p_uv[0]; - r_normal = p_normal[0]; - return; - } - if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) { - r_uv = p_uv[1]; - r_normal = p_normal[1]; - return; - } - if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) { - r_uv = p_uv[2]; - r_normal = p_normal[2]; - return; - } - - Vector3 v0 = p_vtx[1] - p_vtx[0]; - Vector3 v1 = p_vtx[2] - p_vtx[0]; - Vector3 v2 = p_pos - p_vtx[0]; - - float d00 = v0.dot(v0); - float d01 = v0.dot(v1); - float d11 = v1.dot(v1); - float d20 = v2.dot(v0); - float d21 = v2.dot(v1); - float denom = (d00 * d11 - d01 * d01); - if (denom == 0) { - r_uv = p_uv[0]; - r_normal = p_normal[0]; - return; - } - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; - - r_uv = p_uv[0] * u + p_uv[1] * v + p_uv[2] * w; - r_normal = (p_normal[0] * u + p_normal[1] * v + p_normal[2] * w).normalized(); -} - -void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) { - - if (p_level == cell_subdiv - 1) { - //plot the face by guessing its albedo and emission value - - //find best axis to map to, for scanning values - int closest_axis = 0; - float closest_dot = 0; - - Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]); - Vector3 normal = plane.normal; - - for (int i = 0; i < 3; i++) { - - Vector3 axis; - axis[i] = 1.0; - float dot = ABS(normal.dot(axis)); - if (i == 0 || dot > closest_dot) { - closest_axis = i; - closest_dot = dot; - } - } - - Vector3 axis; - axis[closest_axis] = 1.0; - Vector3 t1; - t1[(closest_axis + 1) % 3] = 1.0; - Vector3 t2; - t2[(closest_axis + 2) % 3] = 1.0; - - t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width); - t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width); - - Color albedo_accum; - Color emission_accum; - Vector3 normal_accum; - - float alpha = 0.0; - - //map to a grid average in the best axis for this face - for (int i = 0; i < color_scan_cell_width; i++) { - - Vector3 ofs_i = float(i) * t1; - - for (int j = 0; j < color_scan_cell_width; j++) { - - Vector3 ofs_j = float(j) * t2; - - Vector3 from = p_aabb.position + ofs_i + ofs_j; - Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; - Vector3 half = (to - from) * 0.5; - - //is in this cell? - if (!fast_tri_box_overlap(from + half, half, p_vtx)) { - continue; //face does not span this cell - } - - //go from -size to +size*2 to avoid skipping collisions - Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis]; - Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2; - - if (normal.dot(ray_from - ray_to) < 0) { - SWAP(ray_from, ray_to); - } - - Vector3 intersection; - - if (!plane.intersects_segment(ray_from, ray_to, &intersection)) { - if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) { - intersection = plane.project(ray_from); - } else { - - intersection = plane.project(ray_to); - } - } - - intersection = Face3(p_vtx[0], p_vtx[1], p_vtx[2]).get_closest_point_to(intersection); - - Vector2 uv; - Vector3 lnormal; - get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal); - if (lnormal == Vector3()) //just in case normal as nor provided - lnormal = normal; - - int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); - int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); - - int ofs = uv_y * bake_texture_size + uv_x; - albedo_accum.r += p_material.albedo[ofs].r; - albedo_accum.g += p_material.albedo[ofs].g; - albedo_accum.b += p_material.albedo[ofs].b; - albedo_accum.a += p_material.albedo[ofs].a; - - emission_accum.r += p_material.emission[ofs].r; - emission_accum.g += p_material.emission[ofs].g; - emission_accum.b += p_material.emission[ofs].b; - - normal_accum += lnormal; - - alpha += 1.0; - } - } - - if (alpha == 0) { - //could not in any way get texture information.. so use closest point to center - - Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]); - Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5); - - Vector3 lnormal; - Vector2 uv; - get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal); - if (lnormal == Vector3()) //just in case normal as nor provided - lnormal = normal; - - int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); - int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); - - int ofs = uv_y * bake_texture_size + uv_x; - - alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width); - - albedo_accum.r = p_material.albedo[ofs].r * alpha; - albedo_accum.g = p_material.albedo[ofs].g * alpha; - albedo_accum.b = p_material.albedo[ofs].b * alpha; - albedo_accum.a = p_material.albedo[ofs].a * alpha; - - emission_accum.r = p_material.emission[ofs].r * alpha; - emission_accum.g = p_material.emission[ofs].g * alpha; - emission_accum.b = p_material.emission[ofs].b * alpha; - - normal_accum = lnormal * alpha; - - } else { - - float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width); - alpha *= accdiv; - - albedo_accum.r *= accdiv; - albedo_accum.g *= accdiv; - albedo_accum.b *= accdiv; - albedo_accum.a *= accdiv; - - emission_accum.r *= accdiv; - emission_accum.g *= accdiv; - emission_accum.b *= accdiv; - - normal_accum *= accdiv; - } - - //put this temporarily here, corrected in a later step - bake_cells.write[p_idx].albedo[0] += albedo_accum.r; - bake_cells.write[p_idx].albedo[1] += albedo_accum.g; - bake_cells.write[p_idx].albedo[2] += albedo_accum.b; - bake_cells.write[p_idx].emission[0] += emission_accum.r; - bake_cells.write[p_idx].emission[1] += emission_accum.g; - bake_cells.write[p_idx].emission[2] += emission_accum.b; - bake_cells.write[p_idx].normal[0] += normal_accum.x; - bake_cells.write[p_idx].normal[1] += normal_accum.y; - bake_cells.write[p_idx].normal[2] += normal_accum.z; - bake_cells.write[p_idx].alpha += alpha; - - } else { - //go down - - int half = (1 << (cell_subdiv - 1)) >> (p_level + 1); - for (int i = 0; i < 8; i++) { - - AABB aabb = p_aabb; - aabb.size *= 0.5; - - int nx = p_x; - int ny = p_y; - int nz = p_z; - - if (i & 1) { - aabb.position.x += aabb.size.x; - nx += half; - } - if (i & 2) { - aabb.position.y += aabb.size.y; - ny += half; - } - if (i & 4) { - aabb.position.z += aabb.size.z; - nz += half; - } - //make sure to not plot beyond limits - if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2]) - continue; - - { - AABB test_aabb = aabb; - //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time - Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test - - if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) { - //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) { - //does not fit in child, go on - continue; - } - } - - if (bake_cells[p_idx].children[i] == CHILD_EMPTY) { - //sub cell must be created - - uint32_t child_idx = bake_cells.size(); - bake_cells.write[p_idx].children[i] = child_idx; - bake_cells.resize(bake_cells.size() + 1); - bake_cells.write[child_idx].level = p_level + 1; - } - - _plot_face(bake_cells[p_idx].children[i], p_level + 1, nx, ny, nz, p_vtx, p_normal, p_uv, p_material, aabb); - } - } -} - -Vector<Color> VoxelLightBaker::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) { - - Vector<Color> ret; - - if (p_image.is_null() || p_image->empty()) { - - ret.resize(bake_texture_size * bake_texture_size); - for (int i = 0; i < bake_texture_size * bake_texture_size; i++) { - ret.write[i] = p_color_add; - } - - return ret; - } - p_image = p_image->duplicate(); - - if (p_image->is_compressed()) { - p_image->decompress(); - } - p_image->convert(Image::FORMAT_RGBA8); - p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC); - - PoolVector<uint8_t>::Read r = p_image->get_data().read(); - ret.resize(bake_texture_size * bake_texture_size); - - for (int i = 0; i < bake_texture_size * bake_texture_size; i++) { - Color c; - c.r = (r[i * 4 + 0] / 255.0) * p_color_mul.r + p_color_add.r; - c.g = (r[i * 4 + 1] / 255.0) * p_color_mul.g + p_color_add.g; - c.b = (r[i * 4 + 2] / 255.0) * p_color_mul.b + p_color_add.b; - - c.a = r[i * 4 + 3] / 255.0; - - ret.write[i] = c; - } - - return ret; -} - -VoxelLightBaker::MaterialCache VoxelLightBaker::_get_material_cache(Ref<Material> p_material) { - - //this way of obtaining materials is inaccurate and also does not support some compressed formats very well - Ref<SpatialMaterial> mat = p_material; - - Ref<Material> material = mat; //hack for now - - if (material_cache.has(material)) { - return material_cache[material]; - } - - MaterialCache mc; - - if (mat.is_valid()) { - - Ref<Texture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO); - - Ref<Image> img_albedo; - if (albedo_tex.is_valid()) { - - img_albedo = albedo_tex->get_data(); - mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative - } else { - mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive - } - - Ref<Texture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION); - - Color emission_col = mat->get_emission(); - float emission_energy = mat->get_emission_energy(); - - Ref<Image> img_emission; - - if (emission_tex.is_valid()) { - - img_emission = emission_tex->get_data(); - } - - if (mat->get_emission_operator() == SpatialMaterial::EMISSION_OP_ADD) { - mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy); - } else { - mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0)); - } - - } else { - Ref<Image> empty; - - mc.albedo = _get_bake_texture(empty, Color(0, 0, 0), Color(1, 1, 1)); - mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0)); - } - - material_cache[p_material] = mc; - return mc; -} - -void VoxelLightBaker::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) { - - for (int i = 0; i < p_mesh->get_surface_count(); i++) { - - if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) - continue; //only triangles - - Ref<Material> src_material; - - if (p_override_material.is_valid()) { - src_material = p_override_material; - } else if (i < p_materials.size() && p_materials[i].is_valid()) { - src_material = p_materials[i]; - } else { - src_material = p_mesh->surface_get_material(i); - } - MaterialCache material = _get_material_cache(src_material); - - Array a = p_mesh->surface_get_arrays(i); - - PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; - PoolVector<Vector3>::Read vr = vertices.read(); - PoolVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; - PoolVector<Vector2>::Read uvr; - PoolVector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; - PoolVector<Vector3>::Read nr; - PoolVector<int> index = a[Mesh::ARRAY_INDEX]; - - bool read_uv = false; - bool read_normals = false; - - if (uv.size()) { - - uvr = uv.read(); - read_uv = true; - } - - if (normals.size()) { - read_normals = true; - nr = normals.read(); - } - - if (index.size()) { - - int facecount = index.size() / 3; - PoolVector<int>::Read ir = index.read(); - - for (int j = 0; j < facecount; j++) { - - Vector3 vtxs[3]; - Vector2 uvs[3]; - Vector3 normal[3]; - - for (int k = 0; k < 3; k++) { - vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); - } - - if (read_uv) { - for (int k = 0; k < 3; k++) { - uvs[k] = uvr[ir[j * 3 + k]]; - } - } - - if (read_normals) { - for (int k = 0; k < 3; k++) { - normal[k] = nr[ir[j * 3 + k]]; - } - } - - //test against original bounds - if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) - continue; - //plot - _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds); - } - - } else { - - int facecount = vertices.size() / 3; - - for (int j = 0; j < facecount; j++) { - - Vector3 vtxs[3]; - Vector2 uvs[3]; - Vector3 normal[3]; - - for (int k = 0; k < 3; k++) { - vtxs[k] = p_xform.xform(vr[j * 3 + k]); - } - - if (read_uv) { - for (int k = 0; k < 3; k++) { - uvs[k] = uvr[j * 3 + k]; - } - } - - if (read_normals) { - for (int k = 0; k < 3; k++) { - normal[k] = nr[j * 3 + k]; - } - } - - //test against original bounds - if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) - continue; - //plot face - _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds); - } - } - } - - max_original_cells = bake_cells.size(); -} - -void VoxelLightBaker::_init_light_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, uint32_t p_parent) { - - bake_light.write[p_idx].x = p_x; - bake_light.write[p_idx].y = p_y; - bake_light.write[p_idx].z = p_z; - - if (p_level == cell_subdiv - 1) { - - bake_light.write[p_idx].next_leaf = first_leaf; - first_leaf = p_idx; - } else { - - //go down - int half = (1 << (cell_subdiv - 1)) >> (p_level + 1); - for (int i = 0; i < 8; i++) { - - uint32_t child = bake_cells[p_idx].children[i]; - - if (child == CHILD_EMPTY) - continue; - - int nx = p_x; - int ny = p_y; - int nz = p_z; - - if (i & 1) - nx += half; - if (i & 2) - ny += half; - if (i & 4) - nz += half; - - _init_light_plot(child, p_level + 1, nx, ny, nz, p_idx); - } - } -} - -void VoxelLightBaker::begin_bake_light(BakeQuality p_quality, BakeMode p_bake_mode, float p_propagation, float p_energy) { - _check_init_light(); - propagation = p_propagation; - bake_quality = p_quality; - bake_mode = p_bake_mode; - energy = p_energy; -} - -void VoxelLightBaker::_check_init_light() { - if (bake_light.size() == 0) { - - direct_lights_baked = false; - leaf_voxel_count = 0; - _fixup_plot(0, 0); //pre fixup, so normal, albedo, emission, etc. work for lighting. - bake_light.resize(bake_cells.size()); - print_line("bake light size: " + itos(bake_light.size())); - //zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light)); - first_leaf = -1; - _init_light_plot(0, 0, 0, 0, 0, CHILD_EMPTY); - } -} - -static float _get_normal_advance(const Vector3 &p_normal) { - - Vector3 normal = p_normal; - Vector3 unorm = normal.abs(); - - if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { - // x code - unorm = normal.x > 0.0 ? Vector3(1.0, 0.0, 0.0) : Vector3(-1.0, 0.0, 0.0); - } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { - // y code - unorm = normal.y > 0.0 ? Vector3(0.0, 1.0, 0.0) : Vector3(0.0, -1.0, 0.0); - } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { - // z code - unorm = normal.z > 0.0 ? Vector3(0.0, 0.0, 1.0) : Vector3(0.0, 0.0, -1.0); - } else { - // oh-no we messed up code - // has to be - unorm = Vector3(1.0, 0.0, 0.0); - } - - return 1.0 / normal.dot(unorm); -} - -static const Vector3 aniso_normal[6] = { - Vector3(-1, 0, 0), - Vector3(1, 0, 0), - Vector3(0, -1, 0), - Vector3(0, 1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, 1) -}; - -uint32_t VoxelLightBaker::_find_cell_at_pos(const Cell *cells, int x, int y, int z) { - - uint32_t cell = 0; - - int ofs_x = 0; - int ofs_y = 0; - int ofs_z = 0; - int size = 1 << (cell_subdiv - 1); - int half = size / 2; - - if (x < 0 || x >= size) - return -1; - if (y < 0 || y >= size) - return -1; - if (z < 0 || z >= size) - return -1; - - for (int i = 0; i < cell_subdiv - 1; i++) { - - const Cell *bc = &cells[cell]; - - int child = 0; - if (x >= ofs_x + half) { - child |= 1; - ofs_x += half; - } - if (y >= ofs_y + half) { - child |= 2; - ofs_y += half; - } - if (z >= ofs_z + half) { - child |= 4; - ofs_z += half; - } - - cell = bc->children[child]; - if (cell == CHILD_EMPTY) - return CHILD_EMPTY; - - half >>= 1; - } - - return cell; -} -void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_energy, bool p_direct) { - - _check_init_light(); - - float max_len = Vector3(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]).length() * 1.1; - - if (p_direct) - direct_lights_baked = true; - - Vector3 light_axis = p_direction; - Plane clip[3]; - int clip_planes = 0; - - Light *light_data = bake_light.ptrw(); - const Cell *cells = bake_cells.ptr(); - - for (int i = 0; i < 3; i++) { - - if (Math::is_zero_approx(light_axis[i])) - continue; - clip[clip_planes].normal[i] = 1.0; - - if (light_axis[i] < 0) { - - clip[clip_planes].d = axis_cell_size[i] + 1; - } else { - clip[clip_planes].d -= 1.0; - } - - clip_planes++; - } - - float distance_adv = _get_normal_advance(light_axis); - - int success_count = 0; - - Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy; - - int idx = first_leaf; - while (idx >= 0) { - - Light *light = &light_data[idx]; - - Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5); - to += -light_axis.sign() * 0.47; //make it more likely to receive a ray - - Vector3 from = to - max_len * light_axis; - - for (int j = 0; j < clip_planes; j++) { - - clip[j].intersects_segment(from, to, &from); - } - - float distance = (to - from).length(); - distance += distance_adv - Math::fmod(distance, distance_adv); //make it reach the center of the box always - from = to - light_axis * distance; - - uint32_t result = 0xFFFFFFFF; - - while (distance > -distance_adv) { //use this to avoid precision errors - - result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z))); - if (result != 0xFFFFFFFF) { - break; - } - - from += light_axis * distance_adv; - distance -= distance_adv; - } - - if (result == (uint32_t)idx) { - //cell hit itself! hooray! - - Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); - if (normal == Vector3()) { - for (int i = 0; i < 6; i++) { - light->accum[i][0] += light_energy.x * cells[idx].albedo[0]; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1]; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2]; - } - - } else { - - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-normal)); - light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s; - } - } - - if (p_direct) { - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct - light->direct_accum[i][0] += light_energy.x * s; - light->direct_accum[i][1] += light_energy.y * s; - light->direct_accum[i][2] += light_energy.z * s; - } - } - success_count++; - } - - idx = light_data[idx].next_leaf; - } -} - -void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, bool p_direct) { - - _check_init_light(); - - if (p_direct) - direct_lights_baked = true; - - Plane clip[3]; - int clip_planes = 0; - - // uint64_t us = OS::get_singleton()->get_ticks_usec(); - - Vector3 light_pos = to_cell_space.xform(p_pos) + Vector3(0.5, 0.5, 0.5); - //Vector3 spot_axis = -light_cache.transform.basis.get_axis(2).normalized(); - - float local_radius = to_cell_space.basis.xform(Vector3(0, 0, 1)).length() * p_radius; - - Light *light_data = bake_light.ptrw(); - const Cell *cells = bake_cells.ptr(); - Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy; - - int idx = first_leaf; - while (idx >= 0) { - - Light *light = &light_data[idx]; - - Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5); - to += (light_pos - to).sign() * 0.47; //make it more likely to receive a ray - - Vector3 light_axis = (to - light_pos).normalized(); - float distance_adv = _get_normal_advance(light_axis); - - Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); - - if (normal != Vector3() && normal.dot(-light_axis) < 0.001) { - idx = light_data[idx].next_leaf; - continue; - } - - float att = 1.0; - { - float d = light_pos.distance_to(to); - if (d + distance_adv > local_radius) { - idx = light_data[idx].next_leaf; - continue; // too far away - } - - float dt = CLAMP((d + distance_adv) / local_radius, 0, 1); - att *= powf(1.0 - dt, p_attenutation); - } - - clip_planes = 0; - - for (int c = 0; c < 3; c++) { - - if (Math::is_zero_approx(light_axis[c])) - continue; - clip[clip_planes].normal[c] = 1.0; - - if (light_axis[c] < 0) { - - clip[clip_planes].d = (1 << (cell_subdiv - 1)) + 1; - } else { - clip[clip_planes].d -= 1.0; - } - - clip_planes++; - } - - Vector3 from = light_pos; - - for (int j = 0; j < clip_planes; j++) { - - clip[j].intersects_segment(from, to, &from); - } - - float distance = (to - from).length(); - - distance -= Math::fmod(distance, distance_adv); //make it reach the center of the box always, but this tame make it closer - from = to - light_axis * distance; - to += (light_pos - to).sign() * 0.47; //make it more likely to receive a ray - - uint32_t result = 0xFFFFFFFF; - - while (distance > -distance_adv) { //use this to avoid precision errors - - result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z))); - if (result != 0xFFFFFFFF) { - break; - } - - from += light_axis * distance_adv; - distance -= distance_adv; - } - - if (result == (uint32_t)idx) { - //cell hit itself! hooray! - - if (normal == Vector3()) { - for (int i = 0; i < 6; i++) { - light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * att; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * att; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * att; - } - - } else { - - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-normal)); - light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s * att; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s * att; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s * att; - } - } - - if (p_direct) { - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct - light->direct_accum[i][0] += light_energy.x * s * att; - light->direct_accum[i][1] += light_energy.y * s * att; - light->direct_accum[i][2] += light_energy.z * s * att; - } - } - } - - idx = light_data[idx].next_leaf; - } -} - -void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axis, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, float p_spot_angle, float p_spot_attenuation, bool p_direct) { - - _check_init_light(); - - if (p_direct) - direct_lights_baked = true; - - Plane clip[3]; - int clip_planes = 0; - - // uint64_t us = OS::get_singleton()->get_ticks_usec(); - - Vector3 light_pos = to_cell_space.xform(p_pos) + Vector3(0.5, 0.5, 0.5); - Vector3 spot_axis = to_cell_space.basis.xform(p_axis).normalized(); - - float local_radius = to_cell_space.basis.xform(Vector3(0, 0, 1)).length() * p_radius; - - Light *light_data = bake_light.ptrw(); - const Cell *cells = bake_cells.ptr(); - Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy; - - int idx = first_leaf; - while (idx >= 0) { - - Light *light = &light_data[idx]; - - Vector3 to(light->x + 0.5, light->y + 0.5, light->z + 0.5); - - Vector3 light_axis = (to - light_pos).normalized(); - float distance_adv = _get_normal_advance(light_axis); - - Vector3 normal(cells[idx].normal[0], cells[idx].normal[1], cells[idx].normal[2]); - - if (normal != Vector3() && normal.dot(-light_axis) < 0.001) { - idx = light_data[idx].next_leaf; - continue; - } - - float angle = Math::rad2deg(Math::acos(light_axis.dot(-spot_axis))); - if (angle > p_spot_angle) { - idx = light_data[idx].next_leaf; - continue; // too far away - } - - float att = Math::pow(1.0f - angle / p_spot_angle, p_spot_attenuation); - - { - float d = light_pos.distance_to(to); - if (d + distance_adv > local_radius) { - idx = light_data[idx].next_leaf; - continue; // too far away - } - - float dt = CLAMP((d + distance_adv) / local_radius, 0, 1); - att *= powf(1.0 - dt, p_attenutation); - } - - clip_planes = 0; - - for (int c = 0; c < 3; c++) { - - if (Math::is_zero_approx(light_axis[c])) - continue; - clip[clip_planes].normal[c] = 1.0; - - if (light_axis[c] < 0) { - - clip[clip_planes].d = (1 << (cell_subdiv - 1)) + 1; - } else { - clip[clip_planes].d -= 1.0; - } - - clip_planes++; - } - - Vector3 from = light_pos; - - for (int j = 0; j < clip_planes; j++) { - - clip[j].intersects_segment(from, to, &from); - } - - float distance = (to - from).length(); - - distance -= Math::fmod(distance, distance_adv); //make it reach the center of the box always, but this tame make it closer - from = to - light_axis * distance; - - uint32_t result = 0xFFFFFFFF; - - while (distance > -distance_adv) { //use this to avoid precision errors - - result = _find_cell_at_pos(cells, int(floor(from.x)), int(floor(from.y)), int(floor(from.z))); - if (result != 0xFFFFFFFF) { - break; - } - - from += light_axis * distance_adv; - distance -= distance_adv; - } - - if (result == (uint32_t)idx) { - //cell hit itself! hooray! - - if (normal == Vector3()) { - for (int i = 0; i < 6; i++) { - light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * att; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * att; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * att; - } - - } else { - - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-normal)); - light->accum[i][0] += light_energy.x * cells[idx].albedo[0] * s * att; - light->accum[i][1] += light_energy.y * cells[idx].albedo[1] * s * att; - light->accum[i][2] += light_energy.z * cells[idx].albedo[2] * s * att; - } - } - - if (p_direct) { - for (int i = 0; i < 6; i++) { - float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct - light->direct_accum[i][0] += light_energy.x * s * att; - light->direct_accum[i][1] += light_energy.y * s * att; - light->direct_accum[i][2] += light_energy.z * s * att; - } - } - } - - idx = light_data[idx].next_leaf; - } -} - -void VoxelLightBaker::_fixup_plot(int p_idx, int p_level) { - - if (p_level == cell_subdiv - 1) { - - leaf_voxel_count++; - float alpha = bake_cells[p_idx].alpha; - - bake_cells.write[p_idx].albedo[0] /= alpha; - bake_cells.write[p_idx].albedo[1] /= alpha; - bake_cells.write[p_idx].albedo[2] /= alpha; - - //transfer emission to light - bake_cells.write[p_idx].emission[0] /= alpha; - bake_cells.write[p_idx].emission[1] /= alpha; - bake_cells.write[p_idx].emission[2] /= alpha; - - bake_cells.write[p_idx].normal[0] /= alpha; - bake_cells.write[p_idx].normal[1] /= alpha; - bake_cells.write[p_idx].normal[2] /= alpha; - - Vector3 n(bake_cells[p_idx].normal[0], bake_cells[p_idx].normal[1], bake_cells[p_idx].normal[2]); - if (n.length() < 0.01) { - //too much fight over normal, zero it - bake_cells.write[p_idx].normal[0] = 0; - bake_cells.write[p_idx].normal[1] = 0; - bake_cells.write[p_idx].normal[2] = 0; - } else { - n.normalize(); - bake_cells.write[p_idx].normal[0] = n.x; - bake_cells.write[p_idx].normal[1] = n.y; - bake_cells.write[p_idx].normal[2] = n.z; - } - - bake_cells.write[p_idx].alpha = 1.0; - - /*if (bake_light.size()) { - for(int i=0;i<6;i++) { - - } - }*/ - - } else { - - //go down - - bake_cells.write[p_idx].emission[0] = 0; - bake_cells.write[p_idx].emission[1] = 0; - bake_cells.write[p_idx].emission[2] = 0; - bake_cells.write[p_idx].normal[0] = 0; - bake_cells.write[p_idx].normal[1] = 0; - bake_cells.write[p_idx].normal[2] = 0; - bake_cells.write[p_idx].albedo[0] = 0; - bake_cells.write[p_idx].albedo[1] = 0; - bake_cells.write[p_idx].albedo[2] = 0; - if (bake_light.size()) { - for (int j = 0; j < 6; j++) { - bake_light.write[p_idx].accum[j][0] = 0; - bake_light.write[p_idx].accum[j][1] = 0; - bake_light.write[p_idx].accum[j][2] = 0; - } - } - - float alpha_average = 0; - int children_found = 0; - - for (int i = 0; i < 8; i++) { - - uint32_t child = bake_cells[p_idx].children[i]; - - if (child == CHILD_EMPTY) - continue; - - _fixup_plot(child, p_level + 1); - alpha_average += bake_cells[child].alpha; - - if (bake_light.size() > 0) { - for (int j = 0; j < 6; j++) { - bake_light.write[p_idx].accum[j][0] += bake_light[child].accum[j][0]; - bake_light.write[p_idx].accum[j][1] += bake_light[child].accum[j][1]; - bake_light.write[p_idx].accum[j][2] += bake_light[child].accum[j][2]; - } - bake_cells.write[p_idx].emission[0] += bake_cells[child].emission[0]; - bake_cells.write[p_idx].emission[1] += bake_cells[child].emission[1]; - bake_cells.write[p_idx].emission[2] += bake_cells[child].emission[2]; - } - - children_found++; - } - - bake_cells.write[p_idx].alpha = alpha_average / 8.0; - if (bake_light.size() && children_found) { - float divisor = Math::lerp(8, children_found, propagation); - for (int j = 0; j < 6; j++) { - bake_light.write[p_idx].accum[j][0] /= divisor; - bake_light.write[p_idx].accum[j][1] /= divisor; - bake_light.write[p_idx].accum[j][2] /= divisor; - } - bake_cells.write[p_idx].emission[0] /= divisor; - bake_cells.write[p_idx].emission[1] /= divisor; - bake_cells.write[p_idx].emission[2] /= divisor; - } - } -} - -//make sure any cell (save for the root) has an empty cell previous to it, so it can be interpolated into - -void VoxelLightBaker::_plot_triangle(Vector2 *vertices, Vector3 *positions, Vector3 *normals, LightMap *pixels, int width, int height) { - - int x[3]; - int y[3]; - - for (int j = 0; j < 3; j++) { - - x[j] = vertices[j].x * width; - y[j] = vertices[j].y * height; - //x[j] = CLAMP(x[j], 0, bt.width - 1); - //y[j] = CLAMP(y[j], 0, bt.height - 1); - } - - // sort the points vertically - if (y[1] > y[2]) { - SWAP(x[1], x[2]); - SWAP(y[1], y[2]); - SWAP(positions[1], positions[2]); - SWAP(normals[1], normals[2]); - } - if (y[0] > y[1]) { - SWAP(x[0], x[1]); - SWAP(y[0], y[1]); - SWAP(positions[0], positions[1]); - SWAP(normals[0], normals[1]); - } - if (y[1] > y[2]) { - SWAP(x[1], x[2]); - SWAP(y[1], y[2]); - SWAP(positions[1], positions[2]); - SWAP(normals[1], normals[2]); - } - - double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1); - double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1); - double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1); - double xf = x[0]; - double xt = x[0] + dx_upper; // if y[0] == y[1], special case - for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) { - if (yi >= 0) { - for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) { - //pixels[int(x + y * width)] = color; - - Vector2 v0 = Vector2(x[1] - x[0], y[1] - y[0]); - Vector2 v1 = Vector2(x[2] - x[0], y[2] - y[0]); - //vertices[2] - vertices[0]; - Vector2 v2 = Vector2(xi - x[0], yi - y[0]); - float d00 = v0.dot(v0); - float d01 = v0.dot(v1); - float d11 = v1.dot(v1); - float d20 = v2.dot(v0); - float d21 = v2.dot(v1); - float denom = (d00 * d11 - d01 * d01); - Vector3 pos; - Vector3 normal; - if (denom == 0) { - pos = positions[0]; - normal = normals[0]; - } else { - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; - pos = positions[0] * u + positions[1] * v + positions[2] * w; - normal = normals[0] * u + normals[1] * v + normals[2] * w; - } - - int ofs = yi * width + xi; - pixels[ofs].normal = normal; - pixels[ofs].pos = pos; - } - - for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) { - //pixels[int(x + y * width)] = color; - Vector2 v0 = Vector2(x[1] - x[0], y[1] - y[0]); - Vector2 v1 = Vector2(x[2] - x[0], y[2] - y[0]); - //vertices[2] - vertices[0]; - Vector2 v2 = Vector2(xi - x[0], yi - y[0]); - float d00 = v0.dot(v0); - float d01 = v0.dot(v1); - float d11 = v1.dot(v1); - float d20 = v2.dot(v0); - float d21 = v2.dot(v1); - float denom = (d00 * d11 - d01 * d01); - Vector3 pos; - Vector3 normal; - if (denom == 0) { - pos = positions[0]; - normal = normals[0]; - } else { - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; - pos = positions[0] * u + positions[1] * v + positions[2] * w; - normal = normals[0] * u + normals[1] * v + normals[2] * w; - } - - int ofs = yi * width + xi; - pixels[ofs].normal = normal; - pixels[ofs].pos = pos; - } - } - xf += dx_far; - if (yi < y[1]) - xt += dx_upper; - else - xt += dx_low; - } -} - -void VoxelLightBaker::_sample_baked_octree_filtered_and_anisotropic(const Vector3 &p_posf, const Vector3 &p_direction, float p_level, Vector3 &r_color, float &r_alpha) { - - int size = 1 << (cell_subdiv - 1); - - int clamp_v = size - 1; - //first of all, clamp - Vector3 pos; - pos.x = CLAMP(p_posf.x, 0, clamp_v); - pos.y = CLAMP(p_posf.y, 0, clamp_v); - pos.z = CLAMP(p_posf.z, 0, clamp_v); - - float level = (cell_subdiv - 1) - p_level; - - int target_level; - float level_filter; - if (level <= 0.0) { - level_filter = 0; - target_level = 0; - } else { - target_level = Math::ceil(level); - level_filter = target_level - level; - } - - const Cell *cells = bake_cells.ptr(); - const Light *light = bake_light.ptr(); - - Vector3 color[2][8]; - float alpha[2][8]; - zeromem(alpha, sizeof(float) * 2 * 8); - - //find cell at given level first - - for (int c = 0; c < 2; c++) { - - int current_level = MAX(0, target_level - c); - int level_cell_size = (1 << (cell_subdiv - 1)) >> current_level; - - for (int n = 0; n < 8; n++) { - - int x = int(pos.x); - int y = int(pos.y); - int z = int(pos.z); - - if (n & 1) - x += level_cell_size; - if (n & 2) - y += level_cell_size; - if (n & 4) - z += level_cell_size; - - int ofs_x = 0; - int ofs_y = 0; - int ofs_z = 0; - - x = CLAMP(x, 0, clamp_v); - y = CLAMP(y, 0, clamp_v); - z = CLAMP(z, 0, clamp_v); - - int half = size / 2; - uint32_t cell = 0; - for (int i = 0; i < current_level; i++) { - - const Cell *bc = &cells[cell]; - - int child = 0; - if (x >= ofs_x + half) { - child |= 1; - ofs_x += half; - } - if (y >= ofs_y + half) { - child |= 2; - ofs_y += half; - } - if (z >= ofs_z + half) { - child |= 4; - ofs_z += half; - } - - cell = bc->children[child]; - if (cell == CHILD_EMPTY) - break; - - half >>= 1; - } - - if (cell == CHILD_EMPTY) { - alpha[c][n] = 0; - } else { - alpha[c][n] = cells[cell].alpha; - - for (int i = 0; i < 6; i++) { - //anisotropic read light - float amount = p_direction.dot(aniso_normal[i]); - if (amount < 0) - amount = 0; - color[c][n].x += light[cell].accum[i][0] * amount; - color[c][n].y += light[cell].accum[i][1] * amount; - color[c][n].z += light[cell].accum[i][2] * amount; - } - - color[c][n].x += cells[cell].emission[0]; - color[c][n].y += cells[cell].emission[1]; - color[c][n].z += cells[cell].emission[2]; - } - } - } - - float target_level_size = size >> target_level; - Vector3 pos_fract[2]; - - pos_fract[0].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[0].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[0].z = Math::fmod(pos.z, target_level_size) / target_level_size; - - target_level_size = size >> MAX(0, target_level - 1); - - pos_fract[1].x = Math::fmod(pos.x, target_level_size) / target_level_size; - pos_fract[1].y = Math::fmod(pos.y, target_level_size) / target_level_size; - pos_fract[1].z = Math::fmod(pos.z, target_level_size) / target_level_size; - - float alpha_interp[2]; - Vector3 color_interp[2]; - - for (int i = 0; i < 2; i++) { - - Vector3 color_x00 = color[i][0].linear_interpolate(color[i][1], pos_fract[i].x); - Vector3 color_xy0 = color[i][2].linear_interpolate(color[i][3], pos_fract[i].x); - Vector3 blend_z0 = color_x00.linear_interpolate(color_xy0, pos_fract[i].y); - - Vector3 color_x0z = color[i][4].linear_interpolate(color[i][5], pos_fract[i].x); - Vector3 color_xyz = color[i][6].linear_interpolate(color[i][7], pos_fract[i].x); - Vector3 blend_z1 = color_x0z.linear_interpolate(color_xyz, pos_fract[i].y); - - color_interp[i] = blend_z0.linear_interpolate(blend_z1, pos_fract[i].z); - - float alpha_x00 = Math::lerp(alpha[i][0], alpha[i][1], pos_fract[i].x); - float alpha_xy0 = Math::lerp(alpha[i][2], alpha[i][3], pos_fract[i].x); - float alpha_z0 = Math::lerp(alpha_x00, alpha_xy0, pos_fract[i].y); - - float alpha_x0z = Math::lerp(alpha[i][4], alpha[i][5], pos_fract[i].x); - float alpha_xyz = Math::lerp(alpha[i][6], alpha[i][7], pos_fract[i].x); - float alpha_z1 = Math::lerp(alpha_x0z, alpha_xyz, pos_fract[i].y); - - alpha_interp[i] = Math::lerp(alpha_z0, alpha_z1, pos_fract[i].z); - } - - r_color = color_interp[0].linear_interpolate(color_interp[1], level_filter); - r_alpha = Math::lerp(alpha_interp[0], alpha_interp[1], level_filter); -} - -Vector3 VoxelLightBaker::_voxel_cone_trace(const Vector3 &p_pos, const Vector3 &p_normal, float p_aperture) { - - float bias = 2.5; - float max_distance = (Vector3(1, 1, 1) * (1 << (cell_subdiv - 1))).length(); - - float dist = bias; - float alpha = 0.0; - Vector3 color; - - Vector3 scolor; - float salpha; - - while (dist < max_distance && alpha < 0.95) { - float diameter = MAX(1.0, 2.0 * p_aperture * dist); - _sample_baked_octree_filtered_and_anisotropic(p_pos + dist * p_normal, p_normal, log2(diameter), scolor, salpha); - float a = (1.0 - alpha); - color += scolor * a; - alpha += a * salpha; - dist += diameter * 0.5; - } - - /*if (blend_ambient) { - color.rgb = mix(ambient,color.rgb,min(1.0,alpha/0.95)); - }*/ - - return color; -} - -Vector3 VoxelLightBaker::_compute_pixel_light_at_pos(const Vector3 &p_pos, const Vector3 &p_normal) { - - //find arbitrary tangent and bitangent, then build a matrix - Vector3 v0 = Math::abs(p_normal.z) < 0.999 ? Vector3(0, 0, 1) : Vector3(0, 1, 0); - Vector3 tangent = v0.cross(p_normal).normalized(); - Vector3 bitangent = tangent.cross(p_normal).normalized(); - Basis normal_xform = Basis(tangent, bitangent, p_normal).transposed(); - - const Vector3 *cone_dirs = NULL; - const float *cone_weights = NULL; - int cone_dir_count = 0; - float cone_aperture = 0; - - switch (bake_quality) { - case BAKE_QUALITY_LOW: { - //default quality - static const Vector3 dirs[4] = { - Vector3(Math_SQRT12, 0, Math_SQRT12), - Vector3(0, Math_SQRT12, Math_SQRT12), - Vector3(-Math_SQRT12, 0, Math_SQRT12), - Vector3(0, -Math_SQRT12, Math_SQRT12) - }; - - static const float weights[4] = { 0.25, 0.25, 0.25, 0.25 }; - - cone_dirs = dirs; - cone_dir_count = 4; - cone_aperture = 1.0; // tan(angle) 90 degrees - cone_weights = weights; - } break; - case BAKE_QUALITY_MEDIUM: { - //default quality - static const Vector3 dirs[6] = { - Vector3(0, 0, 1), - Vector3(0.866025, 0, 0.5), - Vector3(0.267617, 0.823639, 0.5), - Vector3(-0.700629, 0.509037, 0.5), - Vector3(-0.700629, -0.509037, 0.5), - Vector3(0.267617, -0.823639, 0.5) - }; - static const float weights[6] = { 0.25f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f }; - // - cone_dirs = dirs; - cone_dir_count = 6; - cone_aperture = 0.577; // tan(angle) 60 degrees - cone_weights = weights; - } break; - case BAKE_QUALITY_HIGH: { - - //high qualily - static const Vector3 dirs[10] = { - Vector3(0.8781648411741658, 0.0, 0.478358141694643), - Vector3(0.5369754325592234, 0.6794204427701518, 0.5000452447267606), - Vector3(-0.19849436573466497, 0.8429904390140635, 0.49996710542041645), - Vector3(-0.7856196499811189, 0.3639120321329737, 0.5003696617825604), - Vector3(-0.7856196499811189, -0.3639120321329737, 0.5003696617825604), - Vector3(-0.19849436573466497, -0.8429904390140635, 0.49996710542041645), - Vector3(0.5369754325592234, -0.6794204427701518, 0.5000452447267606), - Vector3(-0.4451656858129485, 0.0, 0.8954482185892644), - Vector3(0.19124006749743122, 0.39355745585016605, 0.8991883926788214), - Vector3(0.19124006749743122, -0.39355745585016605, 0.8991883926788214), - }; - static const float weights[10] = { 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.08571f, 0.133333f, 0.133333f, 0.13333f }; - cone_dirs = dirs; - cone_dir_count = 10; - cone_aperture = 0.404; // tan(angle) 45 degrees - cone_weights = weights; - } break; - } - - Vector3 accum; - - for (int i = 0; i < cone_dir_count; i++) { - Vector3 dir = normal_xform.xform(cone_dirs[i]).normalized(); //normal may not completely correct when transformed to cell - accum += _voxel_cone_trace(p_pos, dir, cone_aperture) * cone_weights[i]; - } - - return accum; -} - -_ALWAYS_INLINE_ uint32_t xorshift32(uint32_t *state) { - /* Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs" */ - uint32_t x = *state; - x ^= x << 13; - x ^= x >> 17; - x ^= x << 5; - *state = x; - return x; -} - -Vector3 VoxelLightBaker::_compute_ray_trace_at_pos(const Vector3 &p_pos, const Vector3 &p_normal) { - - int samples_per_quality[3] = { 48, 128, 512 }; - - int samples = samples_per_quality[bake_quality]; - - //create a basis in Z - Vector3 v0 = Math::abs(p_normal.z) < 0.999 ? Vector3(0, 0, 1) : Vector3(0, 1, 0); - Vector3 tangent = v0.cross(p_normal).normalized(); - Vector3 bitangent = tangent.cross(p_normal).normalized(); - Basis normal_xform = Basis(tangent, bitangent, p_normal).transposed(); - - float bias = 1.5; - int max_level = cell_subdiv - 1; - int size = 1 << max_level; - - Vector3 accum; - float spread = Math::deg2rad(80.0); - - const Light *light = bake_light.ptr(); - const Cell *cells = bake_cells.ptr(); - - uint32_t local_rng_state = rand(); //needs to be fixed again - - for (int i = 0; i < samples; i++) { - - float random_angle1 = (((xorshift32(&local_rng_state) % 65535) / 65535.0) * 2.0 - 1.0) * spread; - Vector3 axis(0, sin(random_angle1), cos(random_angle1)); - float random_angle2 = ((xorshift32(&local_rng_state) % 65535) / 65535.0) * Math_PI * 2.0; - Basis rot(Vector3(0, 0, 1), random_angle2); - axis = rot.xform(axis); - - Vector3 direction = normal_xform.xform(axis).normalized(); - - Vector3 advance = direction * _get_normal_advance(direction); - - Vector3 pos = p_pos /*+ Vector3(0.5, 0.5, 0.5)*/ + advance * bias; - - uint32_t cell = CHILD_EMPTY; - - while (cell == CHILD_EMPTY) { - - int x = int(pos.x); - int y = int(pos.y); - int z = int(pos.z); - - int ofs_x = 0; - int ofs_y = 0; - int ofs_z = 0; - int half = size / 2; - - if (x < 0 || x >= size) - break; - if (y < 0 || y >= size) - break; - if (z < 0 || z >= size) - break; - - //int level_limit = max_level; - - cell = 0; //start from root - for (int j = 0; j < max_level; j++) { - - const Cell *bc = &cells[cell]; - - int child = 0; - if (x >= ofs_x + half) { - child |= 1; - ofs_x += half; - } - if (y >= ofs_y + half) { - child |= 2; - ofs_y += half; - } - if (z >= ofs_z + half) { - child |= 4; - ofs_z += half; - } - - cell = bc->children[child]; - if (unlikely(cell == CHILD_EMPTY)) - break; - - half >>= 1; - } - - pos += advance; - } - - if (unlikely(cell != CHILD_EMPTY)) { - for (int j = 0; j < 6; j++) { - //anisotropic read light - float amount = direction.dot(aniso_normal[j]); - if (amount <= 0) - continue; - accum.x += light[cell].accum[j][0] * amount; - accum.y += light[cell].accum[j][1] * amount; - accum.z += light[cell].accum[j][2] * amount; - } - accum.x += cells[cell].emission[0]; - accum.y += cells[cell].emission[1]; - accum.z += cells[cell].emission[2]; - } - } - - // Make sure we don't reset this thread's RNG state - - return accum / samples; -} - -void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) { - - LightMap *pixel = &p_line[p_x]; - if (pixel->pos == Vector3()) - return; - switch (bake_mode) { - case BAKE_MODE_CONE_TRACE: { - pixel->light = _compute_pixel_light_at_pos(pixel->pos, pixel->normal) * energy; - } break; - case BAKE_MODE_RAY_TRACE: { - pixel->light = _compute_ray_trace_at_pos(pixel->pos, pixel->normal) * energy; - } break; - } -} - -Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { - - //transfer light information to a lightmap - Ref<Mesh> mesh = p_mesh; - - //step 1 - create lightmap - int width; - int height; - Vector<LightMap> lightmap; - Transform xform = to_cell_space * p_xform; - if (mesh->get_lightmap_size_hint() == Size2()) { - double area = 0; - double uv_area = 0; - for (int i = 0; i < mesh->get_surface_count(); i++) { - Array arrays = mesh->surface_get_arrays(i); - PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX]; - PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2]; - PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX]; - - ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER); - - int vc = vertices.size(); - PoolVector<Vector3>::Read vr = vertices.read(); - PoolVector<Vector2>::Read u2r = uv2.read(); - PoolVector<int>::Read ir; - int ic = 0; - - if (indices.size()) { - ic = indices.size(); - ir = indices.read(); - } - - int faces = ic ? ic / 3 : vc / 3; - for (int j = 0; j < faces; j++) { - Vector3 vertex[3]; - Vector2 uv[3]; - - for (int k = 0; k < 3; k++) { - int idx = ic ? ir[j * 3 + k] : j * 3 + k; - vertex[k] = xform.xform(vr[idx]); - uv[k] = u2r[idx]; - } - - Vector3 p1 = vertex[0]; - Vector3 p2 = vertex[1]; - Vector3 p3 = vertex[2]; - double a = p1.distance_to(p2); - double b = p2.distance_to(p3); - double c = p3.distance_to(p1); - double halfPerimeter = (a + b + c) / 2.0; - area += sqrt(halfPerimeter * (halfPerimeter - a) * (halfPerimeter - b) * (halfPerimeter - c)); - - Vector2 uv_p1 = uv[0]; - Vector2 uv_p2 = uv[1]; - Vector2 uv_p3 = uv[2]; - double uv_a = uv_p1.distance_to(uv_p2); - double uv_b = uv_p2.distance_to(uv_p3); - double uv_c = uv_p3.distance_to(uv_p1); - double uv_halfPerimeter = (uv_a + uv_b + uv_c) / 2.0; - uv_area += sqrt(uv_halfPerimeter * (uv_halfPerimeter - uv_a) * (uv_halfPerimeter - uv_b) * (uv_halfPerimeter - uv_c)); - } - } - - if (uv_area < 0.0001f) { - uv_area = 1.0; - } - - int pixels = (ceil((1.0 / sqrt(uv_area)) * sqrt(area * default_texels_per_unit))); - width = height = CLAMP(pixels, 2, 4096); - } else { - width = mesh->get_lightmap_size_hint().x; - height = mesh->get_lightmap_size_hint().y; - } - - lightmap.resize(width * height); - - //step 2 plot faces to lightmap - for (int i = 0; i < mesh->get_surface_count(); i++) { - Array arrays = mesh->surface_get_arrays(i); - PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX]; - PoolVector<Vector3> normals = arrays[Mesh::ARRAY_NORMAL]; - PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2]; - PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX]; - - ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(normals.size() == 0, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER); - - int vc = vertices.size(); - PoolVector<Vector3>::Read vr = vertices.read(); - PoolVector<Vector3>::Read nr = normals.read(); - PoolVector<Vector2>::Read u2r = uv2.read(); - PoolVector<int>::Read ir; - int ic = 0; - - if (indices.size()) { - ic = indices.size(); - ir = indices.read(); - } - - int faces = ic ? ic / 3 : vc / 3; - for (int j = 0; j < faces; j++) { - Vector3 vertex[3]; - Vector3 normal[3]; - Vector2 uv[3]; - - for (int k = 0; k < 3; k++) { - int idx = ic ? ir[j * 3 + k] : j * 3 + k; - vertex[k] = xform.xform(vr[idx]); - normal[k] = xform.basis.xform(nr[idx]).normalized(); - uv[k] = u2r[idx]; - } - - _plot_triangle(uv, vertex, normal, lightmap.ptrw(), width, height); - } - } - - //step 3 perform voxel cone trace on lightmap pixels - { - LightMap *lightmap_ptr = lightmap.ptrw(); - uint64_t begin_time = OS::get_singleton()->get_ticks_usec(); - volatile int lines = 0; - - // make sure our OS-level rng is seeded - - for (int i = 0; i < height; i++) { - - thread_process_array(width, this, &VoxelLightBaker::_lightmap_bake_point, &lightmap_ptr[i * width]); - - lines = MAX(lines, i); //for multithread - if (p_bake_time_func) { - uint64_t elapsed = OS::get_singleton()->get_ticks_usec() - begin_time; - float elapsed_sec = double(elapsed) / 1000000.0; - float remaining = lines < 1 ? 0 : (elapsed_sec / lines) * (height - lines - 1); - if (p_bake_time_func(p_bake_time_ud, remaining, lines / float(height))) { - return ERR_SKIP; - } - } - } - - if (bake_mode == BAKE_MODE_RAY_TRACE) { - //blur - //gauss kernel, 7 step sigma 2 - static const float gauss_kernel[4] = { 0.214607f, 0.189879f, 0.131514f, 0.071303f }; - //horizontal pass - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - if (lightmap_ptr[i * width + j].normal == Vector3()) { - continue; //empty - } - float gauss_sum = gauss_kernel[0]; - Vector3 accum = lightmap_ptr[i * width + j].light * gauss_kernel[0]; - for (int k = 1; k < 4; k++) { - int new_x = j + k; - if (new_x >= width || lightmap_ptr[i * width + new_x].normal == Vector3()) - break; - gauss_sum += gauss_kernel[k]; - accum += lightmap_ptr[i * width + new_x].light * gauss_kernel[k]; - } - for (int k = 1; k < 4; k++) { - int new_x = j - k; - if (new_x < 0 || lightmap_ptr[i * width + new_x].normal == Vector3()) - break; - gauss_sum += gauss_kernel[k]; - accum += lightmap_ptr[i * width + new_x].light * gauss_kernel[k]; - } - - lightmap_ptr[i * width + j].pos = accum /= gauss_sum; - } - } - //vertical pass - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - if (lightmap_ptr[i * width + j].normal == Vector3()) - continue; //empty, don't write over it anyway - float gauss_sum = gauss_kernel[0]; - Vector3 accum = lightmap_ptr[i * width + j].pos * gauss_kernel[0]; - for (int k = 1; k < 4; k++) { - int new_y = i + k; - if (new_y >= height || lightmap_ptr[new_y * width + j].normal == Vector3()) - break; - gauss_sum += gauss_kernel[k]; - accum += lightmap_ptr[new_y * width + j].pos * gauss_kernel[k]; - } - for (int k = 1; k < 4; k++) { - int new_y = i - k; - if (new_y < 0 || lightmap_ptr[new_y * width + j].normal == Vector3()) - break; - gauss_sum += gauss_kernel[k]; - accum += lightmap_ptr[new_y * width + j].pos * gauss_kernel[k]; - } - - lightmap_ptr[i * width + j].light = accum /= gauss_sum; - } - } - } - - //add directional light (do this after blur) - { - const Cell *cells = bake_cells.ptr(); - const Light *light = bake_light.ptr(); -#ifdef _OPENMP -#pragma omp parallel -#endif - for (int i = 0; i < height; i++) { -#ifdef _OPENMP -#pragma omp parallel for schedule(dynamic, 1) -#endif - for (int j = 0; j < width; j++) { - - //if (i == 125 && j == 280) { - - LightMap *pixel = &lightmap_ptr[i * width + j]; - if (pixel->pos == Vector3()) - continue; //unused, skipe - - int x = int(pixel->pos.x) - 1; - int y = int(pixel->pos.y) - 1; - int z = int(pixel->pos.z) - 1; - Color accum; - int size = 1 << (cell_subdiv - 1); - - int found = 0; - - for (int k = 0; k < 8; k++) { - - int ofs_x = x; - int ofs_y = y; - int ofs_z = z; - - if (k & 1) - ofs_x++; - if (k & 2) - ofs_y++; - if (k & 4) - ofs_z++; - - if (x < 0 || x >= size) - continue; - if (y < 0 || y >= size) - continue; - if (z < 0 || z >= size) - continue; - - uint32_t cell = _find_cell_at_pos(cells, ofs_x, ofs_y, ofs_z); - - if (cell == CHILD_EMPTY) - continue; - for (int l = 0; l < 6; l++) { - float s = pixel->normal.dot(aniso_normal[l]); - if (s < 0) - s = 0; - accum.r += light[cell].direct_accum[l][0] * s; - accum.g += light[cell].direct_accum[l][1] * s; - accum.b += light[cell].direct_accum[l][2] * s; - } - found++; - } - if (found) { - accum /= found; - pixel->light.x += accum.r; - pixel->light.y += accum.g; - pixel->light.z += accum.b; - } - } - } - } - - { - //fill gaps with neighbour vertices to avoid filter fades to black on edges - - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - if (lightmap_ptr[i * width + j].normal != Vector3()) { - continue; //filled, skip - } - - //this can't be made separatable.. - - int closest_i = -1, closest_j = 1; - float closest_dist = 1e20; - - const int margin = 3; - for (int y = i - margin; y <= i + margin; y++) { - for (int x = j - margin; x <= j + margin; x++) { - - if (x == j && y == i) - continue; - if (x < 0 || x >= width) - continue; - if (y < 0 || y >= height) - continue; - if (lightmap_ptr[y * width + x].normal == Vector3()) - continue; //also ensures that blitted stuff is not reused - - float dist = Vector2(i - y, j - x).length(); - if (dist > closest_dist) - continue; - - closest_dist = dist; - closest_i = y; - closest_j = x; - } - } - - if (closest_i != -1) { - lightmap_ptr[i * width + j].light = lightmap_ptr[closest_i * width + closest_j].light; - } - } - } - } - - { - //fill the lightmap data - r_lightmap.width = width; - r_lightmap.height = height; - r_lightmap.light.resize(lightmap.size() * 3); - PoolVector<float>::Write w = r_lightmap.light.write(); - for (int i = 0; i < lightmap.size(); i++) { - w[i * 3 + 0] = lightmap[i].light.x; - w[i * 3 + 1] = lightmap[i].light.y; - w[i * 3 + 2] = lightmap[i].light.z; - } - } - -#if 0 // Enable for debugging. - { - PoolVector<uint8_t> img; - int ls = lightmap.size(); - img.resize(ls * 3); - { - PoolVector<uint8_t>::Write w = img.write(); - for (int i = 0; i < ls; i++) { - w[i * 3 + 0] = CLAMP(lightmap_ptr[i].light.x * 255, 0, 255); - w[i * 3 + 1] = CLAMP(lightmap_ptr[i].light.y * 255, 0, 255); - w[i * 3 + 2] = CLAMP(lightmap_ptr[i].light.z * 255, 0, 255); - //w[i * 3 + 0] = CLAMP(lightmap_ptr[i].normal.x * 255, 0, 255); - //w[i * 3 + 1] = CLAMP(lightmap_ptr[i].normal.y * 255, 0, 255); - //w[i * 3 + 2] = CLAMP(lightmap_ptr[i].normal.z * 255, 0, 255); - //w[i * 3 + 0] = CLAMP(lightmap_ptr[i].pos.x / (1 << (cell_subdiv - 1)) * 255, 0, 255); - //w[i * 3 + 1] = CLAMP(lightmap_ptr[i].pos.y / (1 << (cell_subdiv - 1)) * 255, 0, 255); - //w[i * 3 + 2] = CLAMP(lightmap_ptr[i].pos.z / (1 << (cell_subdiv - 1)) * 255, 0, 255); - } - } - - Ref<Image> image; - image.instance(); - image->create(width, height, false, Image::FORMAT_RGB8, img); - - String name = p_mesh->get_name(); - if (name == "") { - name = "Mesh" + itos(p_mesh->get_instance_id()); - } - image->save_png(name + ".png"); - } -#endif - } - - return OK; -} - -void VoxelLightBaker::begin_bake(int p_subdiv, const AABB &p_bounds) { - - original_bounds = p_bounds; - cell_subdiv = p_subdiv; - bake_cells.resize(1); - material_cache.clear(); - - //find out the actual real bounds, power of 2, which gets the highest subdivision - po2_bounds = p_bounds; - int longest_axis = po2_bounds.get_longest_axis_index(); - axis_cell_size[longest_axis] = (1 << (cell_subdiv - 1)); - leaf_voxel_count = 0; - - for (int i = 0; i < 3; i++) { - - if (i == longest_axis) - continue; - - axis_cell_size[i] = axis_cell_size[longest_axis]; - float axis_size = po2_bounds.size[longest_axis]; - - //shrink until fit subdiv - while (axis_size / 2.0 >= po2_bounds.size[i]) { - axis_size /= 2.0; - axis_cell_size[i] >>= 1; - } - - po2_bounds.size[i] = po2_bounds.size[longest_axis]; - } - - Transform to_bounds; - to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis])); - to_bounds.origin = po2_bounds.position; - - Transform to_grid; - to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis])); - - to_cell_space = to_grid * to_bounds.affine_inverse(); - - cell_size = po2_bounds.size[longest_axis] / axis_cell_size[longest_axis]; -} - -void VoxelLightBaker::end_bake() { - _fixup_plot(0, 0); -} - -//create the data for visual server - -PoolVector<int> VoxelLightBaker::create_gi_probe_data() { - - PoolVector<int> data; - - data.resize(16 + (8 + 1 + 1 + 1 + 1) * bake_cells.size()); //4 for header, rest for rest. - - { - PoolVector<int>::Write w = data.write(); - - uint32_t *w32 = (uint32_t *)w.ptr(); - - w32[0] = 0; //version - w32[1] = cell_subdiv; //subdiv - w32[2] = axis_cell_size[0]; - w32[3] = axis_cell_size[1]; - w32[4] = axis_cell_size[2]; - w32[5] = bake_cells.size(); - w32[6] = leaf_voxel_count; - - int ofs = 16; - - for (int i = 0; i < bake_cells.size(); i++) { - - for (int j = 0; j < 8; j++) { - w32[ofs++] = bake_cells[i].children[j]; - } - - { //albedo - uint32_t rgba = uint32_t(CLAMP(bake_cells[i].albedo[0] * 255.0, 0, 255)) << 16; - rgba |= uint32_t(CLAMP(bake_cells[i].albedo[1] * 255.0, 0, 255)) << 8; - rgba |= uint32_t(CLAMP(bake_cells[i].albedo[2] * 255.0, 0, 255)) << 0; - - w32[ofs++] = rgba; - } - { //emission - - Vector3 e(bake_cells[i].emission[0], bake_cells[i].emission[1], bake_cells[i].emission[2]); - float l = e.length(); - if (l > 0) { - e.normalize(); - l = CLAMP(l / 8.0, 0, 1.0); - } - - uint32_t em = uint32_t(CLAMP(e[0] * 255, 0, 255)) << 24; - em |= uint32_t(CLAMP(e[1] * 255, 0, 255)) << 16; - em |= uint32_t(CLAMP(e[2] * 255, 0, 255)) << 8; - em |= uint32_t(CLAMP(l * 255, 0, 255)); - - w32[ofs++] = em; - } - - //w32[ofs++]=bake_cells[i].used_sides; - { //normal - - Vector3 n(bake_cells[i].normal[0], bake_cells[i].normal[1], bake_cells[i].normal[2]); - n = n * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - uint32_t norm = 0; - - norm |= uint32_t(CLAMP(n.x * 255.0, 0, 255)) << 16; - norm |= uint32_t(CLAMP(n.y * 255.0, 0, 255)) << 8; - norm |= uint32_t(CLAMP(n.z * 255.0, 0, 255)) << 0; - - w32[ofs++] = norm; - } - - { - uint16_t alpha = MIN(uint32_t(bake_cells[i].alpha * 65535.0), 65535); - uint16_t level = bake_cells[i].level; - - w32[ofs++] = (uint32_t(level) << 16) | uint32_t(alpha); - } - } - } - - return data; -} - -void VoxelLightBaker::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, DebugMode p_mode) { - - if (p_level == cell_subdiv - 1) { - - Vector3 center = p_aabb.position + p_aabb.size * 0.5; - Transform xform; - xform.origin = center; - xform.basis.scale(p_aabb.size * 0.5); - p_multimesh->set_instance_transform(idx, xform); - Color col; - if (p_mode == DEBUG_ALBEDO) { - col = Color(bake_cells[p_idx].albedo[0], bake_cells[p_idx].albedo[1], bake_cells[p_idx].albedo[2]); - } else if (p_mode == DEBUG_LIGHT) { - for (int i = 0; i < 6; i++) { - col.r += bake_light[p_idx].accum[i][0]; - col.g += bake_light[p_idx].accum[i][1]; - col.b += bake_light[p_idx].accum[i][2]; - col.r += bake_light[p_idx].direct_accum[i][0]; - col.g += bake_light[p_idx].direct_accum[i][1]; - col.b += bake_light[p_idx].direct_accum[i][2]; - } - } - //Color col = Color(bake_cells[p_idx].emission[0], bake_cells[p_idx].emission[1], bake_cells[p_idx].emission[2]); - p_multimesh->set_instance_color(idx, col); - - idx++; - - } else { - - for (int i = 0; i < 8; i++) { - - uint32_t child = bake_cells[p_idx].children[i]; - - if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) - continue; - - AABB aabb = p_aabb; - aabb.size *= 0.5; - - if (i & 1) - aabb.position.x += aabb.size.x; - if (i & 2) - aabb.position.y += aabb.size.y; - if (i & 4) - aabb.position.z += aabb.size.z; - - _debug_mesh(bake_cells[p_idx].children[i], p_level + 1, aabb, p_multimesh, idx, p_mode); - } - } -} - -Ref<MultiMesh> VoxelLightBaker::create_debug_multimesh(DebugMode p_mode) { - - Ref<MultiMesh> mm; - - ERR_FAIL_COND_V(p_mode == DEBUG_LIGHT && bake_light.size() == 0, mm); - mm.instance(); - - mm->set_transform_format(MultiMesh::TRANSFORM_3D); - mm->set_color_format(MultiMesh::COLOR_8BIT); - mm->set_instance_count(leaf_voxel_count); - - Ref<ArrayMesh> mesh; - mesh.instance(); - - { - Array arr; - arr.resize(Mesh::ARRAY_MAX); - - PoolVector<Vector3> vertices; - PoolVector<Color> colors; -#define ADD_VTX(m_idx) \ - ; \ - vertices.push_back(face_points[m_idx]); \ - colors.push_back(Color(1, 1, 1, 1)); - - for (int i = 0; i < 6; i++) { - - Vector3 face_points[4]; - - for (int j = 0; j < 4; j++) { - - float v[3]; - v[0] = 1.0; - v[1] = 1 - 2 * ((j >> 1) & 1); - v[2] = v[1] * (1 - 2 * (j & 1)); - - for (int k = 0; k < 3; k++) { - - if (i < 3) - face_points[j][(i + k) % 3] = v[k]; - else - face_points[3 - j][(i + k) % 3] = -v[k]; - } - } - - //tri 1 - ADD_VTX(0); - ADD_VTX(1); - ADD_VTX(2); - //tri 2 - ADD_VTX(2); - ADD_VTX(3); - ADD_VTX(0); - } - - arr[Mesh::ARRAY_VERTEX] = vertices; - arr[Mesh::ARRAY_COLOR] = colors; - mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr); - } - - { - Ref<SpatialMaterial> fsm; - fsm.instance(); - fsm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - fsm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - fsm->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - fsm->set_albedo(Color(1, 1, 1, 1)); - - mesh->surface_set_material(0, fsm); - } - - mm->set_mesh(mesh); - - int idx = 0; - _debug_mesh(0, 0, po2_bounds, mm, idx, p_mode); - - return mm; -} - -struct VoxelLightBakerOctree { - - enum { - CHILD_EMPTY = 0xFFFFFFFF - }; - - uint16_t light[6][3]; //anisotropic light - float alpha; - uint32_t children[8]; -}; - -PoolVector<uint8_t> VoxelLightBaker::create_capture_octree(int p_subdiv) { - - p_subdiv = MIN(p_subdiv, cell_subdiv); // use the smaller one - - Vector<uint32_t> remap; - int bc = bake_cells.size(); - remap.resize(bc); - Vector<uint32_t> demap; - - int new_size = 0; - for (int i = 0; i < bc; i++) { - uint32_t c = CHILD_EMPTY; - if (bake_cells[i].level < p_subdiv) { - c = new_size; - new_size++; - demap.push_back(i); - } - remap.write[i] = c; - } - - Vector<VoxelLightBakerOctree> octree; - octree.resize(new_size); - - for (int i = 0; i < new_size; i++) { - octree.write[i].alpha = bake_cells[demap[i]].alpha; - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 3; k++) { - float l = bake_light[demap[i]].accum[j][k]; //add anisotropic light - l += bake_cells[demap[i]].emission[k]; //add emission - octree.write[i].light[j][k] = CLAMP(l * 1024, 0, 65535); //give two more bits to octree - } - } - - for (int j = 0; j < 8; j++) { - uint32_t child = bake_cells[demap[i]].children[j]; - octree.write[i].children[j] = child == CHILD_EMPTY ? CHILD_EMPTY : remap[child]; - } - } - - PoolVector<uint8_t> ret; - int ret_bytes = octree.size() * sizeof(VoxelLightBakerOctree); - ret.resize(ret_bytes); - { - PoolVector<uint8_t>::Write w = ret.write(); - copymem(w.ptr(), octree.ptr(), ret_bytes); - } - - return ret; -} - -float VoxelLightBaker::get_cell_size() const { - return cell_size; -} - -Transform VoxelLightBaker::get_to_cell_space_xform() const { - return to_cell_space; -} -VoxelLightBaker::VoxelLightBaker() { - color_scan_cell_width = 4; - bake_texture_size = 128; - propagation = 0.85; - energy = 1.0; -} diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp new file mode 100644 index 0000000000..0257e6e83d --- /dev/null +++ b/scene/3d/voxelizer.cpp @@ -0,0 +1,1224 @@ +/*************************************************************************/ +/* voxelizer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "voxelizer.h" +#include "core/os/os.h" +#include "core/os/threaded_array_processor.h" + +#include <stdlib.h> + +#define FINDMINMAX(x0, x1, x2, min, max) \ + min = max = x0; \ + if (x1 < min) min = x1; \ + if (x1 > max) max = x1; \ + if (x2 < min) min = x2; \ + if (x2 > max) max = x2; + +static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) { + int q; + Vector3 vmin, vmax; + for (q = 0; q <= 2; q++) { + if (normal[q] > 0.0f) { + vmin[q] = -maxbox[q]; + vmax[q] = maxbox[q]; + } else { + vmin[q] = maxbox[q]; + vmax[q] = -maxbox[q]; + } + } + if (normal.dot(vmin) + d > 0.0f) return false; + if (normal.dot(vmax) + d >= 0.0f) return true; + + return false; +} + +/*======================== X-tests ========================*/ +#define AXISTEST_X01(a, b, fa, fb) \ + p0 = a * v0.y - b * v0.z; \ + p2 = a * v2.y - b * v2.z; \ + if (p0 < p2) { \ + min = p0; \ + max = p2; \ + } else { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if (min > rad || max < -rad) return false; + +#define AXISTEST_X2(a, b, fa, fb) \ + p0 = a * v0.y - b * v0.z; \ + p1 = a * v1.y - b * v1.z; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \ + if (min > rad || max < -rad) return false; + +/*======================== Y-tests ========================*/ +#define AXISTEST_Y02(a, b, fa, fb) \ + p0 = -a * v0.x + b * v0.z; \ + p2 = -a * v2.x + b * v2.z; \ + if (p0 < p2) { \ + min = p0; \ + max = p2; \ + } else { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if (min > rad || max < -rad) return false; + +#define AXISTEST_Y1(a, b, fa, fb) \ + p0 = -a * v0.x + b * v0.z; \ + p1 = -a * v1.x + b * v1.z; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \ + if (min > rad || max < -rad) return false; + +/*======================== Z-tests ========================*/ + +#define AXISTEST_Z12(a, b, fa, fb) \ + p1 = a * v1.x - b * v1.y; \ + p2 = a * v2.x - b * v2.y; \ + if (p2 < p1) { \ + min = p2; \ + max = p1; \ + } else { \ + min = p1; \ + max = p2; \ + } \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if (min > rad || max < -rad) return false; + +#define AXISTEST_Z0(a, b, fa, fb) \ + p0 = a * v0.x - b * v0.y; \ + p1 = a * v1.x - b * v1.y; \ + if (p0 < p1) { \ + min = p0; \ + max = p1; \ + } else { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \ + if (min > rad || max < -rad) return false; + +static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) { + + /* use separating axis theorem to test overlap between triangle and box */ + /* need to test for overlap in these directions: */ + /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ + /* we do not even need to test these) */ + /* 2) normal of the triangle */ + /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ + /* this gives 3x3=9 more tests */ + Vector3 v0, v1, v2; + float min, max, d, p0, p1, p2, rad, fex, fey, fez; + Vector3 normal, e0, e1, e2; + + /* This is the fastest branch on Sun */ + /* move everything so that the boxcenter is in (0,0,0) */ + + v0 = triverts[0] - boxcenter; + v1 = triverts[1] - boxcenter; + v2 = triverts[2] - boxcenter; + + /* compute triangle edges */ + e0 = v1 - v0; /* tri edge 0 */ + e1 = v2 - v1; /* tri edge 1 */ + e2 = v0 - v2; /* tri edge 2 */ + + /* Bullet 3: */ + /* test the 9 tests first (this was faster) */ + fex = Math::abs(e0.x); + fey = Math::abs(e0.y); + fez = Math::abs(e0.z); + AXISTEST_X01(e0.z, e0.y, fez, fey); + AXISTEST_Y02(e0.z, e0.x, fez, fex); + AXISTEST_Z12(e0.y, e0.x, fey, fex); + + fex = Math::abs(e1.x); + fey = Math::abs(e1.y); + fez = Math::abs(e1.z); + AXISTEST_X01(e1.z, e1.y, fez, fey); + AXISTEST_Y02(e1.z, e1.x, fez, fex); + AXISTEST_Z0(e1.y, e1.x, fey, fex); + + fex = Math::abs(e2.x); + fey = Math::abs(e2.y); + fez = Math::abs(e2.z); + AXISTEST_X2(e2.z, e2.y, fez, fey); + AXISTEST_Y1(e2.z, e2.x, fez, fex); + AXISTEST_Z12(e2.y, e2.x, fey, fex); + + /* Bullet 1: */ + /* first test overlap in the {x,y,z}-directions */ + /* find min, max of the triangle each direction, and test for overlap in */ + /* that direction -- this is equivalent to testing a minimal AABB around */ + /* the triangle against the AABB */ + + /* test in X-direction */ + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if (min > boxhalfsize.x || max < -boxhalfsize.x) return false; + + /* test in Y-direction */ + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if (min > boxhalfsize.y || max < -boxhalfsize.y) return false; + + /* test in Z-direction */ + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if (min > boxhalfsize.z || max < -boxhalfsize.z) return false; + + /* Bullet 2: */ + /* test if the box intersects the plane of the triangle */ + /* compute plane equation of triangle: normal*x+d=0 */ + normal = e0.cross(e1); + d = -normal.dot(v0); /* plane eq: normal.x+d=0 */ + return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */ +} + +static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) { + + if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) { + r_uv = p_uv[0]; + r_normal = p_normal[0]; + return; + } + if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) { + r_uv = p_uv[1]; + r_normal = p_normal[1]; + return; + } + if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) { + r_uv = p_uv[2]; + r_normal = p_normal[2]; + return; + } + + Vector3 v0 = p_vtx[1] - p_vtx[0]; + Vector3 v1 = p_vtx[2] - p_vtx[0]; + Vector3 v2 = p_pos - p_vtx[0]; + + float d00 = v0.dot(v0); + float d01 = v0.dot(v1); + float d11 = v1.dot(v1); + float d20 = v2.dot(v0); + float d21 = v2.dot(v1); + float denom = (d00 * d11 - d01 * d01); + if (denom == 0) { + r_uv = p_uv[0]; + r_normal = p_normal[0]; + return; + } + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + + r_uv = p_uv[0] * u + p_uv[1] * v + p_uv[2] * w; + r_normal = (p_normal[0] * u + p_normal[1] * v + p_normal[2] * w).normalized(); +} + +void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) { + + if (p_level == cell_subdiv) { + //plot the face by guessing its albedo and emission value + + //find best axis to map to, for scanning values + int closest_axis = 0; + float closest_dot = 0; + + Plane plane = Plane(p_vtx[0], p_vtx[1], p_vtx[2]); + Vector3 normal = plane.normal; + + for (int i = 0; i < 3; i++) { + + Vector3 axis; + axis[i] = 1.0; + float dot = ABS(normal.dot(axis)); + if (i == 0 || dot > closest_dot) { + closest_axis = i; + closest_dot = dot; + } + } + + Vector3 axis; + axis[closest_axis] = 1.0; + Vector3 t1; + t1[(closest_axis + 1) % 3] = 1.0; + Vector3 t2; + t2[(closest_axis + 2) % 3] = 1.0; + + t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width); + t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width); + + Color albedo_accum; + Color emission_accum; + Vector3 normal_accum; + + float alpha = 0.0; + + //map to a grid average in the best axis for this face + for (int i = 0; i < color_scan_cell_width; i++) { + + Vector3 ofs_i = float(i) * t1; + + for (int j = 0; j < color_scan_cell_width; j++) { + + Vector3 ofs_j = float(j) * t2; + + Vector3 from = p_aabb.position + ofs_i + ofs_j; + Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis]; + Vector3 half = (to - from) * 0.5; + + //is in this cell? + if (!fast_tri_box_overlap(from + half, half, p_vtx)) { + continue; //face does not span this cell + } + + //go from -size to +size*2 to avoid skipping collisions + Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis]; + Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2; + + if (normal.dot(ray_from - ray_to) < 0) { + SWAP(ray_from, ray_to); + } + + Vector3 intersection; + + if (!plane.intersects_segment(ray_from, ray_to, &intersection)) { + if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) { + intersection = plane.project(ray_from); + } else { + + intersection = plane.project(ray_to); + } + } + + intersection = Face3(p_vtx[0], p_vtx[1], p_vtx[2]).get_closest_point_to(intersection); + + Vector2 uv; + Vector3 lnormal; + get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal); + if (lnormal == Vector3()) //just in case normal as nor provided + lnormal = normal; + + int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); + int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1); + + int ofs = uv_y * bake_texture_size + uv_x; + albedo_accum.r += p_material.albedo[ofs].r; + albedo_accum.g += p_material.albedo[ofs].g; + albedo_accum.b += p_material.albedo[ofs].b; + albedo_accum.a += p_material.albedo[ofs].a; + + emission_accum.r += p_material.emission[ofs].r; + emission_accum.g += p_material.emission[ofs].g; + emission_accum.b += p_material.emission[ofs].b; + + normal_accum += lnormal; + + alpha += 1.0; + } + } + + if (alpha == 0) { + //could not in any way get texture information.. so use closest point to center + + Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]); + Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5); + + Vector3 lnormal; + Vector2 uv; + get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal); + if (lnormal == Vector3()) //just in case normal as nor provided + lnormal = normal; + + int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); + int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1); + + int ofs = uv_y * bake_texture_size + uv_x; + + alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width); + + albedo_accum.r = p_material.albedo[ofs].r * alpha; + albedo_accum.g = p_material.albedo[ofs].g * alpha; + albedo_accum.b = p_material.albedo[ofs].b * alpha; + albedo_accum.a = p_material.albedo[ofs].a * alpha; + + emission_accum.r = p_material.emission[ofs].r * alpha; + emission_accum.g = p_material.emission[ofs].g * alpha; + emission_accum.b = p_material.emission[ofs].b * alpha; + + normal_accum = lnormal * alpha; + + } else { + + float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width); + alpha *= accdiv; + + albedo_accum.r *= accdiv; + albedo_accum.g *= accdiv; + albedo_accum.b *= accdiv; + albedo_accum.a *= accdiv; + + emission_accum.r *= accdiv; + emission_accum.g *= accdiv; + emission_accum.b *= accdiv; + + normal_accum *= accdiv; + } + + //put this temporarily here, corrected in a later step + bake_cells.write[p_idx].albedo[0] += albedo_accum.r; + bake_cells.write[p_idx].albedo[1] += albedo_accum.g; + bake_cells.write[p_idx].albedo[2] += albedo_accum.b; + bake_cells.write[p_idx].emission[0] += emission_accum.r; + bake_cells.write[p_idx].emission[1] += emission_accum.g; + bake_cells.write[p_idx].emission[2] += emission_accum.b; + bake_cells.write[p_idx].normal[0] += normal_accum.x; + bake_cells.write[p_idx].normal[1] += normal_accum.y; + bake_cells.write[p_idx].normal[2] += normal_accum.z; + bake_cells.write[p_idx].alpha += alpha; + + } else { + //go down + + int half = (1 << cell_subdiv) >> (p_level + 1); + for (int i = 0; i < 8; i++) { + + AABB aabb = p_aabb; + aabb.size *= 0.5; + + int nx = p_x; + int ny = p_y; + int nz = p_z; + + if (i & 1) { + aabb.position.x += aabb.size.x; + nx += half; + } + if (i & 2) { + aabb.position.y += aabb.size.y; + ny += half; + } + if (i & 4) { + aabb.position.z += aabb.size.z; + nz += half; + } + //make sure to not plot beyond limits + if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2]) + continue; + + { + AABB test_aabb = aabb; + //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time + Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test + + if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) { + //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) { + //does not fit in child, go on + continue; + } + } + + if (bake_cells[p_idx].children[i] == CHILD_EMPTY) { + //sub cell must be created + + uint32_t child_idx = bake_cells.size(); + bake_cells.write[p_idx].children[i] = child_idx; + bake_cells.resize(bake_cells.size() + 1); + bake_cells.write[child_idx].level = p_level + 1; + bake_cells.write[child_idx].x = nx / half; + bake_cells.write[child_idx].y = ny / half; + bake_cells.write[child_idx].z = nz / half; + } + + _plot_face(bake_cells[p_idx].children[i], p_level + 1, nx, ny, nz, p_vtx, p_normal, p_uv, p_material, aabb); + } + } +} + +Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) { + + Vector<Color> ret; + + if (p_image.is_null() || p_image->empty()) { + + ret.resize(bake_texture_size * bake_texture_size); + for (int i = 0; i < bake_texture_size * bake_texture_size; i++) { + ret.write[i] = p_color_add; + } + + return ret; + } + p_image = p_image->duplicate(); + + if (p_image->is_compressed()) { + p_image->decompress(); + } + p_image->convert(Image::FORMAT_RGBA8); + p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC); + + const uint8_t *r = p_image->get_data().ptr(); + ret.resize(bake_texture_size * bake_texture_size); + + for (int i = 0; i < bake_texture_size * bake_texture_size; i++) { + Color c; + c.r = (r[i * 4 + 0] / 255.0) * p_color_mul.r + p_color_add.r; + c.g = (r[i * 4 + 1] / 255.0) * p_color_mul.g + p_color_add.g; + c.b = (r[i * 4 + 2] / 255.0) * p_color_mul.b + p_color_add.b; + + c.a = r[i * 4 + 3] / 255.0; + + ret.write[i] = c; + } + + return ret; +} + +Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material) { + + //this way of obtaining materials is inaccurate and also does not support some compressed formats very well + Ref<StandardMaterial3D> mat = p_material; + + Ref<Material> material = mat; //hack for now + + if (material_cache.has(material)) { + return material_cache[material]; + } + + MaterialCache mc; + + if (mat.is_valid()) { + + Ref<Texture2D> albedo_tex = mat->get_texture(StandardMaterial3D::TEXTURE_ALBEDO); + + Ref<Image> img_albedo; + if (albedo_tex.is_valid()) { + + img_albedo = albedo_tex->get_data(); + mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative + } else { + mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive + } + + Ref<Texture2D> emission_tex = mat->get_texture(StandardMaterial3D::TEXTURE_EMISSION); + + Color emission_col = mat->get_emission(); + float emission_energy = mat->get_emission_energy(); + + Ref<Image> img_emission; + + if (emission_tex.is_valid()) { + + img_emission = emission_tex->get_data(); + } + + if (mat->get_emission_operator() == StandardMaterial3D::EMISSION_OP_ADD) { + mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy); + } else { + mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0)); + } + + } else { + Ref<Image> empty; + + mc.albedo = _get_bake_texture(empty, Color(0, 0, 0), Color(1, 1, 1)); + mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0)); + } + + material_cache[p_material] = mc; + return mc; +} + +void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) { + + for (int i = 0; i < p_mesh->get_surface_count(); i++) { + + if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) + continue; //only triangles + + Ref<Material> src_material; + + if (p_override_material.is_valid()) { + src_material = p_override_material; + } else if (i < p_materials.size() && p_materials[i].is_valid()) { + src_material = p_materials[i]; + } else { + src_material = p_mesh->surface_get_material(i); + } + MaterialCache material = _get_material_cache(src_material); + + Array a = p_mesh->surface_get_arrays(i); + + Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); + Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV]; + const Vector2 *uvr; + Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL]; + const Vector3 *nr; + Vector<int> index = a[Mesh::ARRAY_INDEX]; + + bool read_uv = false; + bool read_normals = false; + + if (uv.size()) { + + uvr = uv.ptr(); + read_uv = true; + } + + if (normals.size()) { + read_normals = true; + nr = normals.ptr(); + } + + if (index.size()) { + + int facecount = index.size() / 3; + const int *ir = index.ptr(); + + for (int j = 0; j < facecount; j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + Vector3 normal[3]; + + for (int k = 0; k < 3; k++) { + vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]); + } + + if (read_uv) { + for (int k = 0; k < 3; k++) { + uvs[k] = uvr[ir[j * 3 + k]]; + } + } + + if (read_normals) { + for (int k = 0; k < 3; k++) { + normal[k] = nr[ir[j * 3 + k]]; + } + } + + //test against original bounds + if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) + continue; + //plot + _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds); + } + + } else { + + int facecount = vertices.size() / 3; + + for (int j = 0; j < facecount; j++) { + + Vector3 vtxs[3]; + Vector2 uvs[3]; + Vector3 normal[3]; + + for (int k = 0; k < 3; k++) { + vtxs[k] = p_xform.xform(vr[j * 3 + k]); + } + + if (read_uv) { + for (int k = 0; k < 3; k++) { + uvs[k] = uvr[j * 3 + k]; + } + } + + if (read_normals) { + for (int k = 0; k < 3; k++) { + normal[k] = nr[j * 3 + k]; + } + } + + //test against original bounds + if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) + continue; + //plot face + _plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds); + } + } + } + + max_original_cells = bake_cells.size(); +} + +void Voxelizer::_sort() { + + // cells need to be sorted by level and coordinates + // it is important that level has more priority (for compute), and that Z has the least, + // given it may aid older implementations plot using GPU + + Vector<CellSort> sorted_cells; + uint32_t cell_count = bake_cells.size(); + sorted_cells.resize(cell_count); + { + + CellSort *sort_cellsp = sorted_cells.ptrw(); + const Cell *bake_cellsp = bake_cells.ptr(); + + for (uint32_t i = 0; i < cell_count; i++) { + sort_cellsp[i].x = bake_cellsp[i].x; + sort_cellsp[i].y = bake_cellsp[i].y; + sort_cellsp[i].z = bake_cellsp[i].z; + sort_cellsp[i].level = bake_cellsp[i].level; + sort_cellsp[i].index = i; + } + } + + sorted_cells.sort(); + + //verify just in case, index 0 must be level 0 + ERR_FAIL_COND(sorted_cells[0].level != 0); + + Vector<Cell> new_bake_cells; + new_bake_cells.resize(cell_count); + Vector<uint32_t> reverse_map; + + { + reverse_map.resize(cell_count); + const CellSort *sort_cellsp = sorted_cells.ptr(); + uint32_t *reverse_mapp = reverse_map.ptrw(); + + for (uint32_t i = 0; i < cell_count; i++) { + reverse_mapp[sort_cellsp[i].index] = i; + } + } + + { + + const CellSort *sort_cellsp = sorted_cells.ptr(); + const Cell *bake_cellsp = bake_cells.ptr(); + const uint32_t *reverse_mapp = reverse_map.ptr(); + Cell *new_bake_cellsp = new_bake_cells.ptrw(); + + for (uint32_t i = 0; i < cell_count; i++) { + //copy to new cell + new_bake_cellsp[i] = bake_cellsp[sort_cellsp[i].index]; + //remap children + for (uint32_t j = 0; j < 8; j++) { + if (new_bake_cellsp[i].children[j] != CHILD_EMPTY) { + new_bake_cellsp[i].children[j] = reverse_mapp[new_bake_cellsp[i].children[j]]; + } + } + } + } + + bake_cells = new_bake_cells; + sorted = true; +} + +void Voxelizer::_fixup_plot(int p_idx, int p_level) { + + if (p_level == cell_subdiv) { + + leaf_voxel_count++; + float alpha = bake_cells[p_idx].alpha; + + bake_cells.write[p_idx].albedo[0] /= alpha; + bake_cells.write[p_idx].albedo[1] /= alpha; + bake_cells.write[p_idx].albedo[2] /= alpha; + + //transfer emission to light + bake_cells.write[p_idx].emission[0] /= alpha; + bake_cells.write[p_idx].emission[1] /= alpha; + bake_cells.write[p_idx].emission[2] /= alpha; + + bake_cells.write[p_idx].normal[0] /= alpha; + bake_cells.write[p_idx].normal[1] /= alpha; + bake_cells.write[p_idx].normal[2] /= alpha; + + Vector3 n(bake_cells[p_idx].normal[0], bake_cells[p_idx].normal[1], bake_cells[p_idx].normal[2]); + if (n.length() < 0.01) { + //too much fight over normal, zero it + bake_cells.write[p_idx].normal[0] = 0; + bake_cells.write[p_idx].normal[1] = 0; + bake_cells.write[p_idx].normal[2] = 0; + } else { + n.normalize(); + bake_cells.write[p_idx].normal[0] = n.x; + bake_cells.write[p_idx].normal[1] = n.y; + bake_cells.write[p_idx].normal[2] = n.z; + } + + bake_cells.write[p_idx].alpha = 1.0; + + /*if (bake_light.size()) { + for(int i=0;i<6;i++) { + + } + }*/ + + } else { + + //go down + + bake_cells.write[p_idx].emission[0] = 0; + bake_cells.write[p_idx].emission[1] = 0; + bake_cells.write[p_idx].emission[2] = 0; + bake_cells.write[p_idx].normal[0] = 0; + bake_cells.write[p_idx].normal[1] = 0; + bake_cells.write[p_idx].normal[2] = 0; + bake_cells.write[p_idx].albedo[0] = 0; + bake_cells.write[p_idx].albedo[1] = 0; + bake_cells.write[p_idx].albedo[2] = 0; + + float alpha_average = 0; + int children_found = 0; + + for (int i = 0; i < 8; i++) { + + uint32_t child = bake_cells[p_idx].children[i]; + + if (child == CHILD_EMPTY) + continue; + + _fixup_plot(child, p_level + 1); + alpha_average += bake_cells[child].alpha; + + children_found++; + } + + bake_cells.write[p_idx].alpha = alpha_average / 8.0; + } +} + +void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) { + + sorted = false; + original_bounds = p_bounds; + cell_subdiv = p_subdiv; + bake_cells.resize(1); + material_cache.clear(); + + print_line("subdiv: " + itos(p_subdiv)); + //find out the actual real bounds, power of 2, which gets the highest subdivision + po2_bounds = p_bounds; + int longest_axis = po2_bounds.get_longest_axis_index(); + axis_cell_size[longest_axis] = 1 << cell_subdiv; + leaf_voxel_count = 0; + + for (int i = 0; i < 3; i++) { + + if (i == longest_axis) + continue; + + axis_cell_size[i] = axis_cell_size[longest_axis]; + float axis_size = po2_bounds.size[longest_axis]; + + //shrink until fit subdiv + while (axis_size / 2.0 >= po2_bounds.size[i]) { + axis_size /= 2.0; + axis_cell_size[i] >>= 1; + } + + po2_bounds.size[i] = po2_bounds.size[longest_axis]; + } + + Transform to_bounds; + to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis])); + to_bounds.origin = po2_bounds.position; + + Transform to_grid; + to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis])); + + to_cell_space = to_grid * to_bounds.affine_inverse(); + + cell_size = po2_bounds.size[longest_axis] / axis_cell_size[longest_axis]; +} + +void Voxelizer::end_bake() { + if (!sorted) { + _sort(); + } + _fixup_plot(0, 0); +} + +//create the data for visual server + +int Voxelizer::get_gi_probe_octree_depth() const { + return cell_subdiv; +} +Vector3i Voxelizer::get_giprobe_octree_size() const { + return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]); +} +int Voxelizer::get_giprobe_cell_count() const { + return bake_cells.size(); +} + +Vector<uint8_t> Voxelizer::get_giprobe_octree_cells() const { + Vector<uint8_t> data; + data.resize((8 * 4) * bake_cells.size()); //8 uint32t values + { + uint8_t *w = data.ptrw(); + uint32_t *children_cells = (uint32_t *)w; + const Cell *cells = bake_cells.ptr(); + + uint32_t cell_count = bake_cells.size(); + + for (uint32_t i = 0; i < cell_count; i++) { + + for (uint32_t j = 0; j < 8; j++) { + children_cells[i * 8 + j] = cells[i].children[j]; + } + } + } + + return data; +} +Vector<uint8_t> Voxelizer::get_giprobe_data_cells() const { + Vector<uint8_t> data; + data.resize((4 * 4) * bake_cells.size()); //8 uint32t values + { + uint8_t *w = data.ptrw(); + uint32_t *dataptr = (uint32_t *)w; + const Cell *cells = bake_cells.ptr(); + + uint32_t cell_count = bake_cells.size(); + + for (uint32_t i = 0; i < cell_count; i++) { + + { //position + + uint32_t x = cells[i].x; + uint32_t y = cells[i].y; + uint32_t z = cells[i].z; + + uint32_t position = x; + position |= y << 11; + position |= z << 21; + + dataptr[i * 4 + 0] = position; + } + + { //albedo + alpha + uint32_t rgba = uint32_t(CLAMP(cells[i].alpha * 255.0, 0, 255)) << 24; //a + rgba |= uint32_t(CLAMP(cells[i].albedo[2] * 255.0, 0, 255)) << 16; //b + rgba |= uint32_t(CLAMP(cells[i].albedo[1] * 255.0, 0, 255)) << 8; //g + rgba |= uint32_t(CLAMP(cells[i].albedo[0] * 255.0, 0, 255)); //r + + dataptr[i * 4 + 1] = rgba; + } + + { //emission, as rgbe9995 + Color emission = Color(cells[i].emission[0], cells[i].emission[1], cells[i].emission[2]); + dataptr[i * 4 + 2] = emission.to_rgbe9995(); + } + + { //normal + + Vector3 n(bake_cells[i].normal[0], bake_cells[i].normal[1], bake_cells[i].normal[2]); + n.normalize(); + + uint32_t normal = uint32_t(uint8_t(int8_t(CLAMP(n.x * 127.0, -128, 127)))); + normal |= uint32_t(uint8_t(int8_t(CLAMP(n.y * 127.0, -128, 127)))) << 8; + normal |= uint32_t(uint8_t(int8_t(CLAMP(n.z * 127.0, -128, 127)))) << 16; + + dataptr[i * 4 + 3] = normal; + } + } + } + + return data; +} + +Vector<int> Voxelizer::get_giprobe_level_cell_count() const { + uint32_t cell_count = bake_cells.size(); + const Cell *cells = bake_cells.ptr(); + Vector<int> level_count; + level_count.resize(cell_subdiv + 1); //remember, always x+1 levels for x subdivisions + { + int *w = level_count.ptrw(); + for (int i = 0; i < cell_subdiv + 1; i++) { + w[i] = 0; + } + + for (uint32_t i = 0; i < cell_count; i++) { + w[cells[i].level]++; + } + } + + return level_count; +} + +// euclidean distance computation based on: +// https://prideout.net/blog/distance_fields/ + +#define square(m_s) ((m_s) * (m_s)) +#define INF 1e20 + +/* dt of 1d function using squared distance */ +static void edt(float *f, int stride, int n) { + + float *d = (float *)alloca(sizeof(float) * n + sizeof(int) * n + sizeof(float) * (n + 1)); + int *v = (int *)&(d[n]); + float *z = (float *)&v[n]; + + int k = 0; + v[0] = 0; + z[0] = -INF; + z[1] = +INF; + for (int q = 1; q <= n - 1; q++) { + float s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]); + while (s <= z[k]) { + k--; + s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]); + } + k++; + v[k] = q; + + z[k] = s; + z[k + 1] = +INF; + } + + k = 0; + for (int q = 0; q <= n - 1; q++) { + while (z[k + 1] < q) + k++; + d[q] = square(q - v[k]) + f[v[k] * stride]; + } + + for (int i = 0; i < n; i++) { + f[i * stride] = d[i]; + } +} + +#undef square + +Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { + + Vector3i octree_size = get_giprobe_octree_size(); + + uint32_t float_count = octree_size.x * octree_size.y * octree_size.z; + float *work_memory = memnew_arr(float, float_count); + for (uint32_t i = 0; i < float_count; i++) { + work_memory[i] = INF; + } + + uint32_t y_mult = octree_size.x; + uint32_t z_mult = y_mult * octree_size.y; + + //plot solid cells + { + const Cell *cells = bake_cells.ptr(); + uint32_t cell_count = bake_cells.size(); + + for (uint32_t i = 0; i < cell_count; i++) { + + if (cells[i].level < (cell_subdiv - 1)) { + continue; //do not care about this level + } + + work_memory[cells[i].x + cells[i].y * y_mult + cells[i].z * z_mult] = 0; + } + } + + //process in each direction + + //xy->z + + for (int i = 0; i < octree_size.x; i++) { + for (int j = 0; j < octree_size.y; j++) { + edt(&work_memory[i + j * y_mult], z_mult, octree_size.z); + } + } + + //xz->y + + for (int i = 0; i < octree_size.x; i++) { + for (int j = 0; j < octree_size.z; j++) { + edt(&work_memory[i + j * z_mult], y_mult, octree_size.y); + } + } + + //yz->x + for (int i = 0; i < octree_size.y; i++) { + for (int j = 0; j < octree_size.z; j++) { + edt(&work_memory[i * y_mult + j * z_mult], 1, octree_size.x); + } + } + + Vector<uint8_t> image3d; + image3d.resize(float_count); + { + uint8_t *w = image3d.ptrw(); + for (uint32_t i = 0; i < float_count; i++) { + uint32_t d = uint32_t(Math::sqrt(work_memory[i])); + if (d == 0) { + w[i] = 0; + } else { + w[i] = MIN(d, 254) + 1; + } + } + } + + return image3d; +} + +#undef INF + +void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx) { + + if (p_level == cell_subdiv - 1) { + + Vector3 center = p_aabb.position + p_aabb.size * 0.5; + Transform xform; + xform.origin = center; + xform.basis.scale(p_aabb.size * 0.5); + p_multimesh->set_instance_transform(idx, xform); + Color col; + col = Color(bake_cells[p_idx].albedo[0], bake_cells[p_idx].albedo[1], bake_cells[p_idx].albedo[2]); + //Color col = Color(bake_cells[p_idx].emission[0], bake_cells[p_idx].emission[1], bake_cells[p_idx].emission[2]); + p_multimesh->set_instance_color(idx, col); + + idx++; + + } else { + + for (int i = 0; i < 8; i++) { + + uint32_t child = bake_cells[p_idx].children[i]; + + if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) + continue; + + AABB aabb = p_aabb; + aabb.size *= 0.5; + + if (i & 1) + aabb.position.x += aabb.size.x; + if (i & 2) + aabb.position.y += aabb.size.y; + if (i & 4) + aabb.position.z += aabb.size.z; + + _debug_mesh(bake_cells[p_idx].children[i], p_level + 1, aabb, p_multimesh, idx); + } + } +} + +Ref<MultiMesh> Voxelizer::create_debug_multimesh() { + + Ref<MultiMesh> mm; + + mm.instance(); + + mm->set_transform_format(MultiMesh::TRANSFORM_3D); + mm->set_use_colors(true); + mm->set_instance_count(leaf_voxel_count); + + Ref<ArrayMesh> mesh; + mesh.instance(); + + { + Array arr; + arr.resize(Mesh::ARRAY_MAX); + + Vector<Vector3> vertices; + Vector<Color> colors; +#define ADD_VTX(m_idx) \ + vertices.push_back(face_points[m_idx]); \ + colors.push_back(Color(1, 1, 1, 1)); + + for (int i = 0; i < 6; i++) { + + Vector3 face_points[4]; + + for (int j = 0; j < 4; j++) { + + float v[3]; + v[0] = 1.0; + v[1] = 1 - 2 * ((j >> 1) & 1); + v[2] = v[1] * (1 - 2 * (j & 1)); + + for (int k = 0; k < 3; k++) { + + if (i < 3) + face_points[j][(i + k) % 3] = v[k]; + else + face_points[3 - j][(i + k) % 3] = -v[k]; + } + } + + //tri 1 + ADD_VTX(0); + ADD_VTX(1); + ADD_VTX(2); + //tri 2 + ADD_VTX(2); + ADD_VTX(3); + ADD_VTX(0); + } + + arr[Mesh::ARRAY_VERTEX] = vertices; + arr[Mesh::ARRAY_COLOR] = colors; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr); + } + + { + Ref<StandardMaterial3D> fsm; + fsm.instance(); + fsm->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + fsm->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + fsm->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + fsm->set_albedo(Color(1, 1, 1, 1)); + + mesh->surface_set_material(0, fsm); + } + + mm->set_mesh(mesh); + + int idx = 0; + _debug_mesh(0, 0, po2_bounds, mm, idx); + + return mm; +} + +Transform Voxelizer::get_to_cell_space_xform() const { + return to_cell_space; +} +Voxelizer::Voxelizer() { + sorted = false; + color_scan_cell_width = 4; + bake_texture_size = 128; +} diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxelizer.h index 7e78a19830..1d50f1cd18 100644 --- a/scene/3d/voxel_light_baker.h +++ b/scene/3d/voxelizer.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* voxel_light_baker.h */ +/* voxelizer.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -31,27 +31,11 @@ #ifndef VOXEL_LIGHT_BAKER_H #define VOXEL_LIGHT_BAKER_H +#include "core/math/vector3i.h" #include "scene/3d/mesh_instance.h" #include "scene/resources/multimesh.h" -class VoxelLightBaker { -public: - enum DebugMode { - DEBUG_ALBEDO, - DEBUG_LIGHT - }; - - enum BakeQuality { - BAKE_QUALITY_LOW, - BAKE_QUALITY_MEDIUM, - BAKE_QUALITY_HIGH - }; - - enum BakeMode { - BAKE_MODE_CONE_TRACE, - BAKE_MODE_RAY_TRACE, - }; - +class Voxelizer { private: enum { CHILD_EMPTY = 0xFFFFFFFF @@ -66,7 +50,10 @@ private: float normal[3]; uint32_t used_sides; float alpha; //used for upsampling - int level; + uint16_t x; + uint16_t y; + uint16_t z; + uint16_t level; Cell() { for (int i = 0; i < 8; i++) { @@ -80,6 +67,7 @@ private: } alpha = 0; used_sides = 0; + x = y = z = 0; level = 0; } }; @@ -87,27 +75,24 @@ private: Vector<Cell> bake_cells; int cell_subdiv; - struct Light { - int x, y, z; - float accum[6][3]; //rgb anisotropic - float direct_accum[6][3]; //for direct bake - int next_leaf; - Light() { - x = y = z = 0; - for (int i = 0; i < 6; i++) { - for (int j = 0; j < 3; j++) { - accum[i][j] = 0; - direct_accum[i][j] = 0; - } - } - next_leaf = 0; + struct CellSort { + union { + struct { + uint64_t z : 16; + uint64_t y : 16; + uint64_t x : 16; + uint64_t level : 16; + }; + uint64_t key; + }; + + int32_t index; + + _FORCE_INLINE_ bool operator<(const CellSort &p_cell_sort) const { + return key < p_cell_sort.key; } }; - int first_leaf; - - Vector<Light> bake_light; - struct MaterialCache { //128x128 textures Vector<Color> albedo; @@ -115,9 +100,6 @@ private: }; Map<Ref<Material>, MaterialCache> material_cache; - int leaf_voxel_count; - bool direct_lights_baked; - AABB original_bounds; AABB po2_bounds; int axis_cell_size[3]; @@ -127,65 +109,37 @@ private: int color_scan_cell_width; int bake_texture_size; float cell_size; - float propagation; - float energy; - - BakeQuality bake_quality; - BakeMode bake_mode; int max_original_cells; - - void _init_light_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, uint32_t p_parent); + int leaf_voxel_count; Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add); MaterialCache _get_material_cache(Ref<Material> p_material); void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb); void _fixup_plot(int p_idx, int p_level); - void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, DebugMode p_mode); - void _check_init_light(); - - uint32_t _find_cell_at_pos(const Cell *cells, int x, int y, int z); + void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx); - struct LightMap { - Vector3 light; - Vector3 pos; - Vector3 normal; - }; - - void _plot_triangle(Vector2 *vertices, Vector3 *positions, Vector3 *normals, LightMap *pixels, int width, int height); - - _FORCE_INLINE_ void _sample_baked_octree_filtered_and_anisotropic(const Vector3 &p_posf, const Vector3 &p_direction, float p_level, Vector3 &r_color, float &r_alpha); - _FORCE_INLINE_ Vector3 _voxel_cone_trace(const Vector3 &p_pos, const Vector3 &p_normal, float p_aperture); - _FORCE_INLINE_ Vector3 _compute_pixel_light_at_pos(const Vector3 &p_pos, const Vector3 &p_normal); - _FORCE_INLINE_ Vector3 _compute_ray_trace_at_pos(const Vector3 &p_pos, const Vector3 &p_normal); - - void _lightmap_bake_point(uint32_t p_x, LightMap *p_line); + bool sorted; + void _sort(); public: void begin_bake(int p_subdiv, const AABB &p_bounds); void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material); - void begin_bake_light(BakeQuality p_quality = BAKE_QUALITY_MEDIUM, BakeMode p_bake_mode = BAKE_MODE_CONE_TRACE, float p_propagation = 0.85, float p_energy = 1); - void plot_light_directional(const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_energy, bool p_direct); - void plot_light_omni(const Vector3 &p_pos, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, bool p_direct); - void plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axis, const Color &p_color, float p_energy, float p_indirect_energy, float p_radius, float p_attenutation, float p_spot_angle, float p_spot_attenuation, bool p_direct); void end_bake(); - struct LightMapData { - int width; - int height; - PoolVector<float> light; - }; - - Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL); + int get_gi_probe_octree_depth() const; + Vector3i get_giprobe_octree_size() const; + int get_giprobe_cell_count() const; + Vector<uint8_t> get_giprobe_octree_cells() const; + Vector<uint8_t> get_giprobe_data_cells() const; + Vector<int> get_giprobe_level_cell_count() const; + Vector<uint8_t> get_sdf_3d_image() const; - PoolVector<int> create_gi_probe_data(); - Ref<MultiMesh> create_debug_multimesh(DebugMode p_mode = DEBUG_ALBEDO); - PoolVector<uint8_t> create_capture_octree(int p_subdiv); + Ref<MultiMesh> create_debug_multimesh(); - float get_cell_size() const; Transform get_to_cell_space_xform() const; - VoxelLightBaker(); + Voxelizer(); }; #endif // VOXEL_LIGHT_BAKER_H diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index c8d7382e81..83a7243906 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -43,12 +43,25 @@ void WorldEnvironment::_notification(int p_what) { add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } + if (camera_effects.is_valid()) { + if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding."); + } + get_viewport()->find_world()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } + } else if (p_what == Spatial::NOTIFICATION_EXIT_WORLD || p_what == Spatial::NOTIFICATION_EXIT_TREE) { if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) { get_viewport()->find_world()->set_environment(Ref<Environment>()); remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id())); } + + if (camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { + get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } } } @@ -77,13 +90,38 @@ Ref<Environment> WorldEnvironment::get_environment() const { return environment; } +void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) { + + if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) { + get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>()); + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + //clean up + } + + camera_effects = p_camera_effects; + if (is_inside_tree() && camera_effects.is_valid()) { + if (get_viewport()->find_world()->get_camera_effects().is_valid()) { + WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding."); + } + get_viewport()->find_world()->set_camera_effects(camera_effects); + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id())); + } + + update_configuration_warning(); +} + +Ref<CameraEffects> WorldEnvironment::get_camera_effects() const { + + return camera_effects; +} + String WorldEnvironment::get_configuration_warning() const { if (!environment.is_valid()) { return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect."); } - if (/*!is_visible_in_tree() ||*/ !is_inside_tree()) + if (!is_inside_tree()) return String(); List<Node *> nodes; @@ -93,11 +131,6 @@ String WorldEnvironment::get_configuration_warning() const { return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); } - // Commenting this warning for now, I think it makes no sense. If anyone can figure out what its supposed to do, feedback welcome. Else it should be deprecated. - //if (environment.is_valid() && get_viewport() && !get_viewport()->get_camera() && environment->get_background() != Environment::BG_CANVAS) { - // return TTR("This WorldEnvironment is ignored. Either add a Camera (for 3D scenes) or set this environment's Background Mode to Canvas (for 2D scenes)."); - //} - return String(); } @@ -106,6 +139,10 @@ void WorldEnvironment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_environment", "env"), &WorldEnvironment::set_environment); ClassDB::bind_method(D_METHOD("get_environment"), &WorldEnvironment::get_environment); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); + + ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &WorldEnvironment::set_camera_effects); + ClassDB::bind_method(D_METHOD("get_camera_effects"), &WorldEnvironment::get_camera_effects); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); } WorldEnvironment::WorldEnvironment() { diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 6e89fe8517..0c590bfc07 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -38,6 +38,7 @@ class WorldEnvironment : public Node { GDCLASS(WorldEnvironment, Node); Ref<Environment> environment; + Ref<CameraEffects> camera_effects; protected: void _notification(int p_what); @@ -47,6 +48,9 @@ public: void set_environment(const Ref<Environment> &p_environment); Ref<Environment> get_environment() const; + void set_camera_effects(const Ref<CameraEffects> &p_camera_effects); + Ref<CameraEffects> get_camera_effects() const; + String get_configuration_warning() const; WorldEnvironment(); diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp index 0f55682427..3502f5e961 100644 --- a/scene/animation/animation_blend_space_1d.cpp +++ b/scene/animation/animation_blend_space_1d.cpp @@ -31,7 +31,7 @@ #include "animation_blend_space_1d.h" void AnimationNodeBlendSpace1D::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, blend_position)); + r_list->push_back(PropertyInfo(Variant::FLOAT, blend_position)); } Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName &p_parameter) const { return 0; @@ -79,16 +79,14 @@ void AnimationNodeBlendSpace1D::_bind_methods() { ClassDB::bind_method(D_METHOD("_add_blend_point", "index", "node"), &AnimationNodeBlendSpace1D::_add_blend_point); - ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace1D::_tree_changed); - for (int i = 0; i < MAX_BLEND_POINTS; i++) { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "blend_point_" + itos(i) + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_add_blend_point", "get_blend_point_node", i); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i); } - ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "value_label", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_value_label", "get_value_label"); } @@ -118,7 +116,7 @@ void AnimationNodeBlendSpace1D::add_blend_point(const Ref<AnimationRootNode> &p_ blend_points[p_at_index].node = p_node; blend_points[p_at_index].position = p_position; - blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); blend_points_used++; emit_signal("tree_changed"); @@ -135,11 +133,11 @@ void AnimationNodeBlendSpace1D::set_blend_point_node(int p_point, const Ref<Anim ERR_FAIL_COND(p_node.is_null()); if (blend_points[p_point].node.is_valid()) { - blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); + blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed)); } blend_points[p_point].node = p_node; - blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); emit_signal("tree_changed"); } @@ -158,7 +156,7 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) { ERR_FAIL_INDEX(p_point, blend_points_used); ERR_FAIL_COND(blend_points[p_point].node.is_null()); - blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); + blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace1D::_tree_changed)); for (int i = p_point; i < blend_points_used - 1; i++) { blend_points[i] = blend_points[i + 1]; diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp index d749959377..638531df41 100644 --- a/scene/animation/animation_blend_space_2d.cpp +++ b/scene/animation/animation_blend_space_2d.cpp @@ -34,7 +34,7 @@ void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const { r_list->push_back(PropertyInfo(Variant::VECTOR2, blend_position)); r_list->push_back(PropertyInfo(Variant::INT, closest, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, length_internal, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, length_internal, PROPERTY_HINT_NONE, "", 0)); } Variant AnimationNodeBlendSpace2D::get_parameter_default_value(const StringName &p_parameter) const { if (p_parameter == closest) { @@ -77,7 +77,7 @@ void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_ blend_points[p_at_index].node = p_node; blend_points[p_at_index].position = p_position; - blend_points[p_at_index].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_at_index].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); blend_points_used++; _queue_auto_triangles(); @@ -95,10 +95,10 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim ERR_FAIL_COND(p_node.is_null()); if (blend_points[p_point].node.is_valid()) { - blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); + blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed)); } blend_points[p_point].node = p_node; - blend_points[p_point].node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + blend_points[p_point].node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); emit_signal("tree_changed"); } @@ -114,7 +114,7 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) { ERR_FAIL_INDEX(p_point, blend_points_used); ERR_FAIL_COND(blend_points[p_point].node.is_null()); - blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed"); + blend_points[p_point].node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendSpace2D::_tree_changed)); for (int i = 0; i < triangles.size(); i++) { bool erase = false; @@ -640,7 +640,6 @@ void AnimationNodeBlendSpace2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &AnimationNodeBlendSpace2D::set_blend_mode); ClassDB::bind_method(D_METHOD("get_blend_mode"), &AnimationNodeBlendSpace2D::get_blend_mode); - ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendSpace2D::_tree_changed); ClassDB::bind_method(D_METHOD("_update_triangles"), &AnimationNodeBlendSpace2D::_update_triangles); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_auto_triangles", "get_auto_triangles"); @@ -650,7 +649,7 @@ void AnimationNodeBlendSpace2D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::VECTOR2, "blend_point_" + itos(i) + "/pos", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_blend_point_position", "get_blend_point_position", i); } - ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_triangles", "_get_triangles"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "triangles", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_triangles", "_get_triangles"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "min_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_min_space", "get_min_space"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "max_space", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_space", "get_max_space"); diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 5c284cb483..8ba7a38628 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -44,7 +44,7 @@ StringName AnimationNodeAnimation::get_animation() const { Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = NULL; void AnimationNodeAnimation::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0)); } void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const { @@ -126,7 +126,7 @@ void AnimationNodeAnimation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimationNodeAnimation::set_animation); ClassDB::bind_method(D_METHOD("get_animation"), &AnimationNodeAnimation::get_animation); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "animation"), "set_animation", "get_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); } AnimationNodeAnimation::AnimationNodeAnimation() { @@ -140,9 +140,9 @@ AnimationNodeAnimation::AnimationNodeAnimation() { void AnimationNodeOneShot::get_parameter_list(List<PropertyInfo> *r_list) const { r_list->push_back(PropertyInfo(Variant::BOOL, active)); r_list->push_back(PropertyInfo(Variant::BOOL, prev_active, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, remaining, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, time_to_restart, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, remaining, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, time_to_restart, PROPERTY_HINT_NONE, "", 0)); } Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_parameter) const { @@ -339,14 +339,14 @@ void AnimationNodeOneShot::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeOneShot::set_use_sync); ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeOneShot::is_using_sync); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time"); ADD_GROUP("autorestart_", "Auto Restart"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autorestart"), "set_autorestart", "has_autorestart"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_delay", "get_autorestart_delay"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "autorestart_random_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_random_delay", "get_autorestart_random_delay"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_delay", "get_autorestart_delay"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_random_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_random_delay", "get_autorestart_random_delay"); ADD_GROUP("", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync"); @@ -379,7 +379,7 @@ AnimationNodeOneShot::AnimationNodeOneShot() { //////////////////////////////////////////////// void AnimationNodeAdd2::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01")); + r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01")); } Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_parameter) const { return 0; @@ -431,7 +431,7 @@ AnimationNodeAdd2::AnimationNodeAdd2() { //////////////////////////////////////////////// void AnimationNodeAdd3::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01")); + r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01")); } Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_parameter) const { return 0; @@ -484,7 +484,7 @@ AnimationNodeAdd3::AnimationNodeAdd3() { ///////////////////////////////////////////// void AnimationNodeBlend2::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01")); + r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01")); } Variant AnimationNodeBlend2::get_parameter_default_value(const StringName &p_parameter) const { return 0; //for blend amount @@ -535,7 +535,7 @@ AnimationNodeBlend2::AnimationNodeBlend2() { ////////////////////////////////////// void AnimationNodeBlend3::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01")); + r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01")); } Variant AnimationNodeBlend3::get_parameter_default_value(const StringName &p_parameter) const { return 0; //for blend amount @@ -583,7 +583,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() { ///////////////////////////////// void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater")); + r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater")); } Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const { return 1.0; //initial timescale @@ -613,7 +613,7 @@ AnimationNodeTimeScale::AnimationNodeTimeScale() { //////////////////////////////////// void AnimationNodeTimeSeek::get_parameter_list(List<PropertyInfo> *r_list) const { - r_list->push_back(PropertyInfo(Variant::REAL, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater")); + r_list->push_back(PropertyInfo(Variant::FLOAT, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater")); } Variant AnimationNodeTimeSeek::get_parameter_default_value(const StringName &p_parameter) const { return 1.0; //initial timescale @@ -661,8 +661,8 @@ void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) con r_list->push_back(PropertyInfo(Variant::INT, current, PROPERTY_HINT_ENUM, anims)); r_list->push_back(PropertyInfo(Variant::INT, prev_current, PROPERTY_HINT_NONE, "", 0)); r_list->push_back(PropertyInfo(Variant::INT, prev, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, time, PROPERTY_HINT_NONE, "", 0)); - r_list->push_back(PropertyInfo(Variant::REAL, prev_xfading, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0)); + r_list->push_back(PropertyInfo(Variant::FLOAT, prev_xfading, PROPERTY_HINT_NONE, "", 0)); } Variant AnimationNodeTransition::get_parameter_default_value(const StringName &p_parameter) const { if (p_parameter == time || p_parameter == prev_xfading) { @@ -829,7 +829,7 @@ void AnimationNodeTransition::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cross_fade_time"), &AnimationNodeTransition::get_cross_fade_time); ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_enabled_inputs", "get_enabled_inputs"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time"); for (int i = 0; i < MAX_INPUTS; i++) { ADD_PROPERTYI(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_input_caption", "get_input_caption", i); @@ -884,8 +884,8 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod emit_changed(); emit_signal("tree_changed"); - p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); - p_node->connect("changed", this, "_node_changed", varray(p_name), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); + p_node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_name), CONNECT_REFERENCE_COUNTED); } Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) const { @@ -947,8 +947,8 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) { { Ref<AnimationNode> node = nodes[p_name].node; - node->disconnect("tree_changed", this, "_tree_changed"); - node->disconnect("changed", this, "_node_changed"); + node->disconnect("tree_changed", callable_mp(this, &AnimationNodeBlendTree::_tree_changed)); + node->disconnect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed)); } nodes.erase(p_name); @@ -973,7 +973,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); ERR_FAIL_COND(p_new_name == SceneStringNames::get_singleton()->output); - nodes[p_name].node->disconnect("changed", this, "_node_changed"); + nodes[p_name].node->disconnect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed)); nodes[p_new_name] = nodes[p_name]; nodes.erase(p_name); @@ -988,7 +988,7 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN } } //connection must be done with new name - nodes[p_new_name].node->connect("changed", this, "_node_changed", varray(p_new_name), CONNECT_REFERENCE_COUNTED); + nodes[p_new_name].node->connect("changed", callable_mp(this, &AnimationNodeBlendTree::_node_changed), varray(p_new_name), CONNECT_REFERENCE_COUNTED); emit_signal("tree_changed"); } @@ -1230,9 +1230,6 @@ void AnimationNodeBlendTree::_bind_methods() { ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeBlendTree::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeBlendTree::get_graph_offset); - ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeBlendTree::_tree_changed); - ClassDB::bind_method(D_METHOD("_node_changed", "node"), &AnimationNodeBlendTree::_node_changed); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset"); BIND_CONSTANT(CONNECTION_OK); diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp index 8d1ffb43cc..9ed8155bdc 100644 --- a/scene/animation/animation_cache.cpp +++ b/scene/animation/animation_cache.cpp @@ -56,7 +56,7 @@ void AnimationCache::_clear_cache() { while (connected_nodes.size()) { - connected_nodes.front()->get()->disconnect("tree_exiting", this, "_node_exit_tree"); + connected_nodes.front()->get()->disconnect("tree_exiting", callable_mp(this, &AnimationCache::_node_exit_tree)); connected_nodes.erase(connected_nodes.front()); } path_cache.clear(); @@ -174,7 +174,7 @@ void AnimationCache::_update_cache() { if (!connected_nodes.has(path.node)) { connected_nodes.insert(path.node); - path.node->connect("tree_exiting", this, "_node_exit_tree", Node::make_binds(path.node), CONNECT_ONESHOT); + path.node->connect("tree_exiting", callable_mp(this, &AnimationCache::_node_exit_tree), Node::make_binds(path.node), CONNECT_ONESHOT); } } @@ -218,7 +218,7 @@ void AnimationCache::set_track_value(int p_idx, const Variant &p_value) { p.object->set_indexed(p.subpath, p_value); } -void AnimationCache::call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +void AnimationCache::call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (cache_dirty) _update_cache(); @@ -283,7 +283,7 @@ void AnimationCache::set_all(float p_time, float p_delta) { Vector<Variant> args = animation->method_track_get_params(i, E->get()); StringName name = animation->method_track_get_name(i, E->get()); - Variant::CallError err; + Callable::CallError err; if (!args.size()) { @@ -313,18 +313,15 @@ void AnimationCache::set_animation(const Ref<Animation> &p_animation) { _clear_cache(); if (animation.is_valid()) - animation->disconnect("changed", this, "_animation_changed"); + animation->disconnect("changed", callable_mp(this, &AnimationCache::_animation_changed)); animation = p_animation; if (animation.is_valid()) - animation->connect("changed", this, "_animation_changed"); + animation->connect("changed", callable_mp(this, &AnimationCache::_animation_changed)); } void AnimationCache::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_node_exit_tree"), &AnimationCache::_node_exit_tree); - ClassDB::bind_method(D_METHOD("_animation_changed"), &AnimationCache::_animation_changed); } void AnimationCache::set_root(Node *p_root) { diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h index 26ad9dfee5..e73b9e2498 100644 --- a/scene/animation/animation_cache.h +++ b/scene/animation/animation_cache.h @@ -79,7 +79,7 @@ protected: public: void set_track_transform(int p_idx, const Transform &p_transform); void set_track_value(int p_idx, const Variant &p_value); - void call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + void call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); void set_all(float p_time, float p_delta = 0); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 59d0d9e87f..fbd9a2aa7d 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -120,8 +120,8 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_condition"), "set_advance_condition", "get_advance_condition"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,32,1"), "set_priority", "get_priority"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); @@ -562,7 +562,7 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation emit_changed(); emit_signal("tree_changed"); - p_node->connect("tree_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); } Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const { @@ -611,7 +611,7 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) { ERR_FAIL_COND(node.is_null()); - node->disconnect("tree_changed", this, "_tree_changed"); + node->disconnect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); } states.erase(p_name); @@ -619,7 +619,7 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) { for (int i = 0; i < transitions.size(); i++) { if (transitions[i].from == p_name || transitions[i].to == p_name) { - transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed"); + transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); transitions.remove(i); i--; } @@ -722,7 +722,7 @@ void AnimationNodeStateMachine::add_transition(const StringName &p_from, const S tr.to = p_to; tr.transition = p_transition; - tr.transition->connect("advance_condition_changed", this, "_tree_changed", varray(), CONNECT_REFERENCE_COUNTED); + tr.transition->connect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), varray(), CONNECT_REFERENCE_COUNTED); transitions.push_back(tr); } @@ -750,7 +750,7 @@ void AnimationNodeStateMachine::remove_transition(const StringName &p_from, cons for (int i = 0; i < transitions.size(); i++) { if (transitions[i].from == p_from && transitions[i].to == p_to) { - transitions.write[i].transition->disconnect("advance_condition_changed", this, "_tree_changed"); + transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); transitions.remove(i); return; } @@ -764,7 +764,7 @@ void AnimationNodeStateMachine::remove_transition(const StringName &p_from, cons void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) { ERR_FAIL_INDEX(p_transition, transitions.size()); - transitions.write[p_transition].transition->disconnect("advance_condition_changed", this, "_tree_changed"); + transitions.write[p_transition].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed)); transitions.remove(p_transition); /*if (playing) { path.clear(); @@ -926,8 +926,8 @@ void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) c } p_list->push_back(PropertyInfo(Variant::ARRAY, "transitions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::STRING, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::STRING, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING_NAME, "start_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::STRING_NAME, "end_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } @@ -975,8 +975,6 @@ void AnimationNodeStateMachine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset); - - ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationNodeStateMachine::_tree_changed); } AnimationNodeStateMachine::AnimationNodeStateMachine() { diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 7ec7037dd7..587485669e 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -106,7 +106,7 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const { } else if (name.begins_with("anims/")) { String which = name.get_slicec('/', 1); - r_ret = get_animation(which).get_ref_ptr(); + r_ret = get_animation(which); } else if (name.begins_with("next/")) { @@ -249,7 +249,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { Vector<StringName> leftover_path; Node *child = parent->get_node_and_resource(a->track_get_path(i), resource, leftover_path); ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node - uint32_t id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id(); + ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id(); int bone_idx = -1; if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton>(child)) { @@ -263,8 +263,8 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) { } { - if (!child->is_connected("tree_exiting", this, "_node_removed")) - child->connect("tree_exiting", this, "_node_removed", make_binds(child), CONNECT_ONESHOT); + if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) + child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed), make_binds(child), CONNECT_ONESHOT); } TrackNodeCacheKey key; @@ -1007,12 +1007,12 @@ void AnimationPlayer::remove_animation(const StringName &p_name) { void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) { - Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed", varray(), CONNECT_REFERENCE_COUNTED); + Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed), varray(), CONNECT_REFERENCE_COUNTED); } void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) { - Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, this, "_animation_changed"); + Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed)); } void AnimationPlayer::rename_animation(const StringName &p_name, const StringName &p_new_name) { @@ -1129,8 +1129,8 @@ void AnimationPlayer::queue(const StringName &p_name) { queued.push_back(p_name); } -PoolVector<String> AnimationPlayer::get_queue() { - PoolVector<String> ret; +Vector<String> AnimationPlayer::get_queue() { + Vector<String> ret; for (List<StringName>::Element *E = queued.front(); E; E = E->next()) { ret.push_back(E->get()); } @@ -1619,10 +1619,6 @@ void AnimationPlayer::restore_animated_values(const AnimatedValuesBackup &p_back #endif void AnimationPlayer::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayer::_node_removed); - ClassDB::bind_method(D_METHOD("_animation_changed"), &AnimationPlayer::_animation_changed); - ClassDB::bind_method(D_METHOD("add_animation", "name", "animation"), &AnimationPlayer::add_animation); ClassDB::bind_method(D_METHOD("remove_animation", "name"), &AnimationPlayer::remove_animation); ClassDB::bind_method(D_METHOD("rename_animation", "name", "newname"), &AnimationPlayer::rename_animation); @@ -1682,22 +1678,22 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER), "set_current_animation", "get_current_animation"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "assigned_animation", PROPERTY_HINT_NONE, "", 0), "set_assigned_animation", "get_assigned_animation"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_autoplay", "get_autoplay"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_length", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "current_animation", PROPERTY_HINT_ENUM, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ANIMATE_AS_TRIGGER), "set_current_animation", "get_current_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "assigned_animation", PROPERTY_HINT_NONE, "", 0), "set_assigned_animation", "get_assigned_animation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "autoplay", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_autoplay", "get_autoplay"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_length", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "current_animation_position", PROPERTY_HINT_NONE, "", 0), "", "get_current_animation_position"); ADD_GROUP("Playback Options", "playback_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_animation_process_mode", "get_animation_process_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playback_active", PROPERTY_HINT_NONE, "", 0), "set_active", "is_active"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "method_call_mode", PROPERTY_HINT_ENUM, "Deferred,Immediate"), "set_method_call_mode", "get_method_call_mode"); - ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "anim_name"))); - ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name"))); - ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING, "anim_name"))); + ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name"))); + ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING_NAME, "old_name"), PropertyInfo(Variant::STRING_NAME, "new_name"))); + ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name"))); ADD_SIGNAL(MethodInfo("caches_cleared")); BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 06f762e63e..24f60363ed 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -159,17 +159,15 @@ private: struct TrackNodeCacheKey { - uint32_t id; + ObjectID id; int bone_idx; inline bool operator<(const TrackNodeCacheKey &p_right) const { - if (id < p_right.id) - return true; - else if (id > p_right.id) - return false; - else + if (id == p_right.id) return bone_idx < p_right.bone_idx; + else + return id < p_right.id; } }; @@ -266,11 +264,11 @@ private: void _stop_playing_caches(); // bind helpers - PoolVector<String> _get_animation_list() const { + Vector<String> _get_animation_list() const { List<StringName> animations; get_animation_list(&animations); - PoolVector<String> ret; + Vector<String> ret; while (animations.size()) { ret.push_back(animations.front()->get()); @@ -318,7 +316,7 @@ public: void play(const StringName &p_name = StringName(), float p_custom_blend = -1, float p_custom_scale = 1.0, bool p_from_end = false); void play_backwards(const StringName &p_name = StringName(), float p_custom_blend = -1); void queue(const StringName &p_name); - PoolVector<String> get_queue(); + Vector<String> get_queue(); void clear_queue(); void stop(bool p_reset = true); bool is_playing() const; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index c28f8dc824..95afd74ee5 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -433,13 +433,13 @@ void AnimationNode::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::ARRAY, "get_parameter_list")); BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_child_by_name", PropertyInfo(Variant::STRING, "name"))); { - MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING, "name")); + MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING_NAME, "name")); mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT; BIND_VMETHOD(mi); } - BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::REAL, "time"), PropertyInfo(Variant::BOOL, "seek"))); + BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::FLOAT, "time"), PropertyInfo(Variant::BOOL, "seek"))); BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption")); - BIND_VMETHOD(MethodInfo(Variant::STRING, "has_filter")); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_filter")); ADD_SIGNAL(MethodInfo("removed_from_graph")); @@ -463,13 +463,13 @@ AnimationNode::AnimationNode() { void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) { if (root.is_valid()) { - root->disconnect("tree_changed", this, "_tree_changed"); + root->disconnect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed)); } root = p_root; if (root.is_valid()) { - root->connect("tree_changed", this, "_tree_changed"); + root->connect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed)); } properties_dirty = true; @@ -582,8 +582,8 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { continue; } - if (!child->is_connected("tree_exited", this, "_node_removed")) { - child->connect("tree_exited", this, "_node_removed", varray(child)); + if (!child->is_connected("tree_exited", callable_mp(this, &AnimationTree::_node_removed))) { + child->connect("tree_exited", callable_mp(this, &AnimationTree::_node_removed), varray(child)); } switch (track_type) { @@ -767,7 +767,7 @@ void AnimationTree::_process_graph(float p_delta) { AnimationPlayer *player = Object::cast_to<AnimationPlayer>(get_node(animation_player)); - ObjectID current_animation_player = 0; + ObjectID current_animation_player; if (player) { current_animation_player = player->get_instance_id(); @@ -775,15 +775,15 @@ void AnimationTree::_process_graph(float p_delta) { if (last_animation_player != current_animation_player) { - if (last_animation_player) { + if (last_animation_player.is_valid()) { Object *old_player = ObjectDB::get_instance(last_animation_player); if (old_player) { - old_player->disconnect("caches_cleared", this, "_clear_caches"); + old_player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); } } if (player) { - player->connect("caches_cleared", this, "_clear_caches"); + player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); } last_animation_player = current_animation_player; @@ -1296,19 +1296,19 @@ void AnimationTree::_notification(int p_what) { if (p_what == NOTIFICATION_EXIT_TREE) { _clear_caches(); - if (last_animation_player) { + if (last_animation_player.is_valid()) { Object *player = ObjectDB::get_instance(last_animation_player); if (player) { - player->disconnect("caches_cleared", this, "_clear_caches"); + player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); } } } else if (p_what == NOTIFICATION_ENTER_TREE) { - if (last_animation_player) { + if (last_animation_player.is_valid()) { Object *player = ObjectDB::get_instance(last_animation_player); if (player) { - player->connect("caches_cleared", this, "_clear_caches"); + player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); } } } @@ -1553,16 +1553,12 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_root_motion_transform"), &AnimationTree::get_root_motion_transform); - ClassDB::bind_method(D_METHOD("_tree_changed"), &AnimationTree::_tree_changed); ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties); ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter); ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance); - ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed); - ClassDB::bind_method(D_METHOD("_clear_caches"), &AnimationTree::_clear_caches); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode"), "set_tree_root", "get_tree_root"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_animation_player", "get_animation_player"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); @@ -1584,7 +1580,6 @@ AnimationTree::AnimationTree() { process_pass = 1; started = true; properties_dirty = true; - last_animation_player = 0; } AnimationTree::~AnimationTree() { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 0a8dc8109f..8769e2c61d 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -187,7 +187,6 @@ private: setup_pass = 0; process_pass = 0; object = NULL; - object_id = 0; } virtual ~TrackCache() {} }; diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp deleted file mode 100644 index c7362391dc..0000000000 --- a/scene/animation/animation_tree_player.cpp +++ /dev/null @@ -1,1866 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "animation_tree_player.h" -#include "animation_player.h" - -#include "scene/scene_string_names.h" - -void AnimationTreePlayer::set_animation_process_mode(AnimationProcessMode p_mode) { - - if (animation_process_mode == p_mode) - return; - - bool pr = processing; - if (pr) - _set_process(false); - animation_process_mode = p_mode; - if (pr) - _set_process(true); -} - -AnimationTreePlayer::AnimationProcessMode AnimationTreePlayer::get_animation_process_mode() const { - - return animation_process_mode; -} - -void AnimationTreePlayer::_set_process(bool p_process, bool p_force) { - if (processing == p_process && !p_force) - return; - - switch (animation_process_mode) { - - case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break; - case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break; - } - - processing = p_process; -} - -bool AnimationTreePlayer::_set(const StringName &p_name, const Variant &p_value) { - - if (String(p_name) == "base_path") { - set_base_path(p_value); - return true; - } - - if (String(p_name) == "master_player") { - set_master_player(p_value); - return true; - } - - if (String(p_name) == SceneStringNames::get_singleton()->playback_active) { - set_active(p_value); - return true; - } - - if (String(p_name) != "data") - return false; - - Dictionary data = p_value; - - Array nodes = data.get_valid("nodes"); - - for (int i = 0; i < nodes.size(); i++) { - - Dictionary node = nodes[i]; - - StringName id = node.get_valid("id"); - Point2 pos = node.get_valid("position"); - - NodeType nt = NODE_MAX; - String type = node.get_valid("type"); - - if (type == "output") - nt = NODE_OUTPUT; - else if (type == "animation") - nt = NODE_ANIMATION; - else if (type == "oneshot") - nt = NODE_ONESHOT; - else if (type == "mix") - nt = NODE_MIX; - else if (type == "blend2") - nt = NODE_BLEND2; - else if (type == "blend3") - nt = NODE_BLEND3; - else if (type == "blend4") - nt = NODE_BLEND4; - else if (type == "timescale") - nt = NODE_TIMESCALE; - else if (type == "timeseek") - nt = NODE_TIMESEEK; - else if (type == "transition") - nt = NODE_TRANSITION; - - ERR_FAIL_COND_V(nt == NODE_MAX, false); - - if (nt != NODE_OUTPUT) - add_node(nt, id); - node_set_position(id, pos); - - switch (nt) { - case NODE_OUTPUT: { - - } break; - case NODE_ANIMATION: { - - if (node.has("from")) - animation_node_set_master_animation(id, node.get_valid("from")); - else - animation_node_set_animation(id, node.get_valid("animation")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - animation_node_set_filter_path(id, filters[j], true); - } - } break; - case NODE_ONESHOT: { - - oneshot_node_set_fadein_time(id, node.get_valid("fade_in")); - oneshot_node_set_fadeout_time(id, node.get_valid("fade_out")); - oneshot_node_set_mix_mode(id, node.get_valid("mix")); - oneshot_node_set_autorestart(id, node.get_valid("autorestart")); - oneshot_node_set_autorestart_delay(id, node.get_valid("autorestart_delay")); - oneshot_node_set_autorestart_random_delay(id, node.get_valid("autorestart_random_delay")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - oneshot_node_set_filter_path(id, filters[j], true); - } - - } break; - case NODE_MIX: { - mix_node_set_amount(id, node.get_valid("mix")); - } break; - case NODE_BLEND2: { - blend2_node_set_amount(id, node.get_valid("blend")); - Array filters = node.get_valid("filter"); - for (int j = 0; j < filters.size(); j++) { - - blend2_node_set_filter_path(id, filters[j], true); - } - } break; - case NODE_BLEND3: { - blend3_node_set_amount(id, node.get_valid("blend")); - } break; - case NODE_BLEND4: { - blend4_node_set_amount(id, node.get_valid("blend")); - } break; - case NODE_TIMESCALE: { - timescale_node_set_scale(id, node.get_valid("scale")); - } break; - case NODE_TIMESEEK: { - } break; - case NODE_TRANSITION: { - - transition_node_set_xfade_time(id, node.get_valid("xfade")); - - Array transitions = node.get_valid("transitions"); - transition_node_set_input_count(id, transitions.size()); - - for (int x = 0; x < transitions.size(); x++) { - - Dictionary d = transitions[x]; - bool aa = d.get_valid("auto_advance"); - transition_node_set_input_auto_advance(id, x, aa); - } - - } break; - default: { - }; - } - } - - Array connections = data.get_valid("connections"); - ERR_FAIL_COND_V(connections.size() % 3, false); - - int cc = connections.size() / 3; - - for (int i = 0; i < cc; i++) { - - StringName src = connections[i * 3 + 0]; - StringName dst = connections[i * 3 + 1]; - int dst_in = connections[i * 3 + 2]; - connect_nodes(src, dst, dst_in); - } - - set_active(data.get_valid("active")); - set_master_player(data.get_valid("master")); - - return true; -} - -bool AnimationTreePlayer::_get(const StringName &p_name, Variant &r_ret) const { - - if (String(p_name) == "base_path") { - r_ret = base_path; - return true; - } - - if (String(p_name) == "master_player") { - r_ret = master; - return true; - } - - if (String(p_name) == "playback/active") { - r_ret = is_active(); - return true; - } - - if (String(p_name) != "data") - return false; - - Dictionary data; - - Array nodes; - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *n = node_map[E->key()]; - - Dictionary node; - node["id"] = E->key(); - node["position"] = n->pos; - - switch (n->type) { - case NODE_OUTPUT: node["type"] = "output"; break; - case NODE_ANIMATION: node["type"] = "animation"; break; - case NODE_ONESHOT: node["type"] = "oneshot"; break; - case NODE_MIX: node["type"] = "mix"; break; - case NODE_BLEND2: node["type"] = "blend2"; break; - case NODE_BLEND3: node["type"] = "blend3"; break; - case NODE_BLEND4: node["type"] = "blend4"; break; - case NODE_TIMESCALE: node["type"] = "timescale"; break; - case NODE_TIMESEEK: node["type"] = "timeseek"; break; - case NODE_TRANSITION: node["type"] = "transition"; break; - default: node["type"] = ""; break; - } - - switch (n->type) { - case NODE_OUTPUT: { - - } break; - case NODE_ANIMATION: { - AnimationNode *an = static_cast<AnimationNode *>(n); - if (master != NodePath() && an->from != "") { - node["from"] = an->from; - } else { - node["animation"] = an->animation; - } - Array k; - List<NodePath> keys; - an->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - } break; - case NODE_ONESHOT: { - OneShotNode *osn = static_cast<OneShotNode *>(n); - node["fade_in"] = osn->fade_in; - node["fade_out"] = osn->fade_out; - node["mix"] = osn->mix; - node["autorestart"] = osn->autorestart; - node["autorestart_delay"] = osn->autorestart_delay; - node["autorestart_random_delay"] = osn->autorestart_random_delay; - - Array k; - List<NodePath> keys; - osn->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - - } break; - case NODE_MIX: { - MixNode *mn = static_cast<MixNode *>(n); - node["mix"] = mn->amount; - } break; - case NODE_BLEND2: { - Blend2Node *bn = static_cast<Blend2Node *>(n); - node["blend"] = bn->value; - Array k; - List<NodePath> keys; - bn->filter.get_key_list(&keys); - k.resize(keys.size()); - int i = 0; - for (List<NodePath>::Element *F = keys.front(); F; F = F->next()) { - k[i++] = F->get(); - } - node["filter"] = k; - - } break; - case NODE_BLEND3: { - Blend3Node *bn = static_cast<Blend3Node *>(n); - node["blend"] = bn->value; - } break; - case NODE_BLEND4: { - Blend4Node *bn = static_cast<Blend4Node *>(n); - node["blend"] = bn->value; - - } break; - case NODE_TIMESCALE: { - TimeScaleNode *tsn = static_cast<TimeScaleNode *>(n); - node["scale"] = tsn->scale; - } break; - case NODE_TIMESEEK: { - } break; - case NODE_TRANSITION: { - - TransitionNode *tn = static_cast<TransitionNode *>(n); - node["xfade"] = tn->xfade; - Array transitions; - - for (int i = 0; i < tn->input_data.size(); i++) { - - Dictionary d; - d["auto_advance"] = tn->input_data[i].auto_advance; - transitions.push_back(d); - } - - node["transitions"] = transitions; - - } break; - default: { - }; - } - - nodes.push_back(node); - } - - data["nodes"] = nodes; - //connectiosn - - List<Connection> connections; - get_connection_list(&connections); - Array connections_arr; - connections_arr.resize(connections.size() * 3); - - int idx = 0; - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - - connections_arr.set(idx + 0, E->get().src_node); - connections_arr.set(idx + 1, E->get().dst_node); - connections_arr.set(idx + 2, E->get().dst_input); - - idx += 3; - } - - data["connections"] = connections_arr; - data["active"] = active; - data["master"] = master; - - r_ret = data; - - return true; -} - -void AnimationTreePlayer::_get_property_list(List<PropertyInfo> *p_list) const { - - p_list->push_back(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK)); -} - -void AnimationTreePlayer::advance(float p_time) { - - _process_animation(p_time); -} - -void AnimationTreePlayer::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - WARN_DEPRECATED_MSG("AnimationTreePlayer has been deprecated. Use AnimationTree instead."); - - if (!processing) { - //make sure that a previous process state was not saved - //only process if "processing" is set - set_physics_process_internal(false); - set_process_internal(false); - } - } break; - case NOTIFICATION_READY: { - - dirty_caches = true; - if (master != NodePath()) { - _update_sources(); - } - } break; - case NOTIFICATION_INTERNAL_PROCESS: { - - if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) - break; - - if (processing) - _process_animation(get_process_delta_time()); - } break; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - - if (animation_process_mode == ANIMATION_PROCESS_IDLE) - break; - - if (processing) - _process_animation(get_physics_process_delta_time()); - } break; - } -} - -void AnimationTreePlayer::_compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter, float p_filtered_coeff) { - - if (p_filter != NULL) { - - List<NodePath> key_list; - p_filter->get_key_list(&key_list); - - for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) { - - if ((*p_filter)[E->get()]) { - - if (p_weights->has(E->get())) { - (*p_weights)[E->get()] *= p_filtered_coeff; - } else { - p_weights->set(E->get(), *p_fallback_weight * p_filtered_coeff); - } - - } else if (p_weights->has(E->get())) { - (*p_weights)[E->get()] *= p_coeff; - } - } - } - - List<NodePath> key_list; - p_weights->get_key_list(&key_list); - - for (List<NodePath>::Element *E = key_list.front(); E; E = E->next()) { - if (p_filter == NULL || !p_filter->has(E->get())) { - (*p_weights)[E->get()] *= p_coeff; - } - } - - *p_fallback_weight *= p_coeff; -} - -float AnimationTreePlayer::_process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek, float p_fallback_weight, HashMap<NodePath, float> *p_weights) { - - ERR_FAIL_COND_V(!node_map.has(p_node), 0); - NodeBase *nb = node_map[p_node]; - - //transform to seconds... - - switch (nb->type) { - - case NODE_OUTPUT: { - - NodeOut *on = static_cast<NodeOut *>(nb); - HashMap<NodePath, float> weights; - - return _process_node(on->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, &weights); - - } break; - case NODE_ANIMATION: { - - AnimationNode *an = static_cast<AnimationNode *>(nb); - - float rem = 0; - if (!an->animation.is_null()) { - - //float pos = an->time; - //float delta = p_time; - - //const Animation *a = an->animation.operator->(); - - if (p_seek) { - an->time = p_time; - an->step = 0; - } else { - an->time = MAX(0, an->time + p_time); - an->step = p_time; - } - - float anim_size = an->animation->get_length(); - - if (an->animation->has_loop()) { - - if (anim_size) - an->time = Math::fposmod(an->time, anim_size); - - } else if (an->time > anim_size) { - - an->time = anim_size; - } - - an->skip = true; - - for (List<AnimationNode::TrackRef>::Element *E = an->tref.front(); E; E = E->next()) { - NodePath track_path = an->animation->track_get_path(E->get().local_track); - if (an->filter.has(track_path) && an->filter[track_path]) { - E->get().weight = 0; - } else { - if (p_weights->has(track_path)) { - float weight = (*p_weights)[track_path]; - E->get().weight = weight; - } else { - E->get().weight = p_fallback_weight; - } - } - if (E->get().weight > CMP_EPSILON) - an->skip = false; - } - - rem = anim_size - an->time; - } - - if (!(*r_prev_anim)) - active_list = an; - else - (*r_prev_anim)->next = an; - - an->next = NULL; - *r_prev_anim = an; - - return rem; - - } break; - case NODE_ONESHOT: { - - OneShotNode *osn = static_cast<OneShotNode *>(nb); - - if (!osn->active) { - //make it as if this node doesn't exist, pass input 0 by. - return _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - } - - bool os_seek = p_seek; - - if (p_seek) - osn->time = p_time; - if (osn->start) { - osn->time = 0; - os_seek = true; - } - - float blend; - - if (osn->time < osn->fade_in) { - - if (osn->fade_in > 0) - blend = osn->time / osn->fade_in; - else - blend = 0; //wtf - - } else if (!osn->start && osn->remaining < osn->fade_out) { - - if (osn->fade_out) - blend = (osn->remaining / osn->fade_out); - else - blend = 1.0; - } else - blend = 1.0; - - float main_rem; - float os_rem; - - HashMap<NodePath, float> os_weights(*p_weights); - float os_fallback_weight = p_fallback_weight; - _compute_weights(&p_fallback_weight, p_weights, osn->mix ? 1.0 : 1.0 - blend, &osn->filter, 1.0); - _compute_weights(&os_fallback_weight, &os_weights, blend, &osn->filter, 0.0); - - main_rem = _process_node(osn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - os_rem = _process_node(osn->inputs[1].node, r_prev_anim, p_time, os_seek, os_fallback_weight, &os_weights); - - if (osn->start) { - osn->remaining = os_rem; - osn->start = false; - } - - if (!p_seek) { - osn->time += p_time; - osn->remaining = os_rem; - if (osn->remaining <= 0) - osn->active = false; - } - - return MAX(main_rem, osn->remaining); - } break; - case NODE_MIX: { - MixNode *mn = static_cast<MixNode *>(nb); - - HashMap<NodePath, float> mn_weights(*p_weights); - float mn_fallback_weight = p_fallback_weight; - _compute_weights(&mn_fallback_weight, &mn_weights, mn->amount); - float rem = _process_node(mn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(mn->inputs[1].node, r_prev_anim, p_time, p_seek, mn_fallback_weight, &mn_weights); - return rem; - - } break; - case NODE_BLEND2: { - - Blend2Node *bn = static_cast<Blend2Node *>(nb); - - HashMap<NodePath, float> bn_weights(*p_weights); - float bn_fallback_weight = p_fallback_weight; - _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value, &bn->filter, 1.0); - _compute_weights(&bn_fallback_weight, &bn_weights, bn->value, &bn->filter, 0.0); - float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, bn_fallback_weight, &bn_weights); - - return rem; - } break; - case NODE_BLEND3: { - Blend3Node *bn = static_cast<Blend3Node *>(nb); - - float rem; - float blend, lower_blend, upper_blend; - if (bn->value < 0) { - lower_blend = -bn->value; - blend = 1.0 - lower_blend; - upper_blend = 0; - } else { - lower_blend = 0; - blend = 1.0 - bn->value; - upper_blend = bn->value; - } - - HashMap<NodePath, float> upper_weights(*p_weights); - float upper_fallback_weight = p_fallback_weight; - HashMap<NodePath, float> lower_weights(*p_weights); - float lower_fallback_weight = p_fallback_weight; - _compute_weights(&upper_fallback_weight, &upper_weights, upper_blend); - _compute_weights(&p_fallback_weight, p_weights, blend); - _compute_weights(&lower_fallback_weight, &lower_weights, lower_blend); - - rem = _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, lower_fallback_weight, &lower_weights); - _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, upper_fallback_weight, &upper_weights); - - return rem; - } break; - case NODE_BLEND4: { - Blend4Node *bn = static_cast<Blend4Node *>(nb); - - HashMap<NodePath, float> weights1(*p_weights); - float fallback_weight1 = p_fallback_weight; - HashMap<NodePath, float> weights2(*p_weights); - float fallback_weight2 = p_fallback_weight; - HashMap<NodePath, float> weights3(*p_weights); - float fallback_weight3 = p_fallback_weight; - - _compute_weights(&p_fallback_weight, p_weights, 1.0 - bn->value.x); - _compute_weights(&fallback_weight1, &weights1, bn->value.x); - _compute_weights(&fallback_weight2, &weights2, 1.0 - bn->value.y); - _compute_weights(&fallback_weight3, &weights3, bn->value.y); - - float rem = _process_node(bn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - _process_node(bn->inputs[1].node, r_prev_anim, p_time, p_seek, fallback_weight1, &weights1); - float rem2 = _process_node(bn->inputs[2].node, r_prev_anim, p_time, p_seek, fallback_weight2, &weights2); - _process_node(bn->inputs[3].node, r_prev_anim, p_time, p_seek, fallback_weight3, &weights3); - - return MAX(rem, rem2); - - } break; - case NODE_TIMESCALE: { - TimeScaleNode *tsn = static_cast<TimeScaleNode *>(nb); - float rem; - if (p_seek) - rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time, true, p_fallback_weight, p_weights); - else - rem = _process_node(tsn->inputs[0].node, r_prev_anim, p_time * tsn->scale, false, p_fallback_weight, p_weights); - if (tsn->scale == 0) - return Math_INF; - else - return rem / tsn->scale; - - } break; - case NODE_TIMESEEK: { - - TimeSeekNode *tsn = static_cast<TimeSeekNode *>(nb); - if (tsn->seek_pos >= 0 && !p_seek) { - - p_time = tsn->seek_pos; - p_seek = true; - } - tsn->seek_pos = -1; - - return _process_node(tsn->inputs[0].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - - } break; - case NODE_TRANSITION: { - - TransitionNode *tn = static_cast<TransitionNode *>(nb); - HashMap<NodePath, float> prev_weights(*p_weights); - float prev_fallback_weight = p_fallback_weight; - - if (tn->prev < 0) { // process current animation, check for transition - - float rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - if (p_seek) - tn->time = p_time; - else - tn->time += p_time; - - if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) { - - tn->set_current((tn->current + 1) % tn->inputs.size()); - } - - return rem; - } else { // cross-fading from tn->prev to tn->current - - float blend = tn->xfade ? (tn->prev_xfading / tn->xfade) : 1; - - float rem; - - _compute_weights(&p_fallback_weight, p_weights, 1.0 - blend); - _compute_weights(&prev_fallback_weight, &prev_weights, blend); - - if (!p_seek && tn->switched) { //just switched, seek to start of current - - rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, 0, true, p_fallback_weight, p_weights); - } else { - - rem = _process_node(tn->inputs[tn->current].node, r_prev_anim, p_time, p_seek, p_fallback_weight, p_weights); - } - - tn->switched = false; - - if (p_seek) { // don't seek prev animation - _process_node(tn->inputs[tn->prev].node, r_prev_anim, 0, false, prev_fallback_weight, &prev_weights); - tn->time = p_time; - } else { - _process_node(tn->inputs[tn->prev].node, r_prev_anim, p_time, false, prev_fallback_weight, &prev_weights); - tn->time += p_time; - tn->prev_xfading -= p_time; - if (tn->prev_xfading < 0) { - - tn->prev = -1; - } - } - - return rem; - } - - } break; - default: { - } - } - - return 0; -} - -void AnimationTreePlayer::_process_animation(float p_delta) { - - if (last_error != CONNECT_OK) - return; - - if (dirty_caches) - _recompute_caches(); - - active_list = NULL; - AnimationNode *prev = NULL; - - if (reset_request) { - - _process_node(out_name, &prev, 0, true); - reset_request = false; - } else - _process_node(out_name, &prev, p_delta); - - if (dirty_caches) { - //some animation changed.. ignore this pass - return; - } - - //update the tracks.. - - /* STEP 1 CLEAR TRACKS */ - - for (TrackMap::Element *E = track_map.front(); E; E = E->next()) { - - Track &t = E->get(); - - t.loc.zero(); - t.rot = Quat(); - t.scale.x = 0; - t.scale.y = 0; - t.scale.z = 0; - - t.value = t.object->get_indexed(t.subpath); - t.value.zero(); - - t.skip = false; - } - - /* STEP 2 PROCESS ANIMATIONS */ - - AnimationNode *anim_list = active_list; - Quat empty_rot; - - while (anim_list) { - - if (!anim_list->animation.is_null() && !anim_list->skip) { - //check if animation is meaningful - Animation *a = anim_list->animation.operator->(); - - for (List<AnimationNode::TrackRef>::Element *E = anim_list->tref.front(); E; E = E->next()) { - - AnimationNode::TrackRef &tr = E->get(); - if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON || !a->track_is_enabled(tr.local_track)) - continue; - - switch (a->track_get_type(tr.local_track)) { - case Animation::TYPE_TRANSFORM: { ///< Transform a node or a bone. - - Vector3 loc; - Quat rot; - Vector3 scale; - a->transform_track_interpolate(tr.local_track, anim_list->time, &loc, &rot, &scale); - - tr.track->loc += loc * tr.weight; - - scale.x -= 1.0; - scale.y -= 1.0; - scale.z -= 1.0; - tr.track->scale += scale * tr.weight; - - tr.track->rot = tr.track->rot * empty_rot.slerp(rot, tr.weight); - - } break; - case Animation::TYPE_VALUE: { ///< Set a value in a property, can be interpolated. - - if (a->value_track_get_update_mode(tr.local_track) == Animation::UPDATE_CONTINUOUS) { - Variant value = a->value_track_interpolate(tr.local_track, anim_list->time); - Variant::blend(tr.track->value, value, tr.weight, tr.track->value); - } else { - int index = a->track_find_key(tr.local_track, anim_list->time); - tr.track->value = a->track_get_key_value(tr.local_track, index); - } - } break; - case Animation::TYPE_METHOD: { ///< Call any method on a specific node. - - List<int> indices; - a->method_track_get_key_indices(tr.local_track, anim_list->time, anim_list->step, &indices); - for (List<int>::Element *F = indices.front(); F; F = F->next()) { - - StringName method = a->method_track_get_name(tr.local_track, F->get()); - Vector<Variant> args = a->method_track_get_params(tr.local_track, F->get()); - args.resize(VARIANT_ARG_MAX); - tr.track->object->call(method, args[0], args[1], args[2], args[3], args[4]); - } - } break; - default: { - } - } - } - } - - anim_list = anim_list->next; - } - - /* STEP 3 APPLY TRACKS */ - - for (TrackMap::Element *E = track_map.front(); E; E = E->next()) { - - Track &t = E->get(); - - if (t.skip || !t.object) - continue; - - if (t.subpath.size()) { // value track - t.object->set_indexed(t.subpath, t.value); - continue; - } - - Transform xform; - xform.origin = t.loc; - - t.scale.x += 1.0; - t.scale.y += 1.0; - t.scale.z += 1.0; - xform.basis.set_quat_scale(t.rot, t.scale); - - if (t.bone_idx >= 0) { - if (t.skeleton) - t.skeleton->set_bone_pose(t.bone_idx, xform); - - } else if (t.spatial) { - - t.spatial->set_transform(xform); - } - } -} - -void AnimationTreePlayer::add_node(NodeType p_type, const StringName &p_node) { - - ERR_FAIL_COND(p_type == NODE_OUTPUT); - ERR_FAIL_COND(node_map.has(p_node)); - - NodeBase *n = NULL; - - switch (p_type) { - - case NODE_ANIMATION: { - - n = memnew(AnimationNode); - } break; - case NODE_ONESHOT: { - - n = memnew(OneShotNode); - - } break; - case NODE_MIX: { - n = memnew(MixNode); - - } break; - case NODE_BLEND2: { - n = memnew(Blend2Node); - - } break; - case NODE_BLEND3: { - n = memnew(Blend3Node); - - } break; - case NODE_BLEND4: { - n = memnew(Blend4Node); - - } break; - case NODE_TIMESCALE: { - n = memnew(TimeScaleNode); - - } break; - case NODE_TIMESEEK: { - n = memnew(TimeSeekNode); - - } break; - case NODE_TRANSITION: { - n = memnew(TransitionNode); - - } break; - default: { - } - } - - //n->name+=" "+itos(p_node); - node_map[p_node] = n; -} - -StringName AnimationTreePlayer::node_get_input_source(const StringName &p_node, int p_input) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), StringName()); - ERR_FAIL_INDEX_V(p_input, node_map[p_node]->inputs.size(), StringName()); - return node_map[p_node]->inputs[p_input].node; -} - -int AnimationTreePlayer::node_get_input_count(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), -1); - return node_map[p_node]->inputs.size(); -} -#define GET_NODE(m_type, m_cast) \ - ERR_FAIL_COND(!node_map.has(p_node)); \ - ERR_FAIL_COND_MSG(node_map[p_node]->type != m_type, "Invalid parameter for node type."); \ - m_cast *n = static_cast<m_cast *>(node_map[p_node]); - -void AnimationTreePlayer::animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - n->animation = p_animation; - dirty_caches = true; -} - -void AnimationTreePlayer::animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - n->from = p_master_animation; - dirty_caches = true; - if (master != NodePath()) - _update_sources(); -} - -void AnimationTreePlayer::animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter) { - - GET_NODE(NODE_ANIMATION, AnimationNode); - - if (p_filter) - n->filter[p_track_path] = true; - else - n->filter.erase(p_track_path); -} - -void AnimationTreePlayer::animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_ANIMATION, AnimationNode); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::oneshot_node_set_fadein_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->fade_in = p_time; -} - -void AnimationTreePlayer::oneshot_node_set_fadeout_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->fade_out = p_time; -} - -void AnimationTreePlayer::oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->mix = p_mix; -} - -void AnimationTreePlayer::oneshot_node_set_autorestart(const StringName &p_node, bool p_active) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart = p_active; -} - -void AnimationTreePlayer::oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart_delay = p_time; -} -void AnimationTreePlayer::oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->autorestart_random_delay = p_time; -} - -void AnimationTreePlayer::oneshot_node_start(const StringName &p_node) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->active = true; - n->start = true; -} - -void AnimationTreePlayer::oneshot_node_stop(const StringName &p_node) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - n->active = false; -} - -void AnimationTreePlayer::oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) { - - GET_NODE(NODE_ONESHOT, OneShotNode); - - if (p_enable) - n->filter[p_filter] = true; - else - n->filter.erase(p_filter); -} - -void AnimationTreePlayer::oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_ONESHOT, OneShotNode); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::mix_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_MIX, MixNode); - n->amount = p_amount; -} - -void AnimationTreePlayer::blend2_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_BLEND2, Blend2Node); - n->value = p_amount; -} - -void AnimationTreePlayer::blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable) { - - GET_NODE(NODE_BLEND2, Blend2Node); - - if (p_enable) - n->filter[p_filter] = true; - else - n->filter.erase(p_filter); -} - -void AnimationTreePlayer::blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const { - - GET_NODE(NODE_BLEND2, Blend2Node); - - n->filter.get_key_list(r_paths); -} - -void AnimationTreePlayer::blend3_node_set_amount(const StringName &p_node, float p_amount) { - - GET_NODE(NODE_BLEND3, Blend3Node); - n->value = p_amount; -} -void AnimationTreePlayer::blend4_node_set_amount(const StringName &p_node, const Vector2 &p_amount) { - - GET_NODE(NODE_BLEND4, Blend4Node); - n->value = p_amount; -} -void AnimationTreePlayer::timescale_node_set_scale(const StringName &p_node, float p_scale) { - - GET_NODE(NODE_TIMESCALE, TimeScaleNode); - n->scale = p_scale; -} -void AnimationTreePlayer::timeseek_node_seek(const StringName &p_node, float p_pos) { - - GET_NODE(NODE_TIMESEEK, TimeSeekNode); - n->seek_pos = p_pos; -} -void AnimationTreePlayer::transition_node_set_input_count(const StringName &p_node, int p_inputs) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_COND(p_inputs < 1); - - n->inputs.resize(p_inputs); - n->input_data.resize(p_inputs); - - _clear_cycle_test(); - - last_error = _cycle_test(out_name); -} -void AnimationTreePlayer::transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_INDEX(p_input, n->input_data.size()); - - n->input_data.write[p_input].auto_advance = p_auto_advance; -} -void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_node, float p_time) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - n->xfade = p_time; -} - -void AnimationTreePlayer::TransitionNode::set_current(int p_current) { - - ERR_FAIL_INDEX(p_current, inputs.size()); - - if (current == p_current) - return; - - prev = current; - prev_xfading = xfade; - prev_time = time; - time = 0; - current = p_current; - switched = true; -} - -void AnimationTreePlayer::transition_node_set_current(const StringName &p_node, int p_current) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - n->set_current(p_current); -} - -void AnimationTreePlayer::node_set_position(const StringName &p_node, const Vector2 &p_pos) { - - ERR_FAIL_COND(!node_map.has(p_node)); - node_map[p_node]->pos = p_pos; -} - -AnimationTreePlayer::NodeType AnimationTreePlayer::node_get_type(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), NODE_OUTPUT); - return node_map[p_node]->type; -} -Point2 AnimationTreePlayer::node_get_position(const StringName &p_node) const { - - ERR_FAIL_COND_V(!node_map.has(p_node), Point2()); - return node_map[p_node]->pos; -} - -#define GET_NODE_V(m_type, m_cast, m_ret) \ - ERR_FAIL_COND_V(!node_map.has(p_node), m_ret); \ - ERR_FAIL_COND_V_MSG(node_map[p_node]->type != m_type, m_ret, "Invalid parameter for node type."); \ - m_cast *n = static_cast<m_cast *>(node_map[p_node]); - -Ref<Animation> AnimationTreePlayer::animation_node_get_animation(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, Ref<Animation>()); - return n->animation; -} - -String AnimationTreePlayer::animation_node_get_master_animation(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, String()); - return n->from; -} - -float AnimationTreePlayer::animation_node_get_position(const StringName &p_node) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, 0); - return n->time; -} - -bool AnimationTreePlayer::animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_ANIMATION, AnimationNode, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::oneshot_node_get_fadein_time(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->fade_in; -} - -float AnimationTreePlayer::oneshot_node_get_fadeout_time(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->fade_out; -} - -bool AnimationTreePlayer::oneshot_node_get_mix_mode(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->mix; -} -bool AnimationTreePlayer::oneshot_node_has_autorestart(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart; -} -float AnimationTreePlayer::oneshot_node_get_autorestart_delay(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart_delay; -} -float AnimationTreePlayer::oneshot_node_get_autorestart_random_delay(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->autorestart_random_delay; -} - -bool AnimationTreePlayer::oneshot_node_is_active(const StringName &p_node) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->active; -} - -bool AnimationTreePlayer::oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_ONESHOT, OneShotNode, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::mix_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_MIX, MixNode, 0); - return n->amount; -} -float AnimationTreePlayer::blend2_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND2, Blend2Node, 0); - return n->value; -} - -bool AnimationTreePlayer::blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const { - - GET_NODE_V(NODE_BLEND2, Blend2Node, 0); - return n->filter.has(p_path); -} - -float AnimationTreePlayer::blend3_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND3, Blend3Node, 0); - return n->value; -} -Vector2 AnimationTreePlayer::blend4_node_get_amount(const StringName &p_node) const { - - GET_NODE_V(NODE_BLEND4, Blend4Node, Vector2()); - return n->value; -} - -float AnimationTreePlayer::timescale_node_get_scale(const StringName &p_node) const { - - GET_NODE_V(NODE_TIMESCALE, TimeScaleNode, 0); - return n->scale; -} - -void AnimationTreePlayer::transition_node_delete_input(const StringName &p_node, int p_input) { - - GET_NODE(NODE_TRANSITION, TransitionNode); - ERR_FAIL_INDEX(p_input, n->inputs.size()); - - if (n->inputs.size() <= 1) - return; - - n->inputs.remove(p_input); - n->input_data.remove(p_input); - last_error = _cycle_test(out_name); -} - -int AnimationTreePlayer::transition_node_get_input_count(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, 0); - return n->inputs.size(); -} - -bool AnimationTreePlayer::transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, false); - ERR_FAIL_INDEX_V(p_input, n->inputs.size(), false); - return n->input_data[p_input].auto_advance; -} -float AnimationTreePlayer::transition_node_get_xfade_time(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, 0); - return n->xfade; -} - -int AnimationTreePlayer::transition_node_get_current(const StringName &p_node) const { - - GET_NODE_V(NODE_TRANSITION, TransitionNode, -1); - return n->current; -} - -/*misc */ -void AnimationTreePlayer::get_node_list(List<StringName> *p_node_list) const { - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - p_node_list->push_back(E->key()); - } -} - -void AnimationTreePlayer::remove_node(const StringName &p_node) { - - ERR_FAIL_COND(!node_map.has(p_node)); - ERR_FAIL_COND_MSG(p_node == out_name, "Node 0 (output) can't be removed."); - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_node) - nb->inputs.write[i].node = StringName(); - } - } - - node_map.erase(p_node); - - _clear_cycle_test(); - - // compute last error again, just in case - last_error = _cycle_test(out_name); - dirty_caches = true; -} - -AnimationTreePlayer::ConnectError AnimationTreePlayer::_cycle_test(const StringName &p_at_node) { - - ERR_FAIL_COND_V(!node_map.has(p_at_node), CONNECT_INCOMPLETE); - - NodeBase *nb = node_map[p_at_node]; - if (nb->cycletest) - return CONNECT_CYCLE; - - nb->cycletest = true; - - for (int i = 0; i < nb->inputs.size(); i++) { - if (nb->inputs[i].node == StringName()) - return CONNECT_INCOMPLETE; - - ConnectError _err = _cycle_test(nb->inputs[i].node); - if (_err) - return _err; - } - - return CONNECT_OK; -} - -// Use this function to not alter next complete _cycle_test(). -void AnimationTreePlayer::_clear_cycle_test() { - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - NodeBase *nb = E->get(); - nb->cycletest = false; - } -} - -Error AnimationTreePlayer::connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) { - - ERR_FAIL_COND_V(!node_map.has(p_src_node), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(!node_map.has(p_dst_node), ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(p_src_node == p_dst_node, ERR_INVALID_PARAMETER); - - //NodeBase *src = node_map[p_src_node]; - NodeBase *dst = node_map[p_dst_node]; - ERR_FAIL_INDEX_V(p_dst_input, dst->inputs.size(), ERR_INVALID_PARAMETER); - - //int oldval = dst->inputs[p_dst_input].node; - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_src_node) - nb->inputs.write[i].node = StringName(); - } - } - - dst->inputs.write[p_dst_input].node = p_src_node; - - _clear_cycle_test(); - - last_error = _cycle_test(out_name); - if (last_error) { - - if (last_error == CONNECT_INCOMPLETE) - return ERR_UNCONFIGURED; - else if (last_error == CONNECT_CYCLE) - return ERR_CYCLIC_LINK; - } - dirty_caches = true; - return OK; -} - -bool AnimationTreePlayer::are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const { - - ERR_FAIL_COND_V(!node_map.has(p_src_node), false); - ERR_FAIL_COND_V(!node_map.has(p_dst_node), false); - ERR_FAIL_COND_V(p_src_node == p_dst_node, false); - - NodeBase *dst = node_map[p_dst_node]; - - return dst->inputs[p_dst_input].node == p_src_node; -} - -void AnimationTreePlayer::disconnect_nodes(const StringName &p_node, int p_input) { - - ERR_FAIL_COND(!node_map.has(p_node)); - - NodeBase *dst = node_map[p_node]; - ERR_FAIL_INDEX(p_input, dst->inputs.size()); - dst->inputs.write[p_input].node = StringName(); - last_error = CONNECT_INCOMPLETE; - dirty_caches = true; -} - -void AnimationTreePlayer::get_connection_list(List<Connection> *p_connections) const { - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node != StringName()) { - Connection c; - c.src_node = nb->inputs[i].node; - c.dst_node = E->key(); - c.dst_input = i; - p_connections->push_back(c); - } - } - } -} - -AnimationTreePlayer::Track *AnimationTreePlayer::_find_track(const NodePath &p_path) { - - Node *parent = get_node(base_path); - ERR_FAIL_COND_V(!parent, NULL); - - RES resource; - Vector<StringName> leftover_path; - Node *child = parent->get_node_and_resource(p_path, resource, leftover_path); - if (!child) { - String err = "Animation track references unknown Node: '" + String(p_path) + "'."; - WARN_PRINT(err.ascii().get_data()); - return NULL; - } - - ObjectID id = child->get_instance_id(); - int bone_idx = -1; - - if (p_path.get_subname_count()) { - - if (Object::cast_to<Skeleton>(child)) - bone_idx = Object::cast_to<Skeleton>(child)->find_bone(p_path.get_subname(0)); - } - - TrackKey key; - key.id = id; - key.bone_idx = bone_idx; - key.subpath_concatenated = p_path.get_concatenated_subnames(); - - if (!track_map.has(key)) { - - Track tr; - tr.id = id; - tr.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child; - tr.skeleton = Object::cast_to<Skeleton>(child); - tr.spatial = Object::cast_to<Spatial>(child); - tr.bone_idx = bone_idx; - if (bone_idx == -1) tr.subpath = leftover_path; - - track_map[key] = tr; - } - - return &track_map[key]; -} - -void AnimationTreePlayer::_recompute_caches() { - - track_map.clear(); - _recompute_caches(out_name); - dirty_caches = false; -} - -void AnimationTreePlayer::_recompute_caches(const StringName &p_node) { - - ERR_FAIL_COND(!node_map.has(p_node)); - - NodeBase *nb = node_map[p_node]; - - if (nb->type == NODE_ANIMATION) { - - AnimationNode *an = static_cast<AnimationNode *>(nb); - an->tref.clear(); - - if (!an->animation.is_null()) { - - Ref<Animation> a = an->animation; - - for (int i = 0; i < an->animation->get_track_count(); i++) { - - Track *tr = _find_track(a->track_get_path(i)); - if (!tr) - continue; - - AnimationNode::TrackRef tref; - tref.local_track = i; - tref.track = tr; - tref.weight = 0; - - an->tref.push_back(tref); - } - } - } - - for (int i = 0; i < nb->inputs.size(); i++) { - - _recompute_caches(nb->inputs[i].node); - } -} - -void AnimationTreePlayer::recompute_caches() { - - dirty_caches = true; -} - -/* playback */ - -void AnimationTreePlayer::set_active(bool p_active) { - - if (active == p_active) - return; - - active = p_active; - processing = active; - reset_request = p_active; - _set_process(processing, true); -} - -bool AnimationTreePlayer::is_active() const { - - return active; -} - -AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const { - - return last_error; -} - -void AnimationTreePlayer::reset() { - - reset_request = true; -} - -void AnimationTreePlayer::set_base_path(const NodePath &p_path) { - - base_path = p_path; - recompute_caches(); -} - -NodePath AnimationTreePlayer::get_base_path() const { - - return base_path; -} - -void AnimationTreePlayer::set_master_player(const NodePath &p_path) { - - if (p_path == master) - return; - - master = p_path; - _update_sources(); - recompute_caches(); -} - -NodePath AnimationTreePlayer::get_master_player() const { - - return master; -} - -PoolVector<String> AnimationTreePlayer::_get_node_list() { - - List<StringName> nl; - get_node_list(&nl); - PoolVector<String> ret; - ret.resize(nl.size()); - int idx = 0; - for (List<StringName>::Element *E = nl.front(); E; E = E->next()) { - ret.set(idx++, E->get()); - } - - return ret; -} - -void AnimationTreePlayer::_update_sources() { - - if (master == NodePath()) - return; - if (!is_inside_tree()) - return; - - Node *m = get_node(master); - if (!m) { - master = NodePath(); - ERR_FAIL_COND(!m); - } - - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(m); - - if (!ap) { - - master = NodePath(); - ERR_FAIL_COND(!ap); - } - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - if (E->get()->type == NODE_ANIMATION) { - - AnimationNode *an = static_cast<AnimationNode *>(E->get()); - - if (an->from != "") { - - an->animation = ap->get_animation(an->from); - } - } - } -} - -bool AnimationTreePlayer::node_exists(const StringName &p_name) const { - - return (node_map.has(p_name)); -} - -Error AnimationTreePlayer::node_rename(const StringName &p_node, const StringName &p_new_name) { - - if (p_new_name == p_node) - return OK; - ERR_FAIL_COND_V(!node_map.has(p_node), ERR_ALREADY_EXISTS); - ERR_FAIL_COND_V(node_map.has(p_new_name), ERR_ALREADY_EXISTS); - ERR_FAIL_COND_V(p_new_name == StringName(), ERR_INVALID_DATA); - ERR_FAIL_COND_V(p_node == out_name, ERR_INVALID_DATA); - ERR_FAIL_COND_V(p_new_name == out_name, ERR_INVALID_DATA); - - for (Map<StringName, NodeBase *>::Element *E = node_map.front(); E; E = E->next()) { - - NodeBase *nb = E->get(); - for (int i = 0; i < nb->inputs.size(); i++) { - - if (nb->inputs[i].node == p_node) { - nb->inputs.write[i].node = p_new_name; - } - } - } - - node_map[p_new_name] = node_map[p_node]; - node_map.erase(p_node); - - return OK; -} - -String AnimationTreePlayer::get_configuration_warning() const { - - return TTR("This node has been deprecated. Use AnimationTree instead."); -} - -void AnimationTreePlayer::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_node", "type", "id"), &AnimationTreePlayer::add_node); - - ClassDB::bind_method(D_METHOD("node_exists", "node"), &AnimationTreePlayer::node_exists); - ClassDB::bind_method(D_METHOD("node_rename", "node", "new_name"), &AnimationTreePlayer::node_rename); - - ClassDB::bind_method(D_METHOD("node_get_type", "id"), &AnimationTreePlayer::node_get_type); - ClassDB::bind_method(D_METHOD("node_get_input_count", "id"), &AnimationTreePlayer::node_get_input_count); - ClassDB::bind_method(D_METHOD("node_get_input_source", "id", "idx"), &AnimationTreePlayer::node_get_input_source); - - ClassDB::bind_method(D_METHOD("animation_node_set_animation", "id", "animation"), &AnimationTreePlayer::animation_node_set_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_animation", "id"), &AnimationTreePlayer::animation_node_get_animation); - - ClassDB::bind_method(D_METHOD("animation_node_set_master_animation", "id", "source"), &AnimationTreePlayer::animation_node_set_master_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_master_animation", "id"), &AnimationTreePlayer::animation_node_get_master_animation); - ClassDB::bind_method(D_METHOD("animation_node_get_position", "id"), &AnimationTreePlayer::animation_node_get_position); - ClassDB::bind_method(D_METHOD("animation_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::animation_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_fadein_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadein_time); - ClassDB::bind_method(D_METHOD("oneshot_node_get_fadein_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadein_time); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_fadeout_time", "id", "time_sec"), &AnimationTreePlayer::oneshot_node_set_fadeout_time); - ClassDB::bind_method(D_METHOD("oneshot_node_get_fadeout_time", "id"), &AnimationTreePlayer::oneshot_node_get_fadeout_time); - - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart", "id", "enable"), &AnimationTreePlayer::oneshot_node_set_autorestart); - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_delay", "id", "delay_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_delay); - ClassDB::bind_method(D_METHOD("oneshot_node_set_autorestart_random_delay", "id", "rand_sec"), &AnimationTreePlayer::oneshot_node_set_autorestart_random_delay); - - ClassDB::bind_method(D_METHOD("oneshot_node_has_autorestart", "id"), &AnimationTreePlayer::oneshot_node_has_autorestart); - ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_delay); - ClassDB::bind_method(D_METHOD("oneshot_node_get_autorestart_random_delay", "id"), &AnimationTreePlayer::oneshot_node_get_autorestart_random_delay); - - ClassDB::bind_method(D_METHOD("oneshot_node_start", "id"), &AnimationTreePlayer::oneshot_node_start); - ClassDB::bind_method(D_METHOD("oneshot_node_stop", "id"), &AnimationTreePlayer::oneshot_node_stop); - ClassDB::bind_method(D_METHOD("oneshot_node_is_active", "id"), &AnimationTreePlayer::oneshot_node_is_active); - ClassDB::bind_method(D_METHOD("oneshot_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::oneshot_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("mix_node_set_amount", "id", "ratio"), &AnimationTreePlayer::mix_node_set_amount); - ClassDB::bind_method(D_METHOD("mix_node_get_amount", "id"), &AnimationTreePlayer::mix_node_get_amount); - - ClassDB::bind_method(D_METHOD("blend2_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend2_node_set_amount); - ClassDB::bind_method(D_METHOD("blend2_node_get_amount", "id"), &AnimationTreePlayer::blend2_node_get_amount); - ClassDB::bind_method(D_METHOD("blend2_node_set_filter_path", "id", "path", "enable"), &AnimationTreePlayer::blend2_node_set_filter_path); - - ClassDB::bind_method(D_METHOD("blend3_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend3_node_set_amount); - ClassDB::bind_method(D_METHOD("blend3_node_get_amount", "id"), &AnimationTreePlayer::blend3_node_get_amount); - - ClassDB::bind_method(D_METHOD("blend4_node_set_amount", "id", "blend"), &AnimationTreePlayer::blend4_node_set_amount); - ClassDB::bind_method(D_METHOD("blend4_node_get_amount", "id"), &AnimationTreePlayer::blend4_node_get_amount); - - ClassDB::bind_method(D_METHOD("timescale_node_set_scale", "id", "scale"), &AnimationTreePlayer::timescale_node_set_scale); - ClassDB::bind_method(D_METHOD("timescale_node_get_scale", "id"), &AnimationTreePlayer::timescale_node_get_scale); - - ClassDB::bind_method(D_METHOD("timeseek_node_seek", "id", "seconds"), &AnimationTreePlayer::timeseek_node_seek); - - ClassDB::bind_method(D_METHOD("transition_node_set_input_count", "id", "count"), &AnimationTreePlayer::transition_node_set_input_count); - ClassDB::bind_method(D_METHOD("transition_node_get_input_count", "id"), &AnimationTreePlayer::transition_node_get_input_count); - ClassDB::bind_method(D_METHOD("transition_node_delete_input", "id", "input_idx"), &AnimationTreePlayer::transition_node_delete_input); - - ClassDB::bind_method(D_METHOD("transition_node_set_input_auto_advance", "id", "input_idx", "enable"), &AnimationTreePlayer::transition_node_set_input_auto_advance); - ClassDB::bind_method(D_METHOD("transition_node_has_input_auto_advance", "id", "input_idx"), &AnimationTreePlayer::transition_node_has_input_auto_advance); - - ClassDB::bind_method(D_METHOD("transition_node_set_xfade_time", "id", "time_sec"), &AnimationTreePlayer::transition_node_set_xfade_time); - ClassDB::bind_method(D_METHOD("transition_node_get_xfade_time", "id"), &AnimationTreePlayer::transition_node_get_xfade_time); - - ClassDB::bind_method(D_METHOD("transition_node_set_current", "id", "input_idx"), &AnimationTreePlayer::transition_node_set_current); - ClassDB::bind_method(D_METHOD("transition_node_get_current", "id"), &AnimationTreePlayer::transition_node_get_current); - - ClassDB::bind_method(D_METHOD("node_set_position", "id", "screen_position"), &AnimationTreePlayer::node_set_position); - ClassDB::bind_method(D_METHOD("node_get_position", "id"), &AnimationTreePlayer::node_get_position); - - ClassDB::bind_method(D_METHOD("remove_node", "id"), &AnimationTreePlayer::remove_node); - ClassDB::bind_method(D_METHOD("connect_nodes", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::connect_nodes); - ClassDB::bind_method(D_METHOD("are_nodes_connected", "id", "dst_id", "dst_input_idx"), &AnimationTreePlayer::are_nodes_connected); - ClassDB::bind_method(D_METHOD("disconnect_nodes", "id", "dst_input_idx"), &AnimationTreePlayer::disconnect_nodes); - - ClassDB::bind_method(D_METHOD("set_active", "enabled"), &AnimationTreePlayer::set_active); - ClassDB::bind_method(D_METHOD("is_active"), &AnimationTreePlayer::is_active); - - ClassDB::bind_method(D_METHOD("set_base_path", "path"), &AnimationTreePlayer::set_base_path); - ClassDB::bind_method(D_METHOD("get_base_path"), &AnimationTreePlayer::get_base_path); - - ClassDB::bind_method(D_METHOD("set_master_player", "nodepath"), &AnimationTreePlayer::set_master_player); - ClassDB::bind_method(D_METHOD("get_master_player"), &AnimationTreePlayer::get_master_player); - - ClassDB::bind_method(D_METHOD("get_node_list"), &AnimationTreePlayer::_get_node_list); - - ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationTreePlayer::set_animation_process_mode); - ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationTreePlayer::get_animation_process_mode); - - ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTreePlayer::advance); - - ClassDB::bind_method(D_METHOD("reset"), &AnimationTreePlayer::reset); - - ClassDB::bind_method(D_METHOD("recompute_caches"), &AnimationTreePlayer::recompute_caches); - - ADD_GROUP("Playback", "playback_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode"); - - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active"); - - BIND_ENUM_CONSTANT(NODE_OUTPUT); - BIND_ENUM_CONSTANT(NODE_ANIMATION); - BIND_ENUM_CONSTANT(NODE_ONESHOT); - BIND_ENUM_CONSTANT(NODE_MIX); - BIND_ENUM_CONSTANT(NODE_BLEND2); - BIND_ENUM_CONSTANT(NODE_BLEND3); - BIND_ENUM_CONSTANT(NODE_BLEND4); - BIND_ENUM_CONSTANT(NODE_TIMESCALE); - BIND_ENUM_CONSTANT(NODE_TIMESEEK); - BIND_ENUM_CONSTANT(NODE_TRANSITION); - - BIND_ENUM_CONSTANT(ANIMATION_PROCESS_PHYSICS); - BIND_ENUM_CONSTANT(ANIMATION_PROCESS_IDLE); -} - -AnimationTreePlayer::AnimationTreePlayer() { - - active_list = NULL; - out = memnew(NodeOut); - out_name = "out"; - out->pos = Point2(40, 40); - node_map.insert(out_name, out); - animation_process_mode = ANIMATION_PROCESS_IDLE; - processing = false; - active = false; - dirty_caches = true; - reset_request = true; - last_error = CONNECT_INCOMPLETE; - base_path = String(".."); -} - -AnimationTreePlayer::~AnimationTreePlayer() { - - while (node_map.size()) { - memdelete(node_map.front()->get()); - node_map.erase(node_map.front()); - } -} diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h deleted file mode 100644 index e1f6ce7b9c..0000000000 --- a/scene/animation/animation_tree_player.h +++ /dev/null @@ -1,487 +0,0 @@ -/*************************************************************************/ -/* animation_tree_player.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ANIMATION_TREE_PLAYER_H -#define ANIMATION_TREE_PLAYER_H - -#include "animation_player.h" -#include "scene/3d/skeleton.h" -#include "scene/3d/spatial.h" -#include "scene/resources/animation.h" - -class AnimationTreePlayer : public Node { - - GDCLASS(AnimationTreePlayer, Node); - OBJ_CATEGORY("Animation Nodes"); - -public: - enum AnimationProcessMode { - ANIMATION_PROCESS_PHYSICS, - ANIMATION_PROCESS_IDLE, - }; - - enum NodeType { - - NODE_OUTPUT, - NODE_ANIMATION, - NODE_ONESHOT, - NODE_MIX, - NODE_BLEND2, - NODE_BLEND3, - NODE_BLEND4, - NODE_TIMESCALE, - NODE_TIMESEEK, - NODE_TRANSITION, - - NODE_MAX, - }; - - enum ConnectError { - - CONNECT_OK, - CONNECT_INCOMPLETE, - CONNECT_CYCLE - }; - -private: - enum { - - DISCONNECTED = -1, - }; - - struct TrackKey { - - uint32_t id; - StringName subpath_concatenated; - int bone_idx; - - inline bool operator<(const TrackKey &p_right) const { - - if (id == p_right.id) { - if (bone_idx == p_right.bone_idx) { - return subpath_concatenated < p_right.subpath_concatenated; - } else - return bone_idx < p_right.bone_idx; - } else - return id < p_right.id; - } - }; - - struct Track { - uint32_t id; - Object *object; - Spatial *spatial; - Skeleton *skeleton; - int bone_idx; - Vector<StringName> subpath; - - Vector3 loc; - Quat rot; - Vector3 scale; - - Variant value; - - bool skip; - - Track() : - id(0), - object(NULL), - spatial(NULL), - skeleton(NULL), - bone_idx(-1), - skip(false) {} - }; - - typedef Map<TrackKey, Track> TrackMap; - - TrackMap track_map; - - struct Input { - - StringName node; - //Input() { node=-1; } - }; - - struct NodeBase { - - bool cycletest; - - NodeType type; - Point2 pos; - - Vector<Input> inputs; - - NodeBase() { cycletest = false; }; - virtual ~NodeBase() { cycletest = false; } - }; - - struct NodeOut : public NodeBase { - - NodeOut() { - type = NODE_OUTPUT; - inputs.resize(1); - } - }; - - struct AnimationNode : public NodeBase { - - Ref<Animation> animation; - - struct TrackRef { - int local_track; - Track *track; - float weight; - }; - - uint64_t last_version; - List<TrackRef> tref; - AnimationNode *next; - float time; - float step; - String from; - bool skip; - - HashMap<NodePath, bool> filter; - - AnimationNode() { - type = NODE_ANIMATION; - next = NULL; - last_version = 0; - skip = false; - } - }; - - struct OneShotNode : public NodeBase { - - bool active; - bool start; - float fade_in; - float fade_out; - - bool autorestart; - float autorestart_delay; - float autorestart_random_delay; - bool mix; - - float time; - float remaining; - float autorestart_remaining; - - HashMap<NodePath, bool> filter; - - OneShotNode() { - type = NODE_ONESHOT; - fade_in = 0; - fade_out = 0; - inputs.resize(2); - autorestart = false; - autorestart_delay = 1; - autorestart_remaining = 0; - mix = false; - active = false; - start = false; - } - }; - - struct MixNode : public NodeBase { - - float amount; - MixNode() { - type = NODE_MIX; - inputs.resize(2); - } - }; - - struct Blend2Node : public NodeBase { - - float value; - HashMap<NodePath, bool> filter; - Blend2Node() { - type = NODE_BLEND2; - value = 0; - inputs.resize(2); - } - }; - - struct Blend3Node : public NodeBase { - - float value; - Blend3Node() { - type = NODE_BLEND3; - value = 0; - inputs.resize(3); - } - }; - - struct Blend4Node : public NodeBase { - - Point2 value; - Blend4Node() { - type = NODE_BLEND4; - inputs.resize(4); - } - }; - - struct TimeScaleNode : public NodeBase { - - float scale; - TimeScaleNode() { - type = NODE_TIMESCALE; - scale = 1; - inputs.resize(1); - } - }; - - struct TimeSeekNode : public NodeBase { - - float seek_pos; - - TimeSeekNode() { - type = NODE_TIMESEEK; - inputs.resize(1); - seek_pos = -1; - } - }; - - struct TransitionNode : public NodeBase { - - struct InputData { - - bool auto_advance; - InputData() { auto_advance = false; } - }; - - Vector<InputData> input_data; - - float prev_time; - float prev_xfading; - int prev; - bool switched; - - float time; - int current; - - float xfade; - - TransitionNode() { - type = NODE_TRANSITION; - xfade = 0; - inputs.resize(1); - input_data.resize(1); - current = 0; - prev = -1; - prev_time = 0; - prev_xfading = 0; - switched = false; - } - void set_current(int p_current); - }; - - void _update_sources(); - - StringName out_name; - NodeOut *out; - - NodePath base_path; - NodePath master; - - ConnectError last_error; - AnimationNode *active_list; - AnimationProcessMode animation_process_mode; - bool processing; - bool active; - bool dirty_caches; - Map<StringName, NodeBase *> node_map; - - // return time left to finish animation - float _process_node(const StringName &p_node, AnimationNode **r_prev_anim, float p_time, bool p_seek = false, float p_fallback_weight = 1.0, HashMap<NodePath, float> *p_weights = NULL); - void _process_animation(float p_delta); - bool reset_request; - - ConnectError _cycle_test(const StringName &p_at_node); - void _clear_cycle_test(); - - Track *_find_track(const NodePath &p_path); - void _recompute_caches(); - void _recompute_caches(const StringName &p_node); - PoolVector<String> _get_node_list(); - - void _compute_weights(float *p_fallback_weight, HashMap<NodePath, float> *p_weights, float p_coeff, const HashMap<NodePath, bool> *p_filter = NULL, float p_filtered_coeff = 0); - -protected: - 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; - void _notification(int p_what); - - static void _bind_methods(); - -public: - void add_node(NodeType p_type, const StringName &p_node); // nodes must be >0 node 0 is built-in (exit) - bool node_exists(const StringName &p_name) const; - - Error node_rename(const StringName &p_node, const StringName &p_new_name); - int node_get_input_count(const StringName &p_node) const; - StringName node_get_input_source(const StringName &p_node, int p_input) const; - - String get_configuration_warning() const; - - /* ANIMATION NODE */ - void animation_node_set_animation(const StringName &p_node, const Ref<Animation> &p_animation); - Ref<Animation> animation_node_get_animation(const StringName &p_node) const; - void animation_node_set_master_animation(const StringName &p_node, const String &p_master_animation); - String animation_node_get_master_animation(const StringName &p_node) const; - float animation_node_get_position(const StringName &p_node) const; - - void animation_node_set_filter_path(const StringName &p_node, const NodePath &p_track_path, bool p_filter); - void animation_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool animation_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - /* ONE SHOT NODE */ - - void oneshot_node_set_fadein_time(const StringName &p_node, float p_time); - void oneshot_node_set_fadeout_time(const StringName &p_node, float p_time); - - float oneshot_node_get_fadein_time(const StringName &p_node) const; - float oneshot_node_get_fadeout_time(const StringName &p_node) const; - - void oneshot_node_set_autorestart(const StringName &p_node, bool p_active); - void oneshot_node_set_autorestart_delay(const StringName &p_node, float p_time); - void oneshot_node_set_autorestart_random_delay(const StringName &p_node, float p_time); - - bool oneshot_node_has_autorestart(const StringName &p_node) const; - float oneshot_node_get_autorestart_delay(const StringName &p_node) const; - float oneshot_node_get_autorestart_random_delay(const StringName &p_node) const; - - void oneshot_node_set_mix_mode(const StringName &p_node, bool p_mix); - bool oneshot_node_get_mix_mode(const StringName &p_node) const; - - void oneshot_node_start(const StringName &p_node); - void oneshot_node_stop(const StringName &p_node); - bool oneshot_node_is_active(const StringName &p_node) const; - - void oneshot_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable); - void oneshot_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool oneshot_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - /* MIX/BLEND NODES */ - - void mix_node_set_amount(const StringName &p_node, float p_amount); - float mix_node_get_amount(const StringName &p_node) const; - - void blend2_node_set_amount(const StringName &p_node, float p_amount); - float blend2_node_get_amount(const StringName &p_node) const; - void blend2_node_set_filter_path(const StringName &p_node, const NodePath &p_filter, bool p_enable); - void blend2_node_set_get_filtered_paths(const StringName &p_node, List<NodePath> *r_paths) const; - bool blend2_node_is_path_filtered(const StringName &p_node, const NodePath &p_path) const; - - void blend3_node_set_amount(const StringName &p_node, float p_amount); - float blend3_node_get_amount(const StringName &p_node) const; - - void blend4_node_set_amount(const StringName &p_node, const Point2 &p_amount); - Point2 blend4_node_get_amount(const StringName &p_node) const; - - /* TIMESCALE/TIMESEEK NODES */ - - void timescale_node_set_scale(const StringName &p_node, float p_scale); - float timescale_node_get_scale(const StringName &p_node) const; - - void timeseek_node_seek(const StringName &p_node, float p_pos); - - /* TRANSITION NODE */ - - void transition_node_set_input_count(const StringName &p_node, int p_inputs); // used for transition node - int transition_node_get_input_count(const StringName &p_node) const; - void transition_node_delete_input(const StringName &p_node, int p_input); // used for transition node - - void transition_node_set_input_auto_advance(const StringName &p_node, int p_input, bool p_auto_advance); // used for transition node - bool transition_node_has_input_auto_advance(const StringName &p_node, int p_input) const; - - void transition_node_set_xfade_time(const StringName &p_node, float p_time); // used for transition node - float transition_node_get_xfade_time(const StringName &p_node) const; - - void transition_node_set_current(const StringName &p_node, int p_current); - int transition_node_get_current(const StringName &p_node) const; - - void node_set_position(const StringName &p_node, const Vector2 &p_pos); //for display - - /* GETS */ - Point2 node_get_position(const StringName &p_node) const; //for display - - NodeType node_get_type(const StringName &p_node) const; - - void get_node_list(List<StringName> *p_node_list) const; - void remove_node(const StringName &p_node); - - Error connect_nodes(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input); - bool are_nodes_connected(const StringName &p_src_node, const StringName &p_dst_node, int p_dst_input) const; - void disconnect_nodes(const StringName &p_node, int p_input); - - void set_base_path(const NodePath &p_path); - NodePath get_base_path() const; - - void set_master_player(const NodePath &p_path); - NodePath get_master_player() const; - - struct Connection { - - StringName src_node; - StringName dst_node; - int dst_input; - }; - - void get_connection_list(List<Connection> *p_connections) const; - - /* playback */ - - void set_active(bool p_active); - bool is_active() const; - - void reset(); - - void recompute_caches(); - - ConnectError get_last_error() const; - - void set_animation_process_mode(AnimationProcessMode p_mode); - AnimationProcessMode get_animation_process_mode() const; - - void _set_process(bool p_process, bool p_force = false); - - void advance(float p_time); - - AnimationTreePlayer(); - ~AnimationTreePlayer(); -}; - -VARIANT_ENUM_CAST(AnimationTreePlayer::NodeType); -VARIANT_ENUM_CAST(AnimationTreePlayer::AnimationProcessMode); - -#endif // ANIMATION_TREE_PLAYER_H diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 32ceeb4dbf..ce9b8bd213 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -79,7 +79,7 @@ void RootMotionView::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - VS::get_singleton()->immediate_set_material(immediate, SpatialMaterial::get_material_rid_for_2d(false, true, false, false, false)); + VS::get_singleton()->immediate_set_material(immediate, StandardMaterial3D::get_material_rid_for_2d(false, true, false, false, false)); first = true; } @@ -164,8 +164,8 @@ AABB RootMotionView::get_aabb() const { return AABB(Vector3(-radius, 0, -radius), Vector3(radius * 2, 0.001, radius * 2)); } -PoolVector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const { - return PoolVector<Face3>(); +Vector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const { + return Vector<Face3>(); } void RootMotionView::_bind_methods() { @@ -187,8 +187,8 @@ void RootMotionView::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_path", "get_animation_path"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "zero_y"), "set_zero_y", "get_zero_y"); } diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index 0a255cb5d2..42950dde42 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -69,7 +69,7 @@ public: bool get_zero_y() const; virtual AABB get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; + virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const; RootMotionView(); ~RootMotionView(); diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 46028a9ce2..5cdb38b5c2 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -329,17 +329,6 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove } } -void FabrikInverseKinematic::reset(Task *p_task) { - ChainItem *ci(&p_task->chain.chain_root); - while (ci) { - p_task->skeleton->set_bone_global_pose_override(ci->bone, Transform(), 0); - if (!ci->children.empty()) - ci = &ci->children.write[0]; - else - ci = NULL; - } -} - void SkeletonIK::_validate_property(PropertyInfo &property) const { if (property.name == "root_bone" || property.name == "tip_bone") { @@ -401,15 +390,15 @@ void SkeletonIK::_bind_methods() { ClassDB::bind_method(D_METHOD("start", "one_time"), &SkeletonIK::start, DEFVAL(false)); ClassDB::bind_method(D_METHOD("stop"), &SkeletonIK::stop); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "root_bone"), "set_root_bone", "get_root_bone"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "tip_bone"), "set_tip_bone", "get_tip_bone"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone"), "set_root_bone", "get_root_bone"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "tip_bone"), "set_tip_bone", "get_tip_bone"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position"); ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node"), "set_target_node", "get_target_node"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_distance"), "set_min_distance", "get_min_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_distance"), "set_min_distance", "get_min_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iterations"), "set_max_iterations", "get_max_iterations"); } @@ -542,8 +531,6 @@ void SkeletonIK::start(bool p_one_time) { void SkeletonIK::stop() { set_process_internal(false); - if (task) - FabrikInverseKinematic::reset(task); } Transform SkeletonIK::_get_target_transform() { diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h index 8fc8a58b99..02d5aba5ba 100644 --- a/scene/animation/skeleton_ik.h +++ b/scene/animation/skeleton_ik.h @@ -98,7 +98,7 @@ class FabrikInverseKinematic { }; public: - struct Task : public RID_Data { + struct Task { RID self; Skeleton *skeleton; @@ -139,7 +139,6 @@ public: static void set_goal(Task *p_task, const Transform &p_goal); static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); - static void reset(Task *p_task); }; class SkeletonIK : public Node { diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 331a6c769c..4b8b537d43 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -67,7 +67,6 @@ void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const count = 0; // Add the specified arguments to the command - // TODO: Make this a switch statement? if (count > 0) cmd.arg[0] = p_arg1; if (count > 1) @@ -97,7 +96,7 @@ void Tween::_process_pending_commands() { // Get the command PendingCommand &cmd = E->get(); - Variant::CallError err; + Callable::CallError err; // Grab all of the arguments for the command Variant *arg[10] = { @@ -157,7 +156,7 @@ void Tween::_get_property_list(List<PropertyInfo> *p_list) const { // Add the property info for the Tween object p_list->push_back(PropertyInfo(Variant::BOOL, "playback/active", PROPERTY_HINT_NONE, "")); p_list->push_back(PropertyInfo(Variant::BOOL, "playback/repeat", PROPERTY_HINT_NONE, "")); - p_list->push_back(PropertyInfo(Variant::REAL, "playback/speed", PROPERTY_HINT_RANGE, "-64,64,0.01")); + p_list->push_back(PropertyInfo(Variant::FLOAT, "playback/speed", PROPERTY_HINT_RANGE, "-64,64,0.01")); } void Tween::_notification(int p_what) { @@ -250,14 +249,14 @@ void Tween::_bind_methods() { // Add the Tween signals ADD_SIGNAL(MethodInfo("tween_started", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"))); - ADD_SIGNAL(MethodInfo("tween_step", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"), PropertyInfo(Variant::REAL, "elapsed"), PropertyInfo(Variant::OBJECT, "value"))); + ADD_SIGNAL(MethodInfo("tween_step", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"), PropertyInfo(Variant::FLOAT, "elapsed"), PropertyInfo(Variant::OBJECT, "value"))); ADD_SIGNAL(MethodInfo("tween_completed", PropertyInfo(Variant::OBJECT, "object"), PropertyInfo(Variant::NODE_PATH, "key"))); ADD_SIGNAL(MethodInfo("tween_all_completed")); // Add the properties and tie them to the getters and setters ADD_PROPERTY(PropertyInfo(Variant::BOOL, "repeat"), "set_repeat", "is_repeat"); ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_tween_process_mode", "get_tween_process_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); // Bind Idle vs Physics process BIND_ENUM_CONSTANT(TWEEN_PROCESS_PHYSICS); @@ -309,9 +308,9 @@ Variant Tween::_get_initial_val(const InterpolateData &p_data) const { ERR_FAIL_COND_V(!valid, p_data.initial_val); } else { // Call the method and get the initial value from it - Variant::CallError error; + Callable::CallError error; initial_val = object->call(p_data.target_key[0], NULL, 0, error); - ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val); + ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val); } return initial_val; } @@ -341,12 +340,12 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const { ERR_FAIL_COND_V(!valid, p_data.initial_val); } else { // We're looking at a method. Call the method on the target object - Variant::CallError error; + Callable::CallError error; final_val = target->call(p_data.target_key[0], NULL, 0, error); - ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val); + ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val); } - // If we're looking at an INT value, instead convert it to a REAL + // If we're looking at an INT value, instead convert it to a FLOAT // This is better for interpolation if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t(); @@ -383,12 +382,12 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) { ERR_FAIL_COND_V(!valid, p_data.initial_val); } else { // We're looking at a method. Call the method on the target object - Variant::CallError error; + Callable::CallError error; final_val = target->call(p_data.target_key[0], NULL, 0, error); - ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, p_data.initial_val); + ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, p_data.initial_val); } - // If we're looking at an INT value, instead convert it to a REAL + // If we're looking at an INT value, instead convert it to a FLOAT // This is better for interpolation if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t(); @@ -402,7 +401,7 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) { // Grab the initial value from the data to calculate delta Variant initial_val = _get_initial_val(p_data); - // If we're looking at an INT value, instead convert it to a REAL + // If we're looking at an INT value, instead convert it to a FLOAT // This is better for interpolation if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t(); @@ -441,8 +440,8 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = (int)_run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int)initial_val, (int)delta_val, p_data.duration); break; - case Variant::REAL: - // Run the REAL specific equation + case Variant::FLOAT: + // Run the FLOAT specific equation result = _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (real_t)initial_val, (real_t)delta_val, p_data.duration); break; @@ -459,6 +458,20 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = r; } break; + case Variant::RECT2: { + // Get the Rect2 for initial and delta value + Rect2 i = initial_val; + Rect2 d = delta_val; + Rect2 r; + + // Execute the equation for the position and size of Rect2 + APPLY_EQUATION(position.x); + APPLY_EQUATION(position.y); + APPLY_EQUATION(size.x); + APPLY_EQUATION(size.y); + result = r; + } break; + case Variant::VECTOR3: { // Get vectors for initial and delta values Vector3 i = initial_val; @@ -473,26 +486,6 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = r; } break; - case Variant::BASIS: { - // Get the basis for initial and delta values - Basis i = initial_val; - Basis d = delta_val; - Basis r; - - // Execute the equation on all the basis and mutate the r basis - // This uses the custom APPLY_EQUATION macro defined above - APPLY_EQUATION(elements[0][0]); - APPLY_EQUATION(elements[0][1]); - APPLY_EQUATION(elements[0][2]); - APPLY_EQUATION(elements[1][0]); - APPLY_EQUATION(elements[1][1]); - APPLY_EQUATION(elements[1][2]); - APPLY_EQUATION(elements[2][0]); - APPLY_EQUATION(elements[2][1]); - APPLY_EQUATION(elements[2][2]); - result = r; - } break; - case Variant::TRANSFORM2D: { // Get the transforms for initial and delta values Transform2D i = initial_val; @@ -509,6 +502,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) { APPLY_EQUATION(elements[2][1]); result = r; } break; + case Variant::QUAT: { // Get the quaternian for the initial and delta values Quat i = initial_val; @@ -523,6 +517,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) { APPLY_EQUATION(w); result = r; } break; + case Variant::AABB: { // Get the AABB's for the initial and delta values AABB i = initial_val; @@ -539,6 +534,27 @@ Variant Tween::_run_equation(InterpolateData &p_data) { APPLY_EQUATION(size.z); result = r; } break; + + case Variant::BASIS: { + // Get the basis for initial and delta values + Basis i = initial_val; + Basis d = delta_val; + Basis r; + + // Execute the equation on all the basis and mutate the r basis + // This uses the custom APPLY_EQUATION macro defined above + APPLY_EQUATION(elements[0][0]); + APPLY_EQUATION(elements[0][1]); + APPLY_EQUATION(elements[0][2]); + APPLY_EQUATION(elements[1][0]); + APPLY_EQUATION(elements[1][1]); + APPLY_EQUATION(elements[1][2]); + APPLY_EQUATION(elements[2][0]); + APPLY_EQUATION(elements[2][1]); + APPLY_EQUATION(elements[2][2]); + result = r; + } break; + case Variant::TRANSFORM: { // Get the transforms for the initial and delta values Transform i = initial_val; @@ -561,6 +577,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) { APPLY_EQUATION(origin.z); result = r; } break; + case Variant::COLOR: { // Get the Color for initial and delta value Color i = initial_val; @@ -575,6 +592,7 @@ Variant Tween::_run_equation(InterpolateData &p_data) { APPLY_EQUATION(a); result = r; } break; + default: { // If unknown, just return the initial value result = initial_val; @@ -607,7 +625,7 @@ bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) { case FOLLOW_METHOD: case TARGETING_METHOD: { // We want to call the method on the target object - Variant::CallError error; + Callable::CallError error; // Do we have a non-nil value passed in? if (value.get_type() != Variant::NIL) { @@ -620,7 +638,7 @@ bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) { } // Did we get an error from the function call? - return error.error == Variant::CallError::CALL_OK; + return error.error == Callable::CallError::CALL_OK; } case INTER_CALLBACK: @@ -732,7 +750,7 @@ void Tween::_tween_process(float p_delta) { } } else { // Call the function directly with the arguments - Variant::CallError error; + Callable::CallError error; Variant *arg[5] = { &data.arg[0], &data.arg[1], @@ -1119,8 +1137,8 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final delta_val = (int)final_val - (int)initial_val; break; - case Variant::REAL: - // Convert to REAL and find the delta + case Variant::FLOAT: + // Convert to FLOAT and find the delta delta_val = (real_t)final_val - (real_t)initial_val; break; @@ -1129,26 +1147,18 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final delta_val = final_val.operator Vector2() - initial_val.operator Vector2(); break; + case Variant::RECT2: { + // Build a new Rect2 and use the new position and sizes to make a delta + Rect2 i = initial_val; + Rect2 f = final_val; + delta_val = Rect2(f.position - i.position, f.size - i.size); + } break; + case Variant::VECTOR3: // Convert to Vectors and find the delta delta_val = final_val.operator Vector3() - initial_val.operator Vector3(); break; - case Variant::BASIS: { - // Build a new basis which is the delta between the initial and final values - Basis i = initial_val; - Basis f = final_val; - delta_val = Basis(f.elements[0][0] - i.elements[0][0], - f.elements[0][1] - i.elements[0][1], - f.elements[0][2] - i.elements[0][2], - f.elements[1][0] - i.elements[1][0], - f.elements[1][1] - i.elements[1][1], - f.elements[1][2] - i.elements[1][2], - f.elements[2][0] - i.elements[2][0], - f.elements[2][1] - i.elements[2][1], - f.elements[2][2] - i.elements[2][2]); - } break; - case Variant::TRANSFORM2D: { // Build a new transform which is the difference between the initial and final values Transform2D i = initial_val; @@ -1175,6 +1185,21 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final delta_val = AABB(f.position - i.position, f.size - i.size); } break; + case Variant::BASIS: { + // Build a new basis which is the delta between the initial and final values + Basis i = initial_val; + Basis f = final_val; + delta_val = Basis(f.elements[0][0] - i.elements[0][0], + f.elements[0][1] - i.elements[0][1], + f.elements[0][2] - i.elements[0][2], + f.elements[1][0] - i.elements[1][0], + f.elements[1][1] - i.elements[1][1], + f.elements[1][2] - i.elements[1][2], + f.elements[2][0] - i.elements[2][0], + f.elements[2][1] - i.elements[2][1], + f.elements[2][2] - i.elements[2][2]); + } break; + case Variant::TRANSFORM: { // Build a new transform which is the difference between the initial and final values Transform i = initial_val; @@ -1203,10 +1228,34 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final delta_val = Color(f.r - i.r, f.g - i.g, f.b - i.b, f.a - i.a); } break; - default: - // TODO: Should move away from a 'magic string'? - ERR_PRINT("Invalid param type, except(int/real/vector2/vector/matrix/matrix32/quat/aabb/transform/color)"); + default: { + static Variant::Type supported_types[] = { + Variant::BOOL, + Variant::INT, + Variant::FLOAT, + Variant::VECTOR2, + Variant::RECT2, + Variant::VECTOR3, + Variant::TRANSFORM2D, + Variant::QUAT, + Variant::AABB, + Variant::BASIS, + Variant::TRANSFORM, + Variant::COLOR, + }; + + int length = *(&supported_types + 1) - supported_types; + String error_msg = "Invalid parameter type. Supported types are: "; + for (int i = 0; i < length; i++) { + if (i != 0) { + error_msg += ", "; + } + error_msg += Variant::get_type_name(supported_types[i]); + } + error_msg += "."; + ERR_PRINT(error_msg); return false; + } }; return true; } @@ -1227,7 +1276,6 @@ bool Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p // Give it the object ERR_FAIL_COND_V_MSG(p_object == NULL, false, "Invalid object provided to Tween."); - ERR_FAIL_COND_V_MSG(!ObjectDB::instance_validate(p_object), false, "Invalid object provided to Tween."); data.id = p_object->get_instance_id(); // Validate the initial and final values @@ -1328,7 +1376,6 @@ bool Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c // Check that the target object is valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); // Duration cannot be negative ERR_FAIL_COND_V(p_duration < 0, false); @@ -1387,7 +1434,6 @@ bool Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S // Check that the target object is valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); // No negative durations allowed ERR_FAIL_COND_V(p_duration < 0, false); @@ -1452,14 +1498,12 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini // TODO: Is this documented? It's really helpful for decluttering tweens if (p_initial_val.get_type() == Variant::NIL) p_initial_val = p_object->get_indexed(p_property.get_subnames()); - // Convert initial INT values to REAL as they are better for interpolation + // Convert initial INT values to FLOAT as they are better for interpolation if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); // Confirm the source and target objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1480,7 +1524,7 @@ bool Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini Variant target_val = p_target->get_indexed(p_target_property.get_subnames(), &target_prop_valid); ERR_FAIL_COND_V(!target_prop_valid, false); - // Convert target INT to REAL since it is better for interpolation + // Convert target INT to FLOAT since it is better for interpolation if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t(); // Verify that the target value and initial value are the same type @@ -1516,14 +1560,12 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi _add_pending_command("follow_method", p_object, p_method, p_initial_val, p_target, p_target_method, p_duration, p_trans_type, p_ease_type, p_delay); return true; } - // Convert initial INT values to REAL as they are better for interpolation + // Convert initial INT values to FLOAT as they are better for interpolation if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t(); // Verify the source and target objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_target == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_target), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1540,11 +1582,11 @@ bool Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi ERR_FAIL_COND_V_MSG(!p_target->has_method(p_target_method), false, "Target has no method named: " + p_target_method + "."); // Call the method to get the target value - Variant::CallError error; + Callable::CallError error; Variant target_val = p_target->call(p_target_method, NULL, 0, error); - ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, false); + ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, false); - // Convert target INT values to REAL as they are better for interpolation + // Convert target INT values to FLOAT as they are better for interpolation if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t(); ERR_FAIL_COND_V(target_val.get_type() != p_initial_val.get_type(), false); @@ -1582,14 +1624,12 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_ p_property = p_property.get_as_property_path(); p_initial_property = p_initial_property.get_as_property_path(); - // Convert the initial INT values to REAL as they are better for Interpolation + // Convert the initial INT values to FLOAT as they are better for Interpolation if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); // Verify both objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1610,7 +1650,7 @@ bool Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_ Variant initial_val = p_initial->get_indexed(p_initial_property.get_subnames(), &initial_prop_valid); ERR_FAIL_COND_V(!initial_prop_valid, false); - // Convert the initial INT value to REAL as it is better for interpolation + // Convert the initial INT value to FLOAT as it is better for interpolation if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t(); ERR_FAIL_COND_V(initial_val.get_type() != p_final_val.get_type(), false); @@ -1650,14 +1690,12 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in return true; } - // Convert final INT values to REAL as they are better for interpolation + // Convert final INT values to FLOAT as they are better for interpolation if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t(); // Make sure the given objects are valid ERR_FAIL_COND_V(p_object == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_object), false); ERR_FAIL_COND_V(p_initial == NULL, false); - ERR_FAIL_COND_V(!ObjectDB::instance_validate(p_initial), false); // No negative durations ERR_FAIL_COND_V(p_duration < 0, false); @@ -1674,11 +1712,11 @@ bool Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in ERR_FAIL_COND_V_MSG(!p_initial->has_method(p_initial_method), false, "Initial Object has no method named: " + p_initial_method + "."); // Call the method to get the initial value - Variant::CallError error; + Callable::CallError error; Variant initial_val = p_initial->call(p_initial_method, NULL, 0, error); - ERR_FAIL_COND_V(error.error != Variant::CallError::CALL_OK, false); + ERR_FAIL_COND_V(error.error != Callable::CallError::CALL_OK, false); - // Convert initial INT values to REAL as they aer better for interpolation + // Convert initial INT values to FLOAT as they aer better for interpolation if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t(); ERR_FAIL_COND_V(initial_val.get_type() != p_final_val.get_type(), false); diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 3a0169f065..2582bab200 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -403,21 +403,19 @@ void AudioStreamPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer::_set_playing); ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer::_is_active); - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer::_bus_layout_changed); - ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer::set_stream_paused); ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer::get_stream_paused); ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer::get_stream_playback); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_target", PROPERTY_HINT_ENUM, "Stereo,Surround,Center"), "set_mix_target", "get_mix_target"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_SIGNAL(MethodInfo("finished")); @@ -441,7 +439,7 @@ AudioStreamPlayer::AudioStreamPlayer() { setstop = false; use_fadeout = false; - AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); + AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer::_bus_layout_changed)); } AudioStreamPlayer::~AudioStreamPlayer() { diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp new file mode 100644 index 0000000000..22ff0611a7 --- /dev/null +++ b/scene/debugger/scene_debugger.cpp @@ -0,0 +1,871 @@ +/*************************************************************************/ +/* scene_debugger.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "scene_debugger.h" + +#include "core/io/marshalls.h" +#include "core/script_debugger_remote.h" +#include "scene/main/scene_tree.h" +#include "scene/main/viewport.h" +#include "scene/resources/packed_scene.h" + +void SceneDebugger::initialize() { +#ifdef DEBUG_ENABLED + LiveEditor::singleton = memnew(LiveEditor); + ScriptDebuggerRemote::scene_tree_parse_func = SceneDebugger::parse_message; +#endif +} + +void SceneDebugger::deinitialize() { +#ifdef DEBUG_ENABLED + if (LiveEditor::singleton) { + memdelete(LiveEditor::singleton); + LiveEditor::singleton = NULL; + } +#endif +} + +#ifdef DEBUG_ENABLED +Error SceneDebugger::parse_message(const String &p_msg, const Array &p_args) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return ERR_UNCONFIGURED; + LiveEditor *live_editor = LiveEditor::get_singleton(); + if (!live_editor) + return ERR_UNCONFIGURED; + if (p_msg == "request_scene_tree") { // Scene tree + live_editor->_send_tree(); + + } else if (p_msg == "save_node") { // Save node. + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + _save_node(p_args[0], p_args[1]); + + } else if (p_msg == "inspect_object") { // Object Inspect + ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); + ObjectID id = p_args[0]; + _send_object_id(id); + + } else if (p_msg == "override_camera_2D:set") { // Camera + ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); + bool enforce = p_args[0]; + scene_tree->get_root()->enable_canvas_transform_override(enforce); + + } else if (p_msg == "override_camera_2D:transform") { + ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); + Transform2D transform = p_args[1]; + scene_tree->get_root()->set_canvas_transform_override(transform); + + } else if (p_msg == "override_camera_3D:set") { + ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); + bool enable = p_args[0]; + scene_tree->get_root()->enable_camera_override(enable); + + } else if (p_msg == "override_camera_3D:transform") { + ERR_FAIL_COND_V(p_args.size() < 5, ERR_INVALID_DATA); + Transform transform = p_args[0]; + bool is_perspective = p_args[1]; + float size_or_fov = p_args[2]; + float near = p_args[3]; + float far = p_args[4]; + if (is_perspective) { + scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far); + } else { + scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far); + } + scene_tree->get_root()->set_camera_override_transform(transform); + + } else if (p_msg == "set_object_property") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + _set_object_property(p_args[0], p_args[1], p_args[2]); + + } else if (!p_msg.begins_with("live_")) { // Live edits below. + return ERR_SKIP; + } else if (p_msg == "live_set_root") { + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + live_editor->_root_func(p_args[0], p_args[1]); + + } else if (p_msg == "live_node_path") { + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + live_editor->_node_path_func(p_args[0], p_args[1]); + + } else if (p_msg == "live_res_path") { + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + live_editor->_res_path_func(p_args[0], p_args[1]); + + } else if (p_msg == "live_node_prop_res") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_node_set_res_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_node_prop") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_node_set_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_res_prop_res") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_res_set_res_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_res_prop") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_res_set_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_node_call") { + ERR_FAIL_COND_V(p_args.size() < 7, ERR_INVALID_DATA); + live_editor->_node_call_func(p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5], p_args[6]); + + } else if (p_msg == "live_res_call") { + ERR_FAIL_COND_V(p_args.size() < 7, ERR_INVALID_DATA); + live_editor->_res_call_func(p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5], p_args[6]); + + } else if (p_msg == "live_create_node") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_create_node_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_instance_node") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_instance_node_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_remove_node") { + ERR_FAIL_COND_V(p_args.size() < 1, ERR_INVALID_DATA); + live_editor->_remove_node_func(p_args[0]); + + } else if (p_msg == "live_remove_and_keep_node") { + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + live_editor->_remove_and_keep_node_func(p_args[0], p_args[1]); + + } else if (p_msg == "live_restore_node") { + ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA); + live_editor->_restore_node_func(p_args[0], p_args[1], p_args[2]); + + } else if (p_msg == "live_duplicate_node") { + ERR_FAIL_COND_V(p_args.size() < 2, ERR_INVALID_DATA); + live_editor->_duplicate_node_func(p_args[0], p_args[1]); + + } else if (p_msg == "live_reparent_node") { + ERR_FAIL_COND_V(p_args.size() < 4, ERR_INVALID_DATA); + live_editor->_reparent_node_func(p_args[0], p_args[1], p_args[2], p_args[3]); + } else { + return ERR_SKIP; + } + return OK; +} + +void SceneDebugger::_save_node(ObjectID id, const String &p_path) { + Node *node = Object::cast_to<Node>(ObjectDB::get_instance(id)); + ERR_FAIL_COND(!node); + + WARN_PRINT("SAVING " + itos(id) + " TO " + p_path); + Ref<PackedScene> ps = memnew(PackedScene); + ps->pack(node); + ResourceSaver::save(p_path, ps); +} + +void SceneDebugger::_send_object_id(ObjectID p_id, int p_max_size) { + SceneDebuggerObject obj(p_id); + if (obj.id.is_null()) + return; + + Array arr; + obj.serialize(arr); + ScriptDebugger::get_singleton()->send_message("inspect_object", arr); +} + +void SceneDebugger::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) { + + Object *obj = ObjectDB::get_instance(p_id); + if (!obj) + return; + + String prop_name = p_property; + if (p_property.begins_with("Members/")) { + Vector<String> ss = p_property.split("/"); + prop_name = ss[ss.size() - 1]; + } + + obj->set(prop_name, p_value); +} + +void SceneDebugger::add_to_cache(const String &p_filename, Node *p_node) { + LiveEditor *debugger = LiveEditor::get_singleton(); + if (!debugger) + return; + + if (ScriptDebugger::get_singleton() && p_filename != String()) { + debugger->live_scene_edit_cache[p_filename].insert(p_node); + } +} +void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) { + LiveEditor *debugger = LiveEditor::get_singleton(); + if (!debugger) + return; + + Map<String, Set<Node *> > &edit_cache = debugger->live_scene_edit_cache; + Map<String, Set<Node *> >::Element *E = edit_cache.find(p_filename); + if (E) { + E->get().erase(p_node); + if (E->get().size() == 0) { + edit_cache.erase(E); + } + } + + Map<Node *, Map<ObjectID, Node *> > &remove_list = debugger->live_edit_remove_list; + Map<Node *, Map<ObjectID, Node *> >::Element *F = remove_list.find(p_node); + if (F) { + for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) { + + memdelete(G->get()); + } + remove_list.erase(F); + } +} + +/// SceneDebuggerObject +SceneDebuggerObject::SceneDebuggerObject(ObjectID p_id) { + id = ObjectID(); + Object *obj = ObjectDB::get_instance(p_id); + if (!obj) + return; + + id = p_id; + class_name = obj->get_class(); + + if (ScriptInstance *si = obj->get_script_instance()) { + // Read script instance constants and variables + if (!si->get_script().is_null()) { + Script *s = si->get_script().ptr(); + _parse_script_properties(s, si); + } + } + + if (Node *node = Object::cast_to<Node>(obj)) { + // Add specialized NodePath info (if inside tree). + if (node->is_inside_tree()) { + PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); + properties.push_back(SceneDebuggerProperty(pi, node->get_path())); + } else { // Can't ask for path if a node is not in tree. + PropertyInfo pi(Variant::STRING, String("Node/path")); + properties.push_back(SceneDebuggerProperty(pi, "[Orphan]")); + } + } else if (Script *s = Object::cast_to<Script>(obj)) { + // Add script constants (no instance). + _parse_script_properties(s, NULL); + } + + // Add base object properties. + List<PropertyInfo> pinfo; + obj->get_property_list(&pinfo, true); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { + properties.push_back(SceneDebuggerProperty(E->get(), obj->get(E->get().name))); + } + } +} + +void SceneDebuggerObject::_parse_script_properties(Script *p_script, ScriptInstance *p_instance) { + typedef Map<const Script *, Set<StringName> > ScriptMemberMap; + typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap; + + ScriptMemberMap members; + if (p_instance) { + members[p_script] = Set<StringName>(); + p_script->get_members(&(members[p_script])); + } + + ScriptConstantsMap constants; + constants[p_script] = Map<StringName, Variant>(); + p_script->get_constants(&(constants[p_script])); + + Ref<Script> base = p_script->get_base_script(); + while (base.is_valid()) { + if (p_instance) { + members[base.ptr()] = Set<StringName>(); + base->get_members(&(members[base.ptr()])); + } + + constants[base.ptr()] = Map<StringName, Variant>(); + base->get_constants(&(constants[base.ptr()])); + + base = base->get_base_script(); + } + + // Members + for (ScriptMemberMap::Element *sm = members.front(); sm; sm = sm->next()) { + for (Set<StringName>::Element *E = sm->get().front(); E; E = E->next()) { + Variant m; + if (p_instance->get(E->get(), m)) { + String script_path = sm->key() == p_script ? "" : sm->key()->get_path().get_file() + "/"; + PropertyInfo pi(m.get_type(), "Members/" + script_path + E->get()); + properties.push_back(SceneDebuggerProperty(pi, m)); + } + } + } + // Constants + for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) { + for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) { + String script_path = sc->key() == p_script ? "" : sc->key()->get_path().get_file() + "/"; + if (E->value().get_type() == Variant::OBJECT) { + Variant id = ((Object *)E->value())->get_instance_id(); + PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object"); + properties.push_back(SceneDebuggerProperty(pi, id)); + } else { + PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key()); + properties.push_back(SceneDebuggerProperty(pi, E->value())); + } + } + } +} + +void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) { + Array send_props; + for (int i = 0; i < properties.size(); i++) { + const PropertyInfo &pi = properties[i].first; + Variant &var = properties[i].second; + + RES res = var; + + if (var.get_type() == Variant::OBJECT && var.is_ref()) { + REF r = var; + if (r.is_valid()) { + res = *r; + } else { + res = RES(); + } + } + + Array prop; + prop.push_back(pi.name); + prop.push_back(pi.type); + + PropertyHint hint = pi.hint; + String hint_string = pi.hint_string; + if (!res.is_null()) { + var = res->get_path(); + } else { //only send information that can be sent.. + int len = 0; //test how big is this to encode + encode_variant(var, NULL, len); + if (len > p_max_size) { //limit to max size + hint = PROPERTY_HINT_OBJECT_TOO_BIG; + hint_string = ""; + var = Variant(); + } + } + prop.push_back(hint); + prop.push_back(hint_string); + prop.push_back(pi.usage); + prop.push_back(var); + send_props.push_back(prop); + } + r_arr.push_back(uint64_t(id)); + r_arr.push_back(class_name); + r_arr.push_back(send_props); +} + +void SceneDebuggerObject::deserialize(const Array &p_arr) { +#define CHECK_TYPE(p_what, p_type) ERR_FAIL_COND(p_what.get_type() != Variant::p_type); + ERR_FAIL_COND(p_arr.size() < 3); + CHECK_TYPE(p_arr[0], INT); + CHECK_TYPE(p_arr[1], STRING); + CHECK_TYPE(p_arr[2], ARRAY); + + id = uint64_t(p_arr[0]); + class_name = p_arr[1]; + Array props = p_arr[2]; + + for (int i = 0; i < props.size(); i++) { + + CHECK_TYPE(props[i], ARRAY); + Array prop = props[i]; + + ERR_FAIL_COND(prop.size() != 6); + CHECK_TYPE(prop[0], STRING); + CHECK_TYPE(prop[1], INT); + CHECK_TYPE(prop[2], INT); + CHECK_TYPE(prop[3], STRING); + CHECK_TYPE(prop[4], INT); + + PropertyInfo pinfo; + pinfo.name = prop[0]; + pinfo.type = Variant::Type(int(prop[1])); + pinfo.hint = PropertyHint(int(prop[2])); + pinfo.hint_string = prop[3]; + pinfo.usage = PropertyUsageFlags(int(prop[4])); + Variant var = prop[5]; + + if (pinfo.type == Variant::OBJECT) { + if (var.is_zero()) { + var = RES(); + } else if (var.get_type() == Variant::OBJECT) { + if (((Object *)var)->is_class("EncodedObjectAsID")) { + var = Object::cast_to<EncodedObjectAsID>(var)->get_object_id(); + pinfo.type = var.get_type(); + pinfo.hint = PROPERTY_HINT_OBJECT_ID; + pinfo.hint_string = "Object"; + } + } + } + properties.push_back(SceneDebuggerProperty(pinfo, var)); + } +} + +/// SceneDebuggerTree +SceneDebuggerTree::SceneDebuggerTree(Node *p_root) { + // Flatten tree into list, depth first, use stack to avoid recursion. + List<Node *> stack; + stack.push_back(p_root); + while (stack.size()) { + Node *n = stack[0]; + stack.pop_front(); + int count = n->get_child_count(); + nodes.push_back(RemoteNode(count, n->get_name(), n->get_class(), n->get_instance_id())); + for (int i = 0; i < count; i++) { + stack.push_front(n->get_child(count - i - 1)); + } + } +} + +void SceneDebuggerTree::serialize(Array &p_arr) { + for (List<RemoteNode>::Element *E = nodes.front(); E; E = E->next()) { + RemoteNode &n = E->get(); + p_arr.push_back(n.child_count); + p_arr.push_back(n.name); + p_arr.push_back(n.type_name); + p_arr.push_back(n.id); + } +} + +void SceneDebuggerTree::deserialize(const Array &p_arr) { + int idx = 0; + while (p_arr.size() > idx) { + ERR_FAIL_COND(p_arr.size() < 4); + CHECK_TYPE(p_arr[idx], INT); + CHECK_TYPE(p_arr[idx + 1], STRING); + CHECK_TYPE(p_arr[idx + 2], STRING); + CHECK_TYPE(p_arr[idx + 3], INT); + nodes.push_back(RemoteNode(p_arr[idx], p_arr[idx + 1], p_arr[idx + 2], p_arr[idx + 3])); + idx += 4; + } +} + +/// LiveEditor +LiveEditor *LiveEditor::singleton = NULL; +LiveEditor *LiveEditor::get_singleton() { + return singleton; +} + +void LiveEditor::_send_tree() { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Array arr; + // Encoded as a flat list depth fist. + SceneDebuggerTree tree(scene_tree->root); + tree.serialize(arr); + ScriptDebugger::get_singleton()->send_message("scene_tree", arr); +} + +void LiveEditor::_node_path_func(const NodePath &p_path, int p_id) { + + live_edit_node_path_cache[p_id] = p_path; +} + +void LiveEditor::_res_path_func(const String &p_path, int p_id) { + + live_edit_resource_cache[p_id] = p_path; +} + +void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Variant &p_value) { + + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + if (!live_edit_node_path_cache.has(p_id)) + return; + + NodePath np = live_edit_node_path_cache[p_id]; + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(np)) + continue; + Node *n2 = n->get_node(np); + + n2->set(p_prop, p_value); + } +} + +void LiveEditor::_node_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { + + RES r = ResourceLoader::load(p_value); + if (!r.is_valid()) + return; + _node_set_func(p_id, p_prop, r); +} +void LiveEditor::_node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + if (!live_edit_node_path_cache.has(p_id)) + return; + + NodePath np = live_edit_node_path_cache[p_id]; + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(np)) + continue; + Node *n2 = n->get_node(np); + + n2->call(p_method, VARIANT_ARG_PASS); + } +} +void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant &p_value) { + + if (!live_edit_resource_cache.has(p_id)) + return; + + String resp = live_edit_resource_cache[p_id]; + + if (!ResourceCache::has(resp)) + return; + + RES r = ResourceCache::get(resp); + if (!r.is_valid()) + return; + + r->set(p_prop, p_value); +} +void LiveEditor::_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { + + RES r = ResourceLoader::load(p_value); + if (!r.is_valid()) + return; + _res_set_func(p_id, p_prop, r); +} +void LiveEditor::_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { + + if (!live_edit_resource_cache.has(p_id)) + return; + + String resp = live_edit_resource_cache[p_id]; + + if (!ResourceCache::has(resp)) + return; + + RES r = ResourceCache::get(resp); + if (!r.is_valid()) + return; + + r->call(p_method, VARIANT_ARG_PASS); +} + +void LiveEditor::_root_func(const NodePath &p_scene_path, const String &p_scene_from) { + + live_edit_root = p_scene_path; + live_edit_scene = p_scene_from; +} + +void LiveEditor::_create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_parent)) + continue; + Node *n2 = n->get_node(p_parent); + + Node *no = Object::cast_to<Node>(ClassDB::instance(p_type)); + if (!no) { + continue; + } + + no->set_name(p_name); + n2->add_child(no); + } +} +void LiveEditor::_instance_node_func(const NodePath &p_parent, const String &p_path, const String &p_name) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Ref<PackedScene> ps = ResourceLoader::load(p_path); + + if (!ps.is_valid()) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_parent)) + continue; + Node *n2 = n->get_node(p_parent); + + Node *no = ps->instance(); + if (!no) { + continue; + } + + no->set_name(p_name); + n2->add_child(no); + } +} +void LiveEditor::_remove_node_func(const NodePath &p_at) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F;) { + + Set<Node *>::Element *N = F->next(); + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_at)) + continue; + Node *n2 = n->get_node(p_at); + + memdelete(n2); + + F = N; + } +} +void LiveEditor::_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_keep_id) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F;) { + + Set<Node *>::Element *N = F->next(); + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_at)) + continue; + + Node *n2 = n->get_node(p_at); + + n2->get_parent()->remove_child(n2); + + live_edit_remove_list[n][p_keep_id] = n2; + + F = N; + } +} +void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_at_pos) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F;) { + + Set<Node *>::Element *N = F->next(); + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_at)) + continue; + Node *n2 = n->get_node(p_at); + + Map<Node *, Map<ObjectID, Node *> >::Element *EN = live_edit_remove_list.find(n); + + if (!EN) + continue; + + Map<ObjectID, Node *>::Element *FN = EN->get().find(p_id); + + if (!FN) + continue; + n2->add_child(FN->get()); + + EN->get().erase(FN); + + if (EN->get().size() == 0) { + live_edit_remove_list.erase(EN); + } + + F = N; + } +} +void LiveEditor::_duplicate_node_func(const NodePath &p_at, const String &p_new_name) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_at)) + continue; + Node *n2 = n->get_node(p_at); + + Node *dup = n2->duplicate(Node::DUPLICATE_SIGNALS | Node::DUPLICATE_GROUPS | Node::DUPLICATE_SCRIPTS); + + if (!dup) + continue; + + dup->set_name(p_new_name); + n2->get_parent()->add_child(dup); + } +} +void LiveEditor::_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) { + SceneTree *scene_tree = SceneTree::get_singleton(); + if (!scene_tree) + return; + + Node *base = NULL; + if (scene_tree->root->has_node(live_edit_root)) + base = scene_tree->root->get_node(live_edit_root); + + Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); + if (!E) + return; //scene not editable + + for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { + + Node *n = F->get(); + + if (base && !base->is_a_parent_of(n)) + continue; + + if (!n->has_node(p_at)) + continue; + Node *nfrom = n->get_node(p_at); + + if (!n->has_node(p_new_place)) + continue; + Node *nto = n->get_node(p_new_place); + + nfrom->get_parent()->remove_child(nfrom); + nfrom->set_name(p_new_name); + + nto->add_child(nfrom); + if (p_at_pos >= 0) + nto->move_child(nfrom, p_at_pos); + } +} + +#endif diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h new file mode 100644 index 0000000000..d22f8e8e18 --- /dev/null +++ b/scene/debugger/scene_debugger.h @@ -0,0 +1,151 @@ +/*************************************************************************/ +/* scene_debugger.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SCENE_DEBUGGER_H +#define SCENE_DEBUGGER_H + +#include "core/array.h" +#include "core/object.h" +#include "core/pair.h" +#include "core/script_language.h" +#include "core/ustring.h" + +class SceneDebugger { + +public: + static void initialize(); + static void deinitialize(); + +#ifdef DEBUG_ENABLED +private: + static void _save_node(ObjectID id, const String &p_path); + static void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value); + static void _send_object_id(ObjectID p_id, int p_max_size = 1 << 20); + +public: + static Error parse_message(const String &p_msg, const Array &p_args); + static void add_to_cache(const String &p_filename, Node *p_node); + static void remove_from_cache(const String &p_filename, Node *p_node); +#endif +}; + +#ifdef DEBUG_ENABLED +class SceneDebuggerObject { + +private: + void _parse_script_properties(Script *p_script, ScriptInstance *p_instance); + +public: + typedef Pair<PropertyInfo, Variant> SceneDebuggerProperty; + ObjectID id; + String class_name; + List<SceneDebuggerProperty> properties; + + SceneDebuggerObject(ObjectID p_id); + SceneDebuggerObject() {} + + void serialize(Array &r_arr, int p_max_size = 1 << 20); + void deserialize(const Array &p_arr); +}; + +class SceneDebuggerTree { + +public: + struct RemoteNode { + int child_count; + String name; + String type_name; + ObjectID id; + + RemoteNode(int p_child, const String &p_name, const String &p_type, ObjectID p_id) { + child_count = p_child; + name = p_name; + type_name = p_type; + id = p_id; + } + + RemoteNode() {} + }; + + List<RemoteNode> nodes; + + void serialize(Array &r_arr); + void deserialize(const Array &p_arr); + SceneDebuggerTree(Node *p_root); + SceneDebuggerTree(){}; +}; + +class LiveEditor { + +private: + friend class SceneDebugger; + Map<int, NodePath> live_edit_node_path_cache; + Map<int, String> live_edit_resource_cache; + + NodePath live_edit_root; + String live_edit_scene; + + Map<String, Set<Node *> > live_scene_edit_cache; + Map<Node *, Map<ObjectID, Node *> > live_edit_remove_list; + + void _send_tree(); + + void _node_path_func(const NodePath &p_path, int p_id); + void _res_path_func(const String &p_path, int p_id); + + void _node_set_func(int p_id, const StringName &p_prop, const Variant &p_value); + void _node_set_res_func(int p_id, const StringName &p_prop, const String &p_value); + void _node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE); + void _res_set_func(int p_id, const StringName &p_prop, const Variant &p_value); + void _res_set_res_func(int p_id, const StringName &p_prop, const String &p_value); + void _res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE); + void _root_func(const NodePath &p_scene_path, const String &p_scene_from); + + void _create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name); + void _instance_node_func(const NodePath &p_parent, const String &p_path, const String &p_name); + void _remove_node_func(const NodePath &p_at); + void _remove_and_keep_node_func(const NodePath &p_at, ObjectID p_keep_id); + void _restore_node_func(ObjectID p_id, const NodePath &p_at, int p_at_pos); + void _duplicate_node_func(const NodePath &p_at, const String &p_new_name); + void _reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos); + + LiveEditor() { + singleton = this; + live_edit_root = NodePath("/root"); + }; + + static LiveEditor *singleton; + +public: + static LiveEditor *get_singleton(); +}; +#endif + +#endif diff --git a/scene/debugger/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp deleted file mode 100644 index 0a075df060..0000000000 --- a/scene/debugger/script_debugger_remote.cpp +++ /dev/null @@ -1,1280 +0,0 @@ -/*************************************************************************/ -/* script_debugger_remote.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "script_debugger_remote.h" - -#include "core/engine.h" -#include "core/io/ip.h" -#include "core/io/marshalls.h" -#include "core/os/input.h" -#include "core/os/os.h" -#include "core/project_settings.h" -#include "scene/main/node.h" -#include "scene/main/scene_tree.h" -#include "scene/main/viewport.h" -#include "scene/resources/packed_scene.h" -#include "servers/visual_server.h" - -void ScriptDebuggerRemote::_send_video_memory() { - - List<ResourceUsage> usage; - if (resource_usage_func) - resource_usage_func(&usage); - - usage.sort(); - - packet_peer_stream->put_var("message:video_mem"); - packet_peer_stream->put_var(usage.size() * 4); - - for (List<ResourceUsage>::Element *E = usage.front(); E; E = E->next()) { - - packet_peer_stream->put_var(E->get().path); - packet_peer_stream->put_var(E->get().type); - packet_peer_stream->put_var(E->get().format); - packet_peer_stream->put_var(E->get().vram); - } -} - -Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_port) { - - IP_Address ip; - if (p_host.is_valid_ip_address()) - ip = p_host; - else - ip = IP::get_singleton()->resolve_hostname(p_host); - - int port = p_port; - - const int tries = 6; - int waits[tries] = { 1, 10, 100, 1000, 1000, 1000 }; - - tcp_client->connect_to_host(ip, port); - - for (int i = 0; i < tries; i++) { - - if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) { - print_verbose("Remote Debugger: Connected!"); - break; - } else { - - const int ms = waits[i]; - OS::get_singleton()->delay_usec(ms * 1000); - print_verbose("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec."); - }; - }; - - if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) { - - ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + "."); - return FAILED; - }; - - packet_peer_stream->set_stream_peer(tcp_client); - - return OK; -} - -void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_variable) { - - packet_peer_stream->put_var(p_name); - - Variant var = p_variable; - if (p_variable.get_type() == Variant::OBJECT && !ObjectDB::instance_validate(p_variable)) { - var = Variant(); - } - - int len = 0; - Error err = encode_variant(var, NULL, len, true); - if (err != OK) - ERR_PRINT("Failed to encode variant."); - - if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size - packet_peer_stream->put_var(Variant()); - } else { - packet_peer_stream->put_var(var); - } -} - -void ScriptDebuggerRemote::_save_node(ObjectID id, const String &p_path) { - - Node *node = Object::cast_to<Node>(ObjectDB::get_instance(id)); - ERR_FAIL_COND(!node); - - Ref<PackedScene> ps = memnew(PackedScene); - ps->pack(node); - ResourceSaver::save(p_path, ps); -} - -void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue, bool p_is_error_breakpoint) { - - //this function is called when there is a debugger break (bug on script) - //or when execution is paused from editor - - if (skip_breakpoints && !p_is_error_breakpoint) - return; - - ERR_FAIL_COND_MSG(!tcp_client->is_connected_to_host(), "Script Debugger failed to connect, but being used anyway."); - - packet_peer_stream->put_var("debug_enter"); - packet_peer_stream->put_var(2); - packet_peer_stream->put_var(p_can_continue); - packet_peer_stream->put_var(p_script->debug_get_error()); - - skip_profile_frame = true; // to avoid super long frame time for the frame - - Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode(); - if (mouse_mode != Input::MOUSE_MODE_VISIBLE) - Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); - - uint64_t loop_begin_usec = 0; - uint64_t loop_time_sec = 0; - while (true) { - loop_begin_usec = OS::get_singleton()->get_ticks_usec(); - - _get_output(); - - if (packet_peer_stream->get_available_packet_count() > 0) { - - Variant var; - Error err = packet_peer_stream->get_var(var); - - ERR_CONTINUE(err != OK); - ERR_CONTINUE(var.get_type() != Variant::ARRAY); - - Array cmd = var; - - ERR_CONTINUE(cmd.size() == 0); - ERR_CONTINUE(cmd[0].get_type() != Variant::STRING); - - String command = cmd[0]; - - if (command == "get_stack_dump") { - - packet_peer_stream->put_var("stack_dump"); - int slc = p_script->debug_get_stack_level_count(); - packet_peer_stream->put_var(slc); - - for (int i = 0; i < slc; i++) { - - Dictionary d; - d["file"] = p_script->debug_get_stack_level_source(i); - d["line"] = p_script->debug_get_stack_level_line(i); - d["function"] = p_script->debug_get_stack_level_function(i); - //d["id"]=p_script->debug_get_stack_level_ - d["id"] = 0; - - packet_peer_stream->put_var(d); - } - - } else if (command == "get_stack_frame_vars") { - - cmd.remove(0); - ERR_CONTINUE(cmd.size() != 1); - int lv = cmd[0]; - - List<String> members; - List<Variant> member_vals; - if (ScriptInstance *inst = p_script->debug_get_stack_level_instance(lv)) { - members.push_back("self"); - member_vals.push_back(inst->get_owner()); - } - p_script->debug_get_stack_level_members(lv, &members, &member_vals); - ERR_CONTINUE(members.size() != member_vals.size()); - - List<String> locals; - List<Variant> local_vals; - p_script->debug_get_stack_level_locals(lv, &locals, &local_vals); - ERR_CONTINUE(locals.size() != local_vals.size()); - - List<String> globals; - List<Variant> globals_vals; - p_script->debug_get_globals(&globals, &globals_vals); - ERR_CONTINUE(globals.size() != globals_vals.size()); - - packet_peer_stream->put_var("stack_frame_vars"); - packet_peer_stream->put_var(3 + (locals.size() + members.size() + globals.size()) * 2); - - { //locals - packet_peer_stream->put_var(locals.size()); - - List<String>::Element *E = locals.front(); - List<Variant>::Element *F = local_vals.front(); - - while (E) { - _put_variable(E->get(), F->get()); - - E = E->next(); - F = F->next(); - } - } - - { //members - packet_peer_stream->put_var(members.size()); - - List<String>::Element *E = members.front(); - List<Variant>::Element *F = member_vals.front(); - - while (E) { - - _put_variable(E->get(), F->get()); - - E = E->next(); - F = F->next(); - } - } - - { //globals - packet_peer_stream->put_var(globals.size()); - - List<String>::Element *E = globals.front(); - List<Variant>::Element *F = globals_vals.front(); - - while (E) { - _put_variable(E->get(), F->get()); - - E = E->next(); - F = F->next(); - } - } - - } else if (command == "step") { - - set_depth(-1); - set_lines_left(1); - break; - } else if (command == "next") { - - set_depth(0); - set_lines_left(1); - break; - - } else if (command == "continue") { - set_depth(-1); - set_lines_left(-1); - OS::get_singleton()->move_window_to_foreground(); - break; - } else if (command == "break") { - ERR_PRINT("Got break when already broke!"); - break; - } else if (command == "request_scene_tree") { - -#ifdef DEBUG_ENABLED - if (scene_tree) - scene_tree->_debugger_request_tree(); -#endif - } else if (command == "request_video_mem") { - - _send_video_memory(); - } else if (command == "inspect_object") { - - ObjectID id = cmd[1]; - _send_object_id(id); - } else if (command == "set_object_property") { - - _set_object_property(cmd[1], cmd[2], cmd[3]); - - } else if (command == "override_camera_2D:set") { - bool enforce = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->enable_canvas_transform_override(enforce); - } - } else if (command == "override_camera_2D:transform") { - Transform2D transform = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->set_canvas_transform_override(transform); - } - } else if (command == "override_camera_3D:set") { - bool enable = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->enable_camera_override(enable); - } - } else if (command == "override_camera_3D:transform") { - Transform transform = cmd[1]; - bool is_perspective = cmd[2]; - float size_or_fov = cmd[3]; - float near = cmd[4]; - float far = cmd[5]; - - if (scene_tree) { - if (is_perspective) { - scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far); - } else { - scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far); - } - scene_tree->get_root()->set_camera_override_transform(transform); - } - - } else if (command == "reload_scripts") { - reload_all_scripts = true; - } else if (command == "breakpoint") { - - bool set = cmd[3]; - if (set) - insert_breakpoint(cmd[2], cmd[1]); - else - remove_breakpoint(cmd[2], cmd[1]); - - } else if (command == "save_node") { - _save_node(cmd[1], cmd[2]); - } else if (command == "set_skip_breakpoints") { - skip_breakpoints = cmd[1]; - } else { - _parse_live_edit(cmd); - } - - } else { - OS::get_singleton()->delay_usec(10000); - OS::get_singleton()->process_and_drop_events(); - } - - // This is for the camera override to stay live even when the game is paused from the editor - loop_time_sec = (OS::get_singleton()->get_ticks_usec() - loop_begin_usec) / 1000000.0f; - VisualServer::get_singleton()->sync(); - if (VisualServer::get_singleton()->has_changed()) { - VisualServer::get_singleton()->draw(true, loop_time_sec * Engine::get_singleton()->get_time_scale()); - } - } - - packet_peer_stream->put_var("debug_exit"); - packet_peer_stream->put_var(0); - - if (mouse_mode != Input::MOUSE_MODE_VISIBLE) - Input::get_singleton()->set_mouse_mode(mouse_mode); -} - -void ScriptDebuggerRemote::_get_output() { - - mutex->lock(); - if (output_strings.size()) { - - locking = true; - packet_peer_stream->put_var("output"); - packet_peer_stream->put_var(output_strings.size()); - - while (output_strings.size()) { - - packet_peer_stream->put_var(output_strings.front()->get()); - output_strings.pop_front(); - } - locking = false; - } - - if (n_messages_dropped > 0) { - Message msg; - msg.message = "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped."; - messages.push_back(msg); - n_messages_dropped = 0; - } - - while (messages.size()) { - locking = true; - packet_peer_stream->put_var("message:" + messages.front()->get().message); - packet_peer_stream->put_var(messages.front()->get().data.size()); - for (int i = 0; i < messages.front()->get().data.size(); i++) { - packet_peer_stream->put_var(messages.front()->get().data[i]); - } - messages.pop_front(); - locking = false; - } - - if (n_errors_dropped == 1) { - // Only print one message about dropping per second - OutputError oe; - oe.error = "TOO_MANY_ERRORS"; - oe.error_descr = "Too many errors! Ignoring errors for up to 1 second."; - oe.warning = false; - uint64_t time = OS::get_singleton()->get_ticks_msec(); - oe.hr = time / 3600000; - oe.min = (time / 60000) % 60; - oe.sec = (time / 1000) % 60; - oe.msec = time % 1000; - errors.push_back(oe); - } - - if (n_warnings_dropped == 1) { - // Only print one message about dropping per second - OutputError oe; - oe.error = "TOO_MANY_WARNINGS"; - oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second."; - oe.warning = true; - uint64_t time = OS::get_singleton()->get_ticks_msec(); - oe.hr = time / 3600000; - oe.min = (time / 60000) % 60; - oe.sec = (time / 1000) % 60; - oe.msec = time % 1000; - errors.push_back(oe); - } - - while (errors.size()) { - locking = true; - packet_peer_stream->put_var("error"); - OutputError oe = errors.front()->get(); - - packet_peer_stream->put_var(oe.callstack.size() + 2); - - Array error_data; - - error_data.push_back(oe.hr); - error_data.push_back(oe.min); - error_data.push_back(oe.sec); - error_data.push_back(oe.msec); - error_data.push_back(oe.source_func); - error_data.push_back(oe.source_file); - error_data.push_back(oe.source_line); - error_data.push_back(oe.error); - error_data.push_back(oe.error_descr); - error_data.push_back(oe.warning); - packet_peer_stream->put_var(error_data); - packet_peer_stream->put_var(oe.callstack.size()); - for (int i = 0; i < oe.callstack.size(); i++) { - packet_peer_stream->put_var(oe.callstack[i]); - } - - errors.pop_front(); - locking = false; - } - mutex->unlock(); -} - -void ScriptDebuggerRemote::line_poll() { - - //the purpose of this is just processing events every now and then when the script might get too busy - //otherwise bugs like infinite loops can't be caught - if (poll_every % 2048 == 0) - _poll_events(); - poll_every++; -} - -void ScriptDebuggerRemote::_err_handler(void *ud, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) { - - if (p_type == ERR_HANDLER_SCRIPT) - return; //ignore script errors, those go through debugger - - Vector<ScriptLanguage::StackInfo> si; - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - si = ScriptServer::get_language(i)->debug_get_current_stack_info(); - if (si.size()) - break; - } - - ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)ud; - sdr->send_error(p_func, p_file, p_line, p_err, p_descr, p_type, si); -} - -bool ScriptDebuggerRemote::_parse_live_edit(const Array &p_command) { - -#ifdef DEBUG_ENABLED - - String cmdstr = p_command[0]; - if (!scene_tree || !cmdstr.begins_with("live_")) - return false; - - if (cmdstr == "live_set_root") { - - scene_tree->_live_edit_root_func(p_command[1], p_command[2]); - - } else if (cmdstr == "live_node_path") { - - scene_tree->_live_edit_node_path_func(p_command[1], p_command[2]); - - } else if (cmdstr == "live_res_path") { - - scene_tree->_live_edit_res_path_func(p_command[1], p_command[2]); - - } else if (cmdstr == "live_node_prop_res") { - - scene_tree->_live_edit_node_set_res_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_node_prop") { - - scene_tree->_live_edit_node_set_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_res_prop_res") { - - scene_tree->_live_edit_res_set_res_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_res_prop") { - - scene_tree->_live_edit_res_set_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_node_call") { - - scene_tree->_live_edit_node_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]); - - } else if (cmdstr == "live_res_call") { - - scene_tree->_live_edit_res_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]); - - } else if (cmdstr == "live_create_node") { - - scene_tree->_live_edit_create_node_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_instance_node") { - - scene_tree->_live_edit_instance_node_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_remove_node") { - - scene_tree->_live_edit_remove_node_func(p_command[1]); - - } else if (cmdstr == "live_remove_and_keep_node") { - - scene_tree->_live_edit_remove_and_keep_node_func(p_command[1], p_command[2]); - - } else if (cmdstr == "live_restore_node") { - - scene_tree->_live_edit_restore_node_func(p_command[1], p_command[2], p_command[3]); - - } else if (cmdstr == "live_duplicate_node") { - - scene_tree->_live_edit_duplicate_node_func(p_command[1], p_command[2]); - - } else if (cmdstr == "live_reparent_node") { - - scene_tree->_live_edit_reparent_node_func(p_command[1], p_command[2], p_command[3], p_command[4]); - - } else { - - return false; - } - - return true; -#else - - return false; -#endif -} - -void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { - - Object *obj = ObjectDB::get_instance(p_id); - if (!obj) - return; - - typedef Pair<PropertyInfo, Variant> PropertyDesc; - List<PropertyDesc> properties; - - if (ScriptInstance *si = obj->get_script_instance()) { - if (!si->get_script().is_null()) { - - typedef Map<const Script *, Set<StringName> > ScriptMemberMap; - typedef Map<const Script *, Map<StringName, Variant> > ScriptConstantsMap; - - ScriptMemberMap members; - members[si->get_script().ptr()] = Set<StringName>(); - si->get_script()->get_members(&(members[si->get_script().ptr()])); - - ScriptConstantsMap constants; - constants[si->get_script().ptr()] = Map<StringName, Variant>(); - si->get_script()->get_constants(&(constants[si->get_script().ptr()])); - - Ref<Script> base = si->get_script()->get_base_script(); - while (base.is_valid()) { - - members[base.ptr()] = Set<StringName>(); - base->get_members(&(members[base.ptr()])); - - constants[base.ptr()] = Map<StringName, Variant>(); - base->get_constants(&(constants[base.ptr()])); - - base = base->get_base_script(); - } - - for (ScriptMemberMap::Element *sm = members.front(); sm; sm = sm->next()) { - for (Set<StringName>::Element *E = sm->get().front(); E; E = E->next()) { - Variant m; - if (si->get(E->get(), m)) { - String script_path = sm->key() == si->get_script().ptr() ? "" : sm->key()->get_path().get_file() + "/"; - PropertyInfo pi(m.get_type(), "Members/" + script_path + E->get()); - properties.push_back(PropertyDesc(pi, m)); - } - } - } - - for (ScriptConstantsMap::Element *sc = constants.front(); sc; sc = sc->next()) { - for (Map<StringName, Variant>::Element *E = sc->get().front(); E; E = E->next()) { - String script_path = sc->key() == si->get_script().ptr() ? "" : sc->key()->get_path().get_file() + "/"; - if (E->value().get_type() == Variant::OBJECT) { - Variant id = ((Object *)E->value())->get_instance_id(); - PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object"); - properties.push_back(PropertyDesc(pi, id)); - } else { - PropertyInfo pi(E->value().get_type(), "Constants/" + script_path + E->key()); - properties.push_back(PropertyDesc(pi, E->value())); - } - } - } - } - } - - if (Node *node = Object::cast_to<Node>(obj)) { - // in some cases node will not be in tree here - // for instance where it created as variable and not yet added to tree - // in such cases we can't ask for it's path - if (node->is_inside_tree()) { - PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); - properties.push_front(PropertyDesc(pi, node->get_path())); - } else { - PropertyInfo pi(Variant::STRING, String("Node/path")); - properties.push_front(PropertyDesc(pi, "[Orphan]")); - } - - } else if (Resource *res = Object::cast_to<Resource>(obj)) { - if (Script *s = Object::cast_to<Script>(res)) { - Map<StringName, Variant> constants; - s->get_constants(&constants); - for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - if (E->value().get_type() == Variant::OBJECT) { - Variant id = ((Object *)E->value())->get_instance_id(); - PropertyInfo pi(id.get_type(), "Constants/" + E->key(), PROPERTY_HINT_OBJECT_ID, "Object"); - properties.push_front(PropertyDesc(pi, E->value())); - } else { - PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key()); - properties.push_front(PropertyDesc(pi, E->value())); - } - } - } - } - - List<PropertyInfo> pinfo; - obj->get_property_list(&pinfo, true); - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { - properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name))); - } - } - - Array send_props; - for (int i = 0; i < properties.size(); i++) { - const PropertyInfo &pi = properties[i].first; - Variant &var = properties[i].second; - - WeakRef *ref = Object::cast_to<WeakRef>(var); - if (ref) { - var = ref->get_ref(); - } - - RES res = var; - - Array prop; - prop.push_back(pi.name); - prop.push_back(pi.type); - - //only send information that can be sent.. - int len = 0; //test how big is this to encode - encode_variant(var, NULL, len); - if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size - prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG); - prop.push_back(""); - prop.push_back(pi.usage); - prop.push_back(Variant()); - } else { - prop.push_back(pi.hint); - prop.push_back(pi.hint_string); - prop.push_back(pi.usage); - - if (!res.is_null()) { - var = res->get_path(); - } - - prop.push_back(var); - } - send_props.push_back(prop); - } - - packet_peer_stream->put_var("message:inspect_object"); - packet_peer_stream->put_var(3); - packet_peer_stream->put_var(p_id); - packet_peer_stream->put_var(obj->get_class()); - packet_peer_stream->put_var(send_props); -} - -void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) { - - Object *obj = ObjectDB::get_instance(p_id); - if (!obj) - return; - - String prop_name = p_property; - if (p_property.begins_with("Members/")) { - Vector<String> ss = p_property.split("/"); - prop_name = ss[ss.size() - 1]; - } - - obj->set(prop_name, p_value); -} - -void ScriptDebuggerRemote::_poll_events() { - - //this si called from ::idle_poll, happens only when running the game, - //does not get called while on debug break - - while (packet_peer_stream->get_available_packet_count() > 0) { - - _get_output(); - - //send over output_strings - - Variant var; - Error err = packet_peer_stream->get_var(var); - - ERR_CONTINUE(err != OK); - ERR_CONTINUE(var.get_type() != Variant::ARRAY); - - Array cmd = var; - - ERR_CONTINUE(cmd.size() == 0); - ERR_CONTINUE(cmd[0].get_type() != Variant::STRING); - - String command = cmd[0]; - //cmd.remove(0); - - if (command == "break") { - - if (get_break_language()) - debug(get_break_language()); - } else if (command == "request_scene_tree") { - -#ifdef DEBUG_ENABLED - if (scene_tree) - scene_tree->_debugger_request_tree(); -#endif - } else if (command == "request_video_mem") { - - _send_video_memory(); - } else if (command == "inspect_object") { - - ObjectID id = cmd[1]; - _send_object_id(id); - } else if (command == "set_object_property") { - - _set_object_property(cmd[1], cmd[2], cmd[3]); - - } else if (command == "start_profiling") { - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->profiling_start(); - } - - max_frame_functions = cmd[1]; - profiler_function_signature_map.clear(); - profiling = true; - frame_time = 0; - idle_time = 0; - physics_time = 0; - physics_frame_time = 0; - - print_line("PROFILING ALRIGHT!"); - - } else if (command == "stop_profiling") { - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->profiling_stop(); - } - profiling = false; - _send_profiling_data(false); - print_line("PROFILING END!"); - } else if (command == "start_network_profiling") { - - multiplayer->profiling_start(); - profiling_network = true; - } else if (command == "stop_network_profiling") { - - multiplayer->profiling_end(); - profiling_network = false; - } else if (command == "override_camera_2D:set") { - bool enforce = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->enable_canvas_transform_override(enforce); - } - } else if (command == "override_camera_2D:transform") { - Transform2D transform = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->set_canvas_transform_override(transform); - } - } else if (command == "override_camera_3D:set") { - bool enable = cmd[1]; - - if (scene_tree) { - scene_tree->get_root()->enable_camera_override(enable); - } - } else if (command == "override_camera_3D:transform") { - Transform transform = cmd[1]; - bool is_perspective = cmd[2]; - float size_or_fov = cmd[3]; - float near = cmd[4]; - float far = cmd[5]; - - if (scene_tree) { - if (is_perspective) { - scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far); - } else { - scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far); - } - scene_tree->get_root()->set_camera_override_transform(transform); - } - - } else if (command == "reload_scripts") { - reload_all_scripts = true; - } else if (command == "breakpoint") { - - bool set = cmd[3]; - if (set) - insert_breakpoint(cmd[2], cmd[1]); - else - remove_breakpoint(cmd[2], cmd[1]); - } else if (command == "set_skip_breakpoints") { - skip_breakpoints = cmd[1]; - } else { - _parse_live_edit(cmd); - } - } -} - -void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) { - - int ofs = 0; - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - if (p_for_frame) - ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info.write[ofs], profile_info.size() - ofs); - else - ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info.write[ofs], profile_info.size() - ofs); - } - - for (int i = 0; i < ofs; i++) { - profile_info_ptrs.write[i] = &profile_info.write[i]; - } - - SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa; - sa.sort(profile_info_ptrs.ptrw(), ofs); - - int to_send = MIN(ofs, max_frame_functions); - - //check signatures first - uint64_t total_script_time = 0; - - for (int i = 0; i < to_send; i++) { - - if (!profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) { - - int idx = profiler_function_signature_map.size(); - packet_peer_stream->put_var("profile_sig"); - packet_peer_stream->put_var(2); - packet_peer_stream->put_var(profile_info_ptrs[i]->signature); - packet_peer_stream->put_var(idx); - - profiler_function_signature_map[profile_info_ptrs[i]->signature] = idx; - } - - total_script_time += profile_info_ptrs[i]->self_time; - } - - //send frames then - - if (p_for_frame) { - packet_peer_stream->put_var("profile_frame"); - packet_peer_stream->put_var(8 + profile_frame_data.size() * 2 + to_send * 4); - } else { - packet_peer_stream->put_var("profile_total"); - packet_peer_stream->put_var(8 + to_send * 4); - } - - packet_peer_stream->put_var(Engine::get_singleton()->get_frames_drawn()); //total frame time - packet_peer_stream->put_var(frame_time); //total frame time - packet_peer_stream->put_var(idle_time); //idle frame time - packet_peer_stream->put_var(physics_time); //fixed frame time - packet_peer_stream->put_var(physics_frame_time); //fixed frame time - - packet_peer_stream->put_var(USEC_TO_SEC(total_script_time)); //total script execution time - - if (p_for_frame) { - - packet_peer_stream->put_var(profile_frame_data.size()); //how many profile framedatas to send - packet_peer_stream->put_var(to_send); //how many script functions to send - for (int i = 0; i < profile_frame_data.size(); i++) { - - packet_peer_stream->put_var(profile_frame_data[i].name); - packet_peer_stream->put_var(profile_frame_data[i].data); - } - } else { - packet_peer_stream->put_var(0); //how many script functions to send - packet_peer_stream->put_var(to_send); //how many script functions to send - } - - for (int i = 0; i < to_send; i++) { - - int sig_id = -1; - - if (profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) { - sig_id = profiler_function_signature_map[profile_info_ptrs[i]->signature]; - } - - packet_peer_stream->put_var(sig_id); - packet_peer_stream->put_var(profile_info_ptrs[i]->call_count); - packet_peer_stream->put_var(profile_info_ptrs[i]->total_time / 1000000.0); - packet_peer_stream->put_var(profile_info_ptrs[i]->self_time / 1000000.0); - } - - if (p_for_frame) { - profile_frame_data.clear(); - } -} - -void ScriptDebuggerRemote::idle_poll() { - - // this function is called every frame, except when there is a debugger break (::debug() in this class) - // execution stops and remains in the ::debug function - - _get_output(); - - if (requested_quit) { - - packet_peer_stream->put_var("kill_me"); - packet_peer_stream->put_var(0); - requested_quit = false; - } - - if (performance) { - - uint64_t pt = OS::get_singleton()->get_ticks_msec(); - if (pt - last_perf_time > 1000) { - - last_perf_time = pt; - int max = performance->get("MONITOR_MAX"); - Array arr; - arr.resize(max); - for (int i = 0; i < max; i++) { - arr[i] = performance->call("get_monitor", i); - } - packet_peer_stream->put_var("performance"); - packet_peer_stream->put_var(1); - packet_peer_stream->put_var(arr); - } - } - - if (profiling) { - - if (skip_profile_frame) { - skip_profile_frame = false; - } else { - //send profiling info normally - _send_profiling_data(true); - } - } - - if (profiling_network) { - uint64_t pt = OS::get_singleton()->get_ticks_msec(); - if (pt - last_net_bandwidth_time > 200) { - last_net_bandwidth_time = pt; - _send_network_bandwidth_usage(); - } - if (pt - last_net_prof_time > 100) { - last_net_prof_time = pt; - _send_network_profiling_data(); - } - } - - if (reload_all_scripts) { - - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->reload_all_scripts(); - } - reload_all_scripts = false; - } - - _poll_events(); -} - -void ScriptDebuggerRemote::_send_network_profiling_data() { - ERR_FAIL_COND(multiplayer.is_null()); - - int n_nodes = multiplayer->get_profiling_frame(&network_profile_info.write[0]); - - packet_peer_stream->put_var("network_profile"); - packet_peer_stream->put_var(n_nodes * 6); - for (int i = 0; i < n_nodes; ++i) { - packet_peer_stream->put_var(network_profile_info[i].node); - packet_peer_stream->put_var(network_profile_info[i].node_path); - packet_peer_stream->put_var(network_profile_info[i].incoming_rpc); - packet_peer_stream->put_var(network_profile_info[i].incoming_rset); - packet_peer_stream->put_var(network_profile_info[i].outgoing_rpc); - packet_peer_stream->put_var(network_profile_info[i].outgoing_rset); - } -} - -void ScriptDebuggerRemote::_send_network_bandwidth_usage() { - ERR_FAIL_COND(multiplayer.is_null()); - - int incoming_bandwidth = multiplayer->get_incoming_bandwidth_usage(); - int outgoing_bandwidth = multiplayer->get_outgoing_bandwidth_usage(); - - packet_peer_stream->put_var("network_bandwidth"); - packet_peer_stream->put_var(2); - packet_peer_stream->put_var(incoming_bandwidth); - packet_peer_stream->put_var(outgoing_bandwidth); -} - -void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) { - - mutex->lock(); - if (!locking && tcp_client->is_connected_to_host()) { - - if (messages.size() >= max_messages_per_frame) { - n_messages_dropped++; - } else { - Message msg; - msg.message = p_message; - msg.data = p_args; - messages.push_back(msg); - } - } - mutex->unlock(); -} - -void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info) { - - OutputError oe; - oe.error = p_err; - oe.error_descr = p_descr; - oe.source_file = p_file; - oe.source_line = p_line; - oe.source_func = p_func; - oe.warning = p_type == ERR_HANDLER_WARNING; - uint64_t time = OS::get_singleton()->get_ticks_msec(); - oe.hr = time / 3600000; - oe.min = (time / 60000) % 60; - oe.sec = (time / 1000) % 60; - oe.msec = time % 1000; - Array cstack; - - uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000; - msec_count += ticks - last_msec; - last_msec = ticks; - - if (msec_count > 1000) { - msec_count = 0; - - err_count = 0; - n_errors_dropped = 0; - warn_count = 0; - n_warnings_dropped = 0; - } - - cstack.resize(p_stack_info.size() * 3); - for (int i = 0; i < p_stack_info.size(); i++) { - cstack[i * 3 + 0] = p_stack_info[i].file; - cstack[i * 3 + 1] = p_stack_info[i].func; - cstack[i * 3 + 2] = p_stack_info[i].line; - } - - oe.callstack = cstack; - if (oe.warning) { - warn_count++; - } else { - err_count++; - } - - mutex->lock(); - - if (!locking && tcp_client->is_connected_to_host()) { - - if (oe.warning) { - if (warn_count > max_warnings_per_second) { - n_warnings_dropped++; - } else { - errors.push_back(oe); - } - } else { - if (err_count > max_errors_per_second) { - n_errors_dropped++; - } else { - errors.push_back(oe); - } - } - } - - mutex->unlock(); -} - -void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) { - - ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)p_this; - - uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000; - sdr->msec_count += ticks - sdr->last_msec; - sdr->last_msec = ticks; - - if (sdr->msec_count > 1000) { - sdr->char_count = 0; - sdr->msec_count = 0; - } - - String s = p_string; - int allowed_chars = MIN(MAX(sdr->max_cps - sdr->char_count, 0), s.length()); - - if (allowed_chars == 0) - return; - - if (allowed_chars < s.length()) { - s = s.substr(0, allowed_chars); - } - - sdr->char_count += allowed_chars; - bool overflowed = sdr->char_count >= sdr->max_cps; - - sdr->mutex->lock(); - if (!sdr->locking && sdr->tcp_client->is_connected_to_host()) { - - if (overflowed) - s += "[...]"; - - sdr->output_strings.push_back(s); - - if (overflowed) { - sdr->output_strings.push_back("[output overflow, print less text!]"); - } - } - sdr->mutex->unlock(); -} - -void ScriptDebuggerRemote::request_quit() { - - requested_quit = true; -} - -void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { - multiplayer = p_multiplayer; -} - -bool ScriptDebuggerRemote::is_profiling() const { - - return profiling; -} -void ScriptDebuggerRemote::add_profiling_frame_data(const StringName &p_name, const Array &p_data) { - - int idx = -1; - for (int i = 0; i < profile_frame_data.size(); i++) { - if (profile_frame_data[i].name == p_name) { - idx = i; - break; - } - } - - FrameData fd; - fd.name = p_name; - fd.data = p_data; - - if (idx == -1) { - profile_frame_data.push_back(fd); - } else { - profile_frame_data.write[idx] = fd; - } -} - -void ScriptDebuggerRemote::profiling_start() { - //ignores this, uses it via connection -} - -void ScriptDebuggerRemote::profiling_end() { - //ignores this, uses it via connection -} - -void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) { - - frame_time = p_frame_time; - idle_time = p_idle_time; - physics_time = p_physics_time; - physics_frame_time = p_physics_frame_time; -} - -void ScriptDebuggerRemote::set_skip_breakpoints(bool p_skip_breakpoints) { - skip_breakpoints = p_skip_breakpoints; -} - -ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL; - -ScriptDebuggerRemote::ScriptDebuggerRemote() : - profiling(false), - profiling_network(false), - max_frame_functions(16), - skip_profile_frame(false), - reload_all_scripts(false), - tcp_client(Ref<StreamPeerTCP>(memnew(StreamPeerTCP))), - packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))), - last_perf_time(0), - last_net_prof_time(0), - last_net_bandwidth_time(0), - performance(Engine::get_singleton()->get_singleton_object("Performance")), - requested_quit(false), - mutex(Mutex::create()), - max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")), - n_messages_dropped(0), - max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")), - max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")), - n_errors_dropped(0), - max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")), - char_count(0), - err_count(0), - warn_count(0), - last_msec(0), - msec_count(0), - locking(false), - poll_every(0), - scene_tree(NULL) { - - packet_peer_stream->set_stream_peer(tcp_client); - packet_peer_stream->set_output_buffer_max_size((1024 * 1024 * 8) - 4); // 8 MiB should be way more than enough, minus 4 bytes for separator. - - phl.printfunc = _print_handler; - phl.userdata = this; - add_print_handler(&phl); - - eh.errfunc = _err_handler; - eh.userdata = this; - add_error_handler(&eh); - - profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions")); - network_profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions")); - profile_info_ptrs.resize(profile_info.size()); -} - -ScriptDebuggerRemote::~ScriptDebuggerRemote() { - - remove_print_handler(&phl); - remove_error_handler(&eh); - memdelete(mutex); -} diff --git a/scene/debugger/script_debugger_remote.h b/scene/debugger/script_debugger_remote.h deleted file mode 100644 index 2c0dccdaf7..0000000000 --- a/scene/debugger/script_debugger_remote.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************/ -/* script_debugger_remote.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SCRIPT_DEBUGGER_REMOTE_H -#define SCRIPT_DEBUGGER_REMOTE_H - -#include "core/io/packet_peer.h" -#include "core/io/stream_peer_tcp.h" -#include "core/list.h" -#include "core/os/os.h" -#include "core/script_language.h" - -class SceneTree; - -class ScriptDebuggerRemote : public ScriptDebugger { - - struct Message { - - String message; - Array data; - }; - - struct ProfileInfoSort { - - bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const { - return A->total_time < B->total_time; - } - }; - - Vector<ScriptLanguage::ProfilingInfo> profile_info; - Vector<ScriptLanguage::ProfilingInfo *> profile_info_ptrs; - Vector<MultiplayerAPI::ProfilingInfo> network_profile_info; - - Map<StringName, int> profiler_function_signature_map; - float frame_time, idle_time, physics_time, physics_frame_time; - - bool profiling; - bool profiling_network; - int max_frame_functions; - bool skip_profile_frame; - bool reload_all_scripts; - - Ref<StreamPeerTCP> tcp_client; - Ref<PacketPeerStream> packet_peer_stream; - - uint64_t last_perf_time; - uint64_t last_net_prof_time; - uint64_t last_net_bandwidth_time; - Object *performance; - bool requested_quit; - Mutex *mutex; - - struct OutputError { - - int hr; - int min; - int sec; - int msec; - String source_file; - String source_func; - int source_line; - String error; - String error_descr; - bool warning; - Array callstack; - }; - - List<String> output_strings; - List<Message> messages; - int max_messages_per_frame; - int n_messages_dropped; - List<OutputError> errors; - int max_errors_per_second; - int max_warnings_per_second; - int n_errors_dropped; - int n_warnings_dropped; - - int max_cps; - int char_count; - int err_count; - int warn_count; - uint64_t last_msec; - uint64_t msec_count; - - bool locking; //hack to avoid a deadloop - static void _print_handler(void *p_this, const String &p_string, bool p_error); - - PrintHandlerList phl; - - void _get_output(); - void _poll_events(); - uint32_t poll_every; - - SceneTree *scene_tree; - - bool _parse_live_edit(const Array &p_command); - - void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value); - - void _send_object_id(ObjectID p_id); - void _send_video_memory(); - - Ref<MultiplayerAPI> multiplayer; - - ErrorHandlerList eh; - static void _err_handler(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type); - - void _send_profiling_data(bool p_for_frame); - void _send_network_profiling_data(); - void _send_network_bandwidth_usage(); - - struct FrameData { - - StringName name; - Array data; - }; - - Vector<FrameData> profile_frame_data; - - void _put_variable(const String &p_name, const Variant &p_variable); - - void _save_node(ObjectID id, const String &p_path); - - bool skip_breakpoints; - -public: - struct ResourceUsage { - - String path; - String format; - String type; - RID id; - int vram; - bool operator<(const ResourceUsage &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; } - }; - - typedef void (*ResourceUsageFunc)(List<ResourceUsage> *); - - static ResourceUsageFunc resource_usage_func; - - Error connect_to_host(const String &p_host, uint16_t p_port); - virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true, bool p_is_error_breakpoint = false); - virtual void idle_poll(); - virtual void line_poll(); - - virtual bool is_remote() const { return true; } - virtual void request_quit(); - - virtual void send_message(const String &p_message, const Array &p_args); - virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info); - - virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer); - - virtual bool is_profiling() const; - virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data); - - virtual void profiling_start(); - virtual void profiling_end(); - virtual void profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time); - - virtual void set_skip_breakpoints(bool p_skip_breakpoints); - - void set_scene_tree(SceneTree *p_scene_tree) { scene_tree = p_scene_tree; }; - - ScriptDebuggerRemote(); - ~ScriptDebuggerRemote(); -}; - -#endif // SCRIPT_DEBUGGER_REMOTE_H diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 6f3d8c61cf..784d298bff 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -40,7 +40,7 @@ Size2 Button::get_minimum_size() const { minsize.width = 0; if (!expand_icon) { - Ref<Texture> _icon; + Ref<Texture2D> _icon; if (icon.is_null() && has_icon("icon")) _icon = Control::get_icon("icon"); else @@ -106,7 +106,7 @@ void Button::_notification(int p_what) { break; } - FALLTHROUGH; + [[fallthrough]]; } case DRAW_PRESSED: { @@ -150,7 +150,7 @@ void Button::_notification(int p_what) { } Ref<Font> font = get_font("font"); - Ref<Texture> _icon; + Ref<Texture2D> _icon; if (icon.is_null() && has_icon("icon")) _icon = Control::get_icon("icon"); else @@ -249,7 +249,7 @@ String Button::get_text() const { return text; } -void Button::set_icon(const Ref<Texture> &p_icon) { +void Button::set_icon(const Ref<Texture2D> &p_icon) { if (icon == p_icon) return; @@ -259,7 +259,7 @@ void Button::set_icon(const Ref<Texture> &p_icon) { minimum_size_changed(); } -Ref<Texture> Button::get_icon() const { +Ref<Texture2D> Button::get_icon() const { return icon; } @@ -331,7 +331,7 @@ void Button::_bind_methods() { BIND_ENUM_CONSTANT(ALIGN_RIGHT); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_button_icon", "get_button_icon"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "get_clip_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_text_align", "get_text_align"); diff --git a/scene/gui/button.h b/scene/gui/button.h index e975dc52a5..3135b98578 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -48,7 +48,7 @@ private: bool flat; String text; String xl_text; - Ref<Texture> icon; + Ref<Texture2D> icon; bool expand_icon; bool clip_text; TextAlign align; @@ -65,8 +65,8 @@ public: void set_text(const String &p_text); String get_text() const; - void set_icon(const Ref<Texture> &p_icon); - Ref<Texture> get_icon() const; + void set_icon(const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_icon() const; void set_expand_icon(bool p_expand_icon); bool is_expand_icon() const; diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 443121db32..89bd8ab0dd 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -33,10 +33,10 @@ #include "servers/visual_server.h" Size2 CheckBox::get_icon_size() const { - Ref<Texture> checked = Control::get_icon("checked"); - Ref<Texture> unchecked = Control::get_icon("unchecked"); - Ref<Texture> radio_checked = Control::get_icon("radio_checked"); - Ref<Texture> radio_unchecked = Control::get_icon("radio_unchecked"); + Ref<Texture2D> checked = Control::get_icon("checked"); + Ref<Texture2D> unchecked = Control::get_icon("unchecked"); + Ref<Texture2D> radio_checked = Control::get_icon("radio_checked"); + Ref<Texture2D> radio_unchecked = Control::get_icon("radio_unchecked"); Size2 tex_size = Size2(0, 0); if (!checked.is_null()) @@ -73,8 +73,8 @@ void CheckBox::_notification(int p_what) { RID ci = get_canvas_item(); - Ref<Texture> on = Control::get_icon(is_radio() ? "radio_checked" : "checked"); - Ref<Texture> off = Control::get_icon(is_radio() ? "radio_unchecked" : "unchecked"); + Ref<Texture2D> on = Control::get_icon(is_radio() ? "radio_checked" : "checked"); + Ref<Texture2D> off = Control::get_icon(is_radio() ? "radio_unchecked" : "unchecked"); Ref<StyleBox> sb = get_stylebox("normal"); Vector2 ofs; diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp index 9d6df94cce..0b093ce850 100644 --- a/scene/gui/check_button.cpp +++ b/scene/gui/check_button.cpp @@ -35,8 +35,8 @@ Size2 CheckButton::get_icon_size() const { - Ref<Texture> on = Control::get_icon(is_disabled() ? "on_disabled" : "on"); - Ref<Texture> off = Control::get_icon(is_disabled() ? "off_disabled" : "off"); + Ref<Texture2D> on = Control::get_icon(is_disabled() ? "on_disabled" : "on"); + Ref<Texture2D> off = Control::get_icon(is_disabled() ? "off_disabled" : "off"); Size2 tex_size = Size2(0, 0); if (!on.is_null()) tex_size = Size2(on->get_width(), on->get_height()); @@ -68,8 +68,8 @@ void CheckButton::_notification(int p_what) { RID ci = get_canvas_item(); - Ref<Texture> on = Control::get_icon(is_disabled() ? "on_disabled" : "on"); - Ref<Texture> off = Control::get_icon(is_disabled() ? "off_disabled" : "off"); + Ref<Texture2D> on = Control::get_icon(is_disabled() ? "on_disabled" : "on"); + Ref<Texture2D> off = Control::get_icon(is_disabled() ? "off_disabled" : "off"); Ref<StyleBox> sb = get_stylebox("normal"); Vector2 ofs; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 01f4070883..cbbad79811 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -59,7 +59,7 @@ void ColorPicker::_notification(int p_what) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - PoolColorArray saved_presets = EditorSettings::get_singleton()->get_project_metadata("color_picker", "presets", PoolColorArray()); + PackedColorArray saved_presets = EditorSettings::get_singleton()->get_project_metadata("color_picker", "presets", PackedColorArray()); for (int i = 0; i < saved_presets.size(); i++) { add_preset(saved_presets[i]); @@ -295,7 +295,7 @@ void ColorPicker::add_preset(const Color &p_color) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - PoolColorArray arr_to_save = get_presets(); + PackedColorArray arr_to_save = get_presets(); EditorSettings::get_singleton()->set_project_metadata("color_picker", "presets", arr_to_save); } #endif @@ -309,16 +309,16 @@ void ColorPicker::erase_preset(const Color &p_color) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - PoolColorArray arr_to_save = get_presets(); + PackedColorArray arr_to_save = get_presets(); EditorSettings::get_singleton()->set_project_metadata("color_picker", "presets", arr_to_save); } #endif } } -PoolColorArray ColorPicker::get_presets() const { +PackedColorArray ColorPicker::get_presets() const { - PoolColorArray arr; + PackedColorArray arr; arr.resize(presets.size()); for (int i = 0; i < presets.size(); i++) { arr.set(i, presets[i]); @@ -445,7 +445,7 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) { c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted()); c->draw_line(Point2(x, y), Point2(x, y), Color(1, 1, 1), 2); } else if (p_which == 1) { - Ref<Texture> hue = get_icon("color_hue", "ColorPicker"); + Ref<Texture2D> hue = get_icon("color_hue", "ColorPicker"); c->draw_texture_rect(hue, Rect2(Point2(), c->get_size())); int y = c->get_size().y - c->get_size().y * (1.0 - h); Color col = Color(); @@ -593,10 +593,10 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { Ref<Image> img = r->get_texture()->get_data(); if (img.is_valid() && !img->empty()) { - img->lock(); + Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position(); Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y); - img->unlock(); + set_pick_color(c); } } @@ -615,9 +615,9 @@ void ColorPicker::_screen_pick_pressed() { screen->set_as_toplevel(true); screen->set_anchors_and_margins_preset(Control::PRESET_WIDE); screen->set_default_cursor_shape(CURSOR_POINTING_HAND); - screen->connect("gui_input", this, "_screen_input"); + screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input)); // It immediately toggles off in the first press otherwise. - screen->call_deferred("connect", "hide", btn_pick, "set_pressed", varray(false)); + screen->call_deferred("connect", "hide", Callable(btn_pick, "set_pressed"), varray(false)); } screen->raise(); screen->show_modal(); @@ -667,6 +667,7 @@ void ColorPicker::set_presets_visible(bool p_visible) { presets_visible = p_visible; preset_separator->set_visible(p_visible); preset_container->set_visible(p_visible); + preset_container2->set_visible(p_visible); } bool ColorPicker::are_presets_visible() const { @@ -677,9 +678,9 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color); ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color); - ClassDB::bind_method(D_METHOD("set_hsv_mode", "mode"), &ColorPicker::set_hsv_mode); + ClassDB::bind_method(D_METHOD("set_hsv_mode"), &ColorPicker::set_hsv_mode); ClassDB::bind_method(D_METHOD("is_hsv_mode"), &ColorPicker::is_hsv_mode); - ClassDB::bind_method(D_METHOD("set_raw_mode", "mode"), &ColorPicker::set_raw_mode); + ClassDB::bind_method(D_METHOD("set_raw_mode"), &ColorPicker::set_raw_mode); ClassDB::bind_method(D_METHOD("is_raw_mode"), &ColorPicker::is_raw_mode); ClassDB::bind_method(D_METHOD("set_deferred_mode", "mode"), &ColorPicker::set_deferred_mode); ClassDB::bind_method(D_METHOD("is_deferred_mode"), &ColorPicker::is_deferred_mode); @@ -692,21 +693,6 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset); ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset); ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets); - ClassDB::bind_method(D_METHOD("_value_changed"), &ColorPicker::_value_changed); - ClassDB::bind_method(D_METHOD("_html_entered"), &ColorPicker::_html_entered); - ClassDB::bind_method(D_METHOD("_text_type_toggled"), &ColorPicker::_text_type_toggled); - ClassDB::bind_method(D_METHOD("_add_preset_pressed"), &ColorPicker::_add_preset_pressed); - ClassDB::bind_method(D_METHOD("_screen_pick_pressed"), &ColorPicker::_screen_pick_pressed); - ClassDB::bind_method(D_METHOD("_sample_draw"), &ColorPicker::_sample_draw); - ClassDB::bind_method(D_METHOD("_update_presets"), &ColorPicker::_update_presets); - ClassDB::bind_method(D_METHOD("_hsv_draw"), &ColorPicker::_hsv_draw); - ClassDB::bind_method(D_METHOD("_uv_input"), &ColorPicker::_uv_input); - ClassDB::bind_method(D_METHOD("_w_input"), &ColorPicker::_w_input); - ClassDB::bind_method(D_METHOD("_preset_input"), &ColorPicker::_preset_input); - ClassDB::bind_method(D_METHOD("_screen_input"), &ColorPicker::_screen_input); - ClassDB::bind_method(D_METHOD("_focus_enter"), &ColorPicker::_focus_enter); - ClassDB::bind_method(D_METHOD("_focus_exit"), &ColorPicker::_focus_exit); - ClassDB::bind_method(D_METHOD("_html_focus_exit"), &ColorPicker::_html_focus_exit); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha"); @@ -741,20 +727,20 @@ ColorPicker::ColorPicker() : uv_edit = memnew(Control); hb_edit->add_child(uv_edit); - uv_edit->connect("gui_input", this, "_uv_input"); + uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input)); uv_edit->set_mouse_filter(MOUSE_FILTER_PASS); uv_edit->set_h_size_flags(SIZE_EXPAND_FILL); uv_edit->set_v_size_flags(SIZE_EXPAND_FILL); uv_edit->set_custom_minimum_size(Size2(get_constant("sv_width"), get_constant("sv_height"))); - uv_edit->connect("draw", this, "_hsv_draw", make_binds(0, uv_edit)); + uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, uv_edit)); w_edit = memnew(Control); hb_edit->add_child(w_edit); w_edit->set_custom_minimum_size(Size2(get_constant("h_width"), 0)); w_edit->set_h_size_flags(SIZE_FILL); w_edit->set_v_size_flags(SIZE_EXPAND_FILL); - w_edit->connect("gui_input", this, "_w_input"); - w_edit->connect("draw", this, "_hsv_draw", make_binds(1, w_edit)); + w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input)); + w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit)); HBoxContainer *hb_smpl = memnew(HBoxContainer); add_child(hb_smpl); @@ -762,13 +748,13 @@ ColorPicker::ColorPicker() : sample = memnew(TextureRect); hb_smpl->add_child(sample); sample->set_h_size_flags(SIZE_EXPAND_FILL); - sample->connect("draw", this, "_sample_draw"); + sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw)); btn_pick = memnew(ToolButton); hb_smpl->add_child(btn_pick); btn_pick->set_toggle_mode(true); btn_pick->set_tooltip(TTR("Pick a color from the editor window.")); - btn_pick->connect("pressed", this, "_screen_pick_pressed"); + btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed)); VBoxContainer *vbl = memnew(VBoxContainer); add_child(vbl); @@ -796,14 +782,14 @@ ColorPicker::ColorPicker() : values[i] = memnew(SpinBox); scroll[i]->share(values[i]); hbc->add_child(values[i]); - values[i]->get_line_edit()->connect("focus_entered", this, "_focus_enter"); - values[i]->get_line_edit()->connect("focus_exited", this, "_focus_exit"); + values[i]->get_line_edit()->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter)); + values[i]->get_line_edit()->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit)); scroll[i]->set_min(0); scroll[i]->set_page(0); scroll[i]->set_h_size_flags(SIZE_EXPAND_FILL); - scroll[i]->connect("value_changed", this, "_value_changed"); + scroll[i]->connect("value_changed", callable_mp(this, &ColorPicker::_value_changed)); vbr->add_child(hbc); } @@ -815,12 +801,12 @@ ColorPicker::ColorPicker() : btn_hsv = memnew(CheckButton); hhb->add_child(btn_hsv); btn_hsv->set_text(TTR("HSV")); - btn_hsv->connect("toggled", this, "set_hsv_mode"); + btn_hsv->connect("toggled", callable_mp(this, &ColorPicker::set_hsv_mode)); btn_raw = memnew(CheckButton); hhb->add_child(btn_raw); btn_raw->set_text(TTR("Raw")); - btn_raw->connect("toggled", this, "set_raw_mode"); + btn_raw->connect("toggled", callable_mp(this, &ColorPicker::set_raw_mode)); text_type = memnew(Button); hhb->add_child(text_type); @@ -831,7 +817,7 @@ ColorPicker::ColorPicker() : #ifdef TOOLS_ENABLED text_type->set_custom_minimum_size(Size2(28 * EDSCALE, 0)); // Adjust for the width of the "Script" icon. #endif - text_type->connect("pressed", this, "_text_type_toggled"); + text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled)); } else { text_type->set_flat(true); @@ -841,9 +827,9 @@ ColorPicker::ColorPicker() : c_text = memnew(LineEdit); hhb->add_child(c_text); c_text->set_h_size_flags(SIZE_EXPAND_FILL); - c_text->connect("text_entered", this, "_html_entered"); - c_text->connect("focus_entered", this, "_focus_enter"); - c_text->connect("focus_exited", this, "_html_focus_exit"); + c_text->connect("text_entered", callable_mp(this, &ColorPicker::_html_entered)); + c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter)); + c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit)); _update_controls(); updating = false; @@ -859,8 +845,8 @@ ColorPicker::ColorPicker() : preset = memnew(TextureRect); preset_container->add_child(preset); - preset->connect("gui_input", this, "_preset_input"); - preset->connect("draw", this, "_update_presets"); + preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input)); + preset->connect("draw", callable_mp(this, &ColorPicker::_update_presets)); preset_container2 = memnew(HBoxContainer); preset_container2->set_h_size_flags(SIZE_EXPAND_FILL); @@ -868,7 +854,7 @@ ColorPicker::ColorPicker() : bt_add_preset = memnew(Button); preset_container2->add_child(bt_add_preset); bt_add_preset->set_tooltip(TTR("Add current color as a preset.")); - bt_add_preset->connect("pressed", this, "_add_preset_pressed"); + bt_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed)); } ///////////////// @@ -968,10 +954,10 @@ void ColorPickerButton::_update_picker() { picker = memnew(ColorPicker); popup->add_child(picker); add_child(popup); - picker->connect("color_changed", this, "_color_changed"); - popup->connect("modal_closed", this, "_modal_closed"); - popup->connect("about_to_show", this, "set_pressed", varray(true)); - popup->connect("popup_hide", this, "set_pressed", varray(false)); + picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed)); + popup->connect("modal_closed", callable_mp(this, &ColorPickerButton::_modal_closed)); + popup->connect("about_to_show", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true)); + popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); picker->set_pick_color(color); picker->set_edit_alpha(edit_alpha); emit_signal("picker_created"); @@ -986,8 +972,6 @@ void ColorPickerButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_popup"), &ColorPickerButton::get_popup); ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPickerButton::set_edit_alpha); ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPickerButton::is_editing_alpha); - ClassDB::bind_method(D_METHOD("_color_changed"), &ColorPickerButton::_color_changed); - ClassDB::bind_method(D_METHOD("_modal_closed"), &ColorPickerButton::_modal_closed); ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color"))); ADD_SIGNAL(MethodInfo("popup_closed")); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 49d36dfb3a..dde2f37135 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -116,7 +116,7 @@ public: void add_preset(const Color &p_color); void erase_preset(const Color &p_color); - PoolColorArray get_presets() const; + PackedColorArray get_presets() const; void set_hsv_mode(bool p_enabled); bool is_hsv_mode() const; diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index b411f563b8..41f33bb719 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -48,9 +48,9 @@ void Container::add_child_notify(Node *p_child) { if (!control) return; - control->connect("size_flags_changed", this, "queue_sort"); - control->connect("minimum_size_changed", this, "_child_minsize_changed"); - control->connect("visibility_changed", this, "_child_minsize_changed"); + control->connect("size_flags_changed", callable_mp(this, &Container::queue_sort)); + control->connect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed)); + control->connect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed)); minimum_size_changed(); queue_sort(); @@ -75,9 +75,9 @@ void Container::remove_child_notify(Node *p_child) { if (!control) return; - control->disconnect("size_flags_changed", this, "queue_sort"); - control->disconnect("minimum_size_changed", this, "_child_minsize_changed"); - control->disconnect("visibility_changed", this, "_child_minsize_changed"); + control->disconnect("size_flags_changed", callable_mp(this, &Container::queue_sort)); + control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed)); + control->disconnect("visibility_changed", callable_mp(this, &Container::_child_minsize_changed)); minimum_size_changed(); queue_sort(); @@ -185,7 +185,6 @@ String Container::get_configuration_warning() const { void Container::_bind_methods() { ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children); - ClassDB::bind_method(D_METHOD("_child_minsize_changed"), &Container::_child_minsize_changed); ClassDB::bind_method(D_METHOD("queue_sort"), &Container::queue_sort); ClassDB::bind_method(D_METHOD("fit_child_in_rect", "child", "rect"), &Container::fit_child_in_rect); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 4c70bd1d39..1a231e368b 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -221,28 +221,28 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("custom_icons/")) { String dname = name.get_slicec('/', 1); if (data.icon_override.has(dname)) { - data.icon_override[dname]->disconnect("changed", this, "_override_changed"); + data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_shaders/")) { String dname = name.get_slicec('/', 1); if (data.shader_override.has(dname)) { - data.shader_override[dname]->disconnect("changed", this, "_override_changed"); + data.shader_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.shader_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_styles/")) { String dname = name.get_slicec('/', 1); if (data.style_override.has(dname)) { - data.style_override[dname]->disconnect("changed", this, "_override_changed"); + data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("custom_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - data.font_override[dname]->disconnect("changed", this, "_override_changed"); + data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); @@ -358,7 +358,7 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const { if (data.icon_override.has(E->get())) hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED; - p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture", hint)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", hint)); } } { @@ -542,10 +542,10 @@ void Control::_notification(int p_notification) { if (data.parent_canvas_item) { - data.parent_canvas_item->connect("item_rect_changed", this, "_size_changed"); + data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); } else { //connect viewport - get_viewport()->connect("size_changed", this, "_size_changed"); + get_viewport()->connect("size_changed", callable_mp(this, &Control::_size_changed)); } } @@ -561,11 +561,11 @@ void Control::_notification(int p_notification) { if (data.parent_canvas_item) { - data.parent_canvas_item->disconnect("item_rect_changed", this, "_size_changed"); + data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); data.parent_canvas_item = NULL; } else if (!is_set_as_toplevel()) { //disconnect viewport - get_viewport()->disconnect("size_changed", this, "_size_changed"); + get_viewport()->disconnect("size_changed", callable_mp(this, &Control::_size_changed)); } if (data.MI) { @@ -687,9 +687,9 @@ bool Control::has_point(const Point2 &p_point) const { if (get_script_instance()) { Variant v = p_point; const Variant *p = &v; - Variant::CallError ce; + Callable::CallError ce; Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->has_point, &p, 1, ce); - if (ce.error == Variant::CallError::CALL_OK) { + if (ce.error == Callable::CallError::CALL_OK) { return ret; } } @@ -705,12 +705,12 @@ void Control::set_drag_forwarding(Control *p_target) { if (p_target) data.drag_owner = p_target->get_instance_id(); else - data.drag_owner = 0; + data.drag_owner = ObjectID(); } Variant Control::get_drag_data(const Point2 &p_point) { - if (data.drag_owner) { + if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); @@ -721,9 +721,9 @@ Variant Control::get_drag_data(const Point2 &p_point) { if (get_script_instance()) { Variant v = p_point; const Variant *p = &v; - Variant::CallError ce; + Callable::CallError ce; Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->get_drag_data, &p, 1, ce); - if (ce.error == Variant::CallError::CALL_OK) + if (ce.error == Callable::CallError::CALL_OK) return ret; } @@ -732,7 +732,7 @@ Variant Control::get_drag_data(const Point2 &p_point) { bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const { - if (data.drag_owner) { + if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); @@ -743,9 +743,9 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const if (get_script_instance()) { Variant v = p_point; const Variant *p[2] = { &v, &p_data }; - Variant::CallError ce; + Callable::CallError ce; Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->can_drop_data, p, 2, ce); - if (ce.error == Variant::CallError::CALL_OK) + if (ce.error == Callable::CallError::CALL_OK) return ret; } @@ -753,7 +753,7 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const } void Control::drop_data(const Point2 &p_point, const Variant &p_data) { - if (data.drag_owner) { + if (data.drag_owner.is_valid()) { Object *obj = ObjectDB::get_instance(data.drag_owner); if (obj) { Control *c = Object::cast_to<Control>(obj); @@ -765,9 +765,9 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) { if (get_script_instance()) { Variant v = p_point; const Variant *p[2] = { &v, &p_data }; - Variant::CallError ce; + Callable::CallError ce; Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->drop_data, p, 2, ce); - if (ce.error == Variant::CallError::CALL_OK) + if (ce.error == Callable::CallError::CALL_OK) return; } } @@ -805,19 +805,19 @@ Size2 Control::get_minimum_size() const { ScriptInstance *si = const_cast<Control *>(this)->get_script_instance(); if (si) { - Variant::CallError ce; + Callable::CallError ce; Variant s = si->call(SceneStringNames::get_singleton()->_get_minimum_size, NULL, 0, ce); - if (ce.error == Variant::CallError::CALL_OK) + if (ce.error == Callable::CallError::CALL_OK) return s; } return Size2(); } -Ref<Texture> Control::get_icon(const StringName &p_name, const StringName &p_type) const { +Ref<Texture2D> Control::get_icon(const StringName &p_name, const StringName &p_type) const { if (p_type == StringName() || p_type == get_class_name()) { - const Ref<Texture> *tex = data.icon_override.getptr(p_name); + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); if (tex) return *tex; } @@ -1063,7 +1063,7 @@ int Control::get_constant(const StringName &p_name, const StringName &p_type) co bool Control::has_icon_override(const StringName &p_name) const { - const Ref<Texture> *tex = data.icon_override.getptr(p_name); + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); return tex != NULL; } @@ -1880,10 +1880,10 @@ Rect2 Control::get_anchorable_rect() const { return Rect2(Point2(), get_size()); } -void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) { +void Control::add_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", this, "_override_changed"); + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } // clear if "null" is passed instead of a icon @@ -1892,7 +1892,7 @@ void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_ } else { data.icon_override[p_name] = p_icon; if (data.icon_override[p_name].is_valid()) { - data.icon_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } } notification(NOTIFICATION_THEME_CHANGED); @@ -1901,7 +1901,7 @@ void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_ void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) { if (data.shader_override.has(p_name)) { - data.shader_override[p_name]->disconnect("changed", this, "_override_changed"); + data.shader_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } // clear if "null" is passed instead of a shader @@ -1910,7 +1910,7 @@ void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p } else { data.shader_override[p_name] = p_shader; if (data.shader_override[p_name].is_valid()) { - data.shader_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + data.shader_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } } notification(NOTIFICATION_THEME_CHANGED); @@ -1918,7 +1918,7 @@ void Control::add_shader_override(const StringName &p_name, const Ref<Shader> &p void Control::add_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", this, "_override_changed"); + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } // clear if "null" is passed instead of a style @@ -1927,7 +1927,7 @@ void Control::add_style_override(const StringName &p_name, const Ref<StyleBox> & } else { data.style_override[p_name] = p_style; if (data.style_override[p_name].is_valid()) { - data.style_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } } notification(NOTIFICATION_THEME_CHANGED); @@ -1936,7 +1936,7 @@ void Control::add_style_override(const StringName &p_name, const Ref<StyleBox> & void Control::add_font_override(const StringName &p_name, const Ref<Font> &p_font) { if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", this, "_override_changed"); + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); } // clear if "null" is passed instead of a font @@ -1945,7 +1945,7 @@ void Control::add_font_override(const StringName &p_name, const Ref<Font> &p_fon } else { data.font_override[p_name] = p_font; if (data.font_override[p_name].is_valid()) { - data.font_override[p_name]->connect("changed", this, "_override_changed", Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); } } notification(NOTIFICATION_THEME_CHANGED); @@ -2224,7 +2224,7 @@ void Control::_modal_stack_remove() { get_viewport()->_gui_remove_from_modal_stack(element, data.modal_prev_focus_owner); - data.modal_prev_focus_owner = 0; + data.modal_prev_focus_owner = ObjectID(); } void Control::_propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign) { @@ -2262,7 +2262,7 @@ void Control::set_theme(const Ref<Theme> &p_theme) { return; if (data.theme.is_valid()) { - data.theme->disconnect("changed", this, "_theme_changed"); + data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed)); } data.theme = p_theme; @@ -2282,7 +2282,7 @@ void Control::set_theme(const Ref<Theme> &p_theme) { } if (data.theme.is_valid()) { - data.theme->connect("changed", this, "_theme_changed", varray(), CONNECT_DEFERRED); + data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), varray(), CONNECT_DEFERRED); } } @@ -2625,9 +2625,9 @@ bool Control::is_text_field() const { if (get_script_instance()) { Variant v=p_point; const Variant *p[2]={&v,&p_data}; - Variant::CallError ce; + Callable::CallError ce; Variant ret = get_script_instance()->call("is_text_field",p,2,ce); - if (ce.error==Variant::CallError::CALL_OK) + if (ce.error==Callable::CallError::CALL_OK) return ret; } */ @@ -2813,7 +2813,6 @@ Control::GrowDirection Control::get_v_grow_direction() const { void Control::_bind_methods() { //ClassDB::bind_method(D_METHOD("_window_resize_event"),&Control::_window_resize_event); - ClassDB::bind_method(D_METHOD("_size_changed"), &Control::_size_changed); ClassDB::bind_method(D_METHOD("_update_minimum_size"), &Control::_update_minimum_size); ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event); @@ -2942,10 +2941,6 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("minimum_size_changed"), &Control::minimum_size_changed); - ClassDB::bind_method(D_METHOD("_theme_changed"), &Control::_theme_changed); - - ClassDB::bind_method(D_METHOD("_override_changed"), &Control::_override_changed); - BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size")); @@ -2959,10 +2954,10 @@ void Control::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::BOOL, "_clips_input")); ADD_GROUP("Anchor", "anchor_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_right", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_bottom", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", MARGIN_BOTTOM); ADD_GROUP("Margin", "margin_"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "margin_left", PROPERTY_HINT_RANGE, "-4096,4096"), "set_margin", "get_margin", MARGIN_LEFT); @@ -2979,7 +2974,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_global_position", PROPERTY_HINT_NONE, "", 0), "_set_global_position", "get_global_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_min_size"), "set_custom_minimum_size", "get_custom_minimum_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rect_rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater"), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_pivot_offset"), "set_pivot_offset", "get_pivot_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rect_clip_content"), "set_clip_contents", "is_clipping_contents"); @@ -3003,7 +2998,7 @@ void Control::_bind_methods() { ADD_GROUP("Size Flags", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_stretch_ratio", "get_stretch_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_stretch_ratio", "get_stretch_ratio"); ADD_GROUP("Theme", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); ADD_GROUP("", ""); @@ -3110,7 +3105,7 @@ Control::Control() { data.rotation = 0; data.parent_canvas_item = NULL; data.scale = Vector2(1, 1); - data.drag_owner = 0; + data.modal_frame = 0; data.block_minimum_size_adjust = false; data.disable_visibility_clip = false; @@ -3125,7 +3120,6 @@ Control::Control() { data.margin[i] = 0; } data.focus_mode = FOCUS_NONE; - data.modal_prev_focus_owner = 0; } Control::~Control() { diff --git a/scene/gui/control.h b/scene/gui/control.h index 357858beb6..67e8ed0d27 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -198,7 +198,7 @@ private: NodePath focus_next; NodePath focus_prev; - HashMap<StringName, Ref<Texture> > icon_override; + HashMap<StringName, Ref<Texture2D> > icon_override; HashMap<StringName, Ref<Shader> > shader_override; HashMap<StringName, Ref<StyleBox> > style_override; HashMap<StringName, Ref<Font> > font_override; @@ -420,14 +420,14 @@ public: /* SKINNING */ - void add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon); + void add_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon); void add_shader_override(const StringName &p_name, const Ref<Shader> &p_shader); void add_style_override(const StringName &p_name, const Ref<StyleBox> &p_style); void add_font_override(const StringName &p_name, const Ref<Font> &p_font); void add_color_override(const StringName &p_name, const Color &p_color); void add_constant_override(const StringName &p_name, int p_constant); - Ref<Texture> get_icon(const StringName &p_name, const StringName &p_type = StringName()) const; + Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_type = StringName()) const; Ref<Shader> get_shader(const StringName &p_name, const StringName &p_type = StringName()) const; Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_type = StringName()) const; Ref<Font> get_font(const StringName &p_name, const StringName &p_type = StringName()) const; diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index e0e88e1577..6cadd0a63e 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -247,8 +247,10 @@ void WindowDialog::_notification(int p_what) { } break; case NOTIFICATION_POPUP_HIDE: { - if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !was_editor_dimmed) + if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !was_editor_dimmed) { EditorNode::get_singleton()->dim_editor(false); + set_pass_on_modal_close_click(false); + } } break; #endif } @@ -334,7 +336,6 @@ void WindowDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("get_title"), &WindowDialog::get_title); ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &WindowDialog::set_resizable); ClassDB::bind_method(D_METHOD("get_resizable"), &WindowDialog::get_resizable); - ClassDB::bind_method(D_METHOD("_closed"), &WindowDialog::_closed); ClassDB::bind_method(D_METHOD("get_close_button"), &WindowDialog::get_close_button); ADD_PROPERTY(PropertyInfo(Variant::STRING, "window_title", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT_INTL), "set_title", "get_title"); @@ -347,7 +348,7 @@ WindowDialog::WindowDialog() { resizable = false; close_button = memnew(TextureButton); add_child(close_button); - close_button->connect("pressed", this, "_closed"); + close_button->connect("pressed", callable_mp(this, &WindowDialog::_closed)); #ifdef TOOLS_ENABLED was_editor_dimmed = false; @@ -395,7 +396,7 @@ void AcceptDialog::_notification(int p_what) { } } -void AcceptDialog::_builtin_text_entered(const String &p_text) { +void AcceptDialog::_text_entered(const String &p_text) { _ok_pressed(); } @@ -407,11 +408,18 @@ void AcceptDialog::_ok_pressed() { ok_pressed(); emit_signal("confirmed"); } + void AcceptDialog::_close_pressed() { cancel_pressed(); } +// FIXME: This is redundant with _closed_pressed, but there's a slight behavior +// change (WindowDialog's _closed() also calls hide()) which should be assessed. +void AcceptDialog::_on_close_pressed() { + _closed(); // From WindowDialog. +} + String AcceptDialog::get_text() const { return label->get_text(); @@ -446,7 +454,7 @@ void AcceptDialog::register_text_enter(Node *p_line_edit) { ERR_FAIL_NULL(p_line_edit); LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); if (line_edit) - line_edit->connect("text_entered", this, "_builtin_text_entered"); + line_edit->connect("text_entered", callable_mp(this, &AcceptDialog::_text_entered)); } void AcceptDialog::_update_child_rects() { @@ -531,7 +539,7 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin } if (p_action != "") { - button->connect("pressed", this, "_custom_action", varray(p_action)); + button->connect("pressed", callable_mp(this, &AcceptDialog::_custom_action), varray(p_action)); } return button; @@ -543,29 +551,26 @@ Button *AcceptDialog::add_cancel(const String &p_cancel) { if (p_cancel == "") c = RTR("Cancel"); Button *b = swap_ok_cancel ? add_button(c, true) : add_button(c); - b->connect("pressed", this, "_closed"); + b->connect("pressed", callable_mp(this, &AcceptDialog::_on_close_pressed)); return b; } void AcceptDialog::_bind_methods() { - ClassDB::bind_method(D_METHOD("_ok"), &AcceptDialog::_ok_pressed); ClassDB::bind_method(D_METHOD("get_ok"), &AcceptDialog::get_ok); ClassDB::bind_method(D_METHOD("get_label"), &AcceptDialog::get_label); ClassDB::bind_method(D_METHOD("set_hide_on_ok", "enabled"), &AcceptDialog::set_hide_on_ok); ClassDB::bind_method(D_METHOD("get_hide_on_ok"), &AcceptDialog::get_hide_on_ok); ClassDB::bind_method(D_METHOD("add_button", "text", "right", "action"), &AcceptDialog::add_button, DEFVAL(false), DEFVAL("")); ClassDB::bind_method(D_METHOD("add_cancel", "name"), &AcceptDialog::add_cancel); - ClassDB::bind_method(D_METHOD("_builtin_text_entered"), &AcceptDialog::_builtin_text_entered); ClassDB::bind_method(D_METHOD("register_text_enter", "line_edit"), &AcceptDialog::register_text_enter); - ClassDB::bind_method(D_METHOD("_custom_action"), &AcceptDialog::_custom_action); ClassDB::bind_method(D_METHOD("set_text", "text"), &AcceptDialog::set_text); ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text); ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap"), &AcceptDialog::set_autowrap); ClassDB::bind_method(D_METHOD("has_autowrap"), &AcceptDialog::has_autowrap); ADD_SIGNAL(MethodInfo("confirmed")); - ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING, "action"))); + ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING_NAME, "action"))); ADD_GROUP("Dialog", "dialog"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); @@ -600,7 +605,7 @@ AcceptDialog::AcceptDialog() { hbc->add_child(ok); hbc->add_spacer(); - ok->connect("pressed", this, "_ok"); + ok->connect("pressed", callable_mp(this, &AcceptDialog::_ok_pressed)); set_as_toplevel(true); hide_on_ok = true; diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index b6381e98b4..c474f7849d 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -64,7 +64,6 @@ class WindowDialog : public Popup { #endif void _gui_input(const Ref<InputEvent> &p_event); - void _closed(); int _drag_hit_test(const Point2 &pos) const; protected: @@ -75,6 +74,9 @@ protected: void _notification(int p_what); static void _bind_methods(); + // Not private since used by derived classes signal. + void _closed(); + public: TextureButton *get_close_button(); @@ -113,9 +115,7 @@ class AcceptDialog : public WindowDialog { bool hide_on_ok; void _custom_action(const String &p_action); - void _ok_pressed(); void _close_pressed(); - void _builtin_text_entered(const String &p_text); void _update_child_rects(); static bool swap_ok_cancel; @@ -128,6 +128,11 @@ protected: virtual void cancel_pressed() {} virtual void custom_action(const String &) {} + // Not private since used by derived classes signal. + void _text_entered(const String &p_text); + void _ok_pressed(); + void _on_close_pressed(); + public: Size2 get_minimum_size() const; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 2cc9c1a53a..1d813d8081 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -85,7 +85,7 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { bool handled = true; - switch (k->get_scancode()) { + switch (k->get_keycode()) { case KEY_H: { @@ -193,7 +193,7 @@ void FileDialog::_action_pressed() { TreeItem *ti = tree->get_next_selected(NULL); String fbase = dir_access->get_current_dir(); - PoolVector<String> files; + Vector<String> files; while (ti) { files.push_back(fbase.plus_file(ti->get_text(0))); @@ -424,7 +424,7 @@ void FileDialog::update_file_list() { dir_access->list_dir_begin(); TreeItem *root = tree->create_item(); - Ref<Texture> folder = get_icon("folder"); + Ref<Texture2D> folder = get_icon("folder"); const Color folder_color = get_color("folder_icon_modulate"); List<String> files; List<String> dirs; @@ -518,7 +518,7 @@ void FileDialog::update_file_list() { if (get_icon_func) { - Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get())); + Ref<Texture2D> icon = get_icon_func(base_dir.plus_file(files.front()->get())); ti->set_icon(0, icon); } @@ -805,15 +805,7 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_unhandled_input"), &FileDialog::_unhandled_input); - ClassDB::bind_method(D_METHOD("_tree_multi_selected"), &FileDialog::_tree_multi_selected); - ClassDB::bind_method(D_METHOD("_tree_selected"), &FileDialog::_tree_selected); - ClassDB::bind_method(D_METHOD("_tree_item_activated"), &FileDialog::_tree_item_activated); - ClassDB::bind_method(D_METHOD("_dir_entered"), &FileDialog::_dir_entered); - ClassDB::bind_method(D_METHOD("_file_entered"), &FileDialog::_file_entered); - ClassDB::bind_method(D_METHOD("_action_pressed"), &FileDialog::_action_pressed); ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed); - ClassDB::bind_method(D_METHOD("_filter_selected"), &FileDialog::_filter_selected); - ClassDB::bind_method(D_METHOD("_save_confirm_pressed"), &FileDialog::_save_confirm_pressed); ClassDB::bind_method(D_METHOD("clear_filters"), &FileDialog::clear_filters); ClassDB::bind_method(D_METHOD("add_filter", "filter"), &FileDialog::add_filter); @@ -835,13 +827,9 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("get_access"), &FileDialog::get_access); ClassDB::bind_method(D_METHOD("set_show_hidden_files", "show"), &FileDialog::set_show_hidden_files); ClassDB::bind_method(D_METHOD("is_showing_hidden_files"), &FileDialog::is_showing_hidden_files); - ClassDB::bind_method(D_METHOD("_select_drive"), &FileDialog::_select_drive); - ClassDB::bind_method(D_METHOD("_make_dir"), &FileDialog::_make_dir); - ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileDialog::_make_dir_confirm); ClassDB::bind_method(D_METHOD("_update_file_name"), &FileDialog::update_file_name); - ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list); ClassDB::bind_method(D_METHOD("_update_dir"), &FileDialog::update_dir); - ClassDB::bind_method(D_METHOD("_go_up"), &FileDialog::_go_up); + ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list); ClassDB::bind_method(D_METHOD("deselect_items"), &FileDialog::deselect_items); ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate); @@ -849,14 +837,14 @@ void FileDialog::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open File,Open Files,Open Folder,Open Any,Save"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"), "set_access", "get_access"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_STRING_ARRAY, "filters"), "set_filters", "get_filters"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_hidden_files"), "set_show_hidden_files", "is_showing_hidden_files"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir"), "set_current_dir", "get_current_dir"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file"), "set_current_file", "get_current_file"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path"), "set_current_path", "get_current_path"); ADD_SIGNAL(MethodInfo("file_selected", PropertyInfo(Variant::STRING, "path"))); - ADD_SIGNAL(MethodInfo("files_selected", PropertyInfo(Variant::POOL_STRING_ARRAY, "paths"))); + ADD_SIGNAL(MethodInfo("files_selected", PropertyInfo(Variant::PACKED_STRING_ARRAY, "paths"))); ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir"))); BIND_ENUM_CONSTANT(MODE_OPEN_FILE); @@ -900,11 +888,11 @@ FileDialog::FileDialog() { dir_up = memnew(ToolButton); dir_up->set_tooltip(RTR("Go to parent folder.")); hbc->add_child(dir_up); - dir_up->connect("pressed", this, "_go_up"); + dir_up->connect("pressed", callable_mp(this, &FileDialog::_go_up)); drives = memnew(OptionButton); hbc->add_child(drives); - drives->connect("item_selected", this, "_select_drive"); + drives->connect("item_selected", callable_mp(this, &FileDialog::_select_drive)); hbc->add_child(memnew(Label(RTR("Path:")))); dir = memnew(LineEdit); @@ -913,19 +901,19 @@ FileDialog::FileDialog() { refresh = memnew(ToolButton); refresh->set_tooltip(RTR("Refresh files.")); - refresh->connect("pressed", this, "_update_file_list"); + refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list)); hbc->add_child(refresh); show_hidden = memnew(ToolButton); show_hidden->set_toggle_mode(true); show_hidden->set_pressed(is_showing_hidden_files()); show_hidden->set_tooltip(RTR("Toggle the visibility of hidden files.")); - show_hidden->connect("toggled", this, "set_show_hidden_files"); + show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files)); hbc->add_child(show_hidden); makedir = memnew(Button); makedir->set_text(RTR("Create Folder")); - makedir->connect("pressed", this, "_make_dir"); + makedir->connect("pressed", callable_mp(this, &FileDialog::_make_dir)); hbc->add_child(makedir); vbc->add_child(hbc); @@ -950,20 +938,20 @@ FileDialog::FileDialog() { access = ACCESS_RESOURCES; _update_drives(); - connect("confirmed", this, "_action_pressed"); - tree->connect("multi_selected", this, "_tree_multi_selected", varray(), CONNECT_DEFERRED); - tree->connect("cell_selected", this, "_tree_selected", varray(), CONNECT_DEFERRED); - tree->connect("item_activated", this, "_tree_item_activated", varray()); - tree->connect("nothing_selected", this, "deselect_items"); - dir->connect("text_entered", this, "_dir_entered"); - file->connect("text_entered", this, "_file_entered"); - filter->connect("item_selected", this, "_filter_selected"); + connect("confirmed", callable_mp(this, &FileDialog::_action_pressed)); + tree->connect("multi_selected", callable_mp(this, &FileDialog::_tree_multi_selected), varray(), CONNECT_DEFERRED); + tree->connect("cell_selected", callable_mp(this, &FileDialog::_tree_selected), varray(), CONNECT_DEFERRED); + tree->connect("item_activated", callable_mp(this, &FileDialog::_tree_item_activated), varray()); + tree->connect("nothing_selected", callable_mp(this, &FileDialog::deselect_items)); + dir->connect("text_entered", callable_mp(this, &FileDialog::_dir_entered)); + file->connect("text_entered", callable_mp(this, &FileDialog::_file_entered)); + filter->connect("item_selected", callable_mp(this, &FileDialog::_filter_selected)); confirm_save = memnew(ConfirmationDialog); confirm_save->set_as_toplevel(true); add_child(confirm_save); - confirm_save->connect("confirmed", this, "_save_confirm_pressed"); + confirm_save->connect("confirmed", callable_mp(this, &FileDialog::_save_confirm_pressed)); makedialog = memnew(ConfirmationDialog); makedialog->set_title(RTR("Create Folder")); @@ -974,7 +962,7 @@ FileDialog::FileDialog() { makevb->add_margin_child(RTR("Name:"), makedirname); add_child(makedialog); makedialog->register_text_enter(makedirname); - makedialog->connect("confirmed", this, "_make_dir_confirm"); + makedialog->connect("confirmed", callable_mp(this, &FileDialog::_make_dir_confirm)); mkdirerr = memnew(AcceptDialog); mkdirerr->set_text(RTR("Could not create folder.")); add_child(mkdirerr); @@ -1003,8 +991,6 @@ FileDialog::~FileDialog() { void LineEditFileChooser::_bind_methods() { - ClassDB::bind_method(D_METHOD("_browse"), &LineEditFileChooser::_browse); - ClassDB::bind_method(D_METHOD("_chosen"), &LineEditFileChooser::_chosen); ClassDB::bind_method(D_METHOD("get_button"), &LineEditFileChooser::get_button); ClassDB::bind_method(D_METHOD("get_line_edit"), &LineEditFileChooser::get_line_edit); ClassDB::bind_method(D_METHOD("get_file_dialog"), &LineEditFileChooser::get_file_dialog); @@ -1029,10 +1015,10 @@ LineEditFileChooser::LineEditFileChooser() { button = memnew(Button); button->set_text(" .. "); add_child(button); - button->connect("pressed", this, "_browse"); + button->connect("pressed", callable_mp(this, &LineEditFileChooser::_browse)); dialog = memnew(FileDialog); add_child(dialog); - dialog->connect("file_selected", this, "_chosen"); - dialog->connect("dir_selected", this, "_chosen"); - dialog->connect("files_selected", this, "_chosen"); + dialog->connect("file_selected", callable_mp(this, &LineEditFileChooser::_chosen)); + dialog->connect("dir_selected", callable_mp(this, &LineEditFileChooser::_chosen)); + dialog->connect("files_selected", callable_mp(this, &LineEditFileChooser::_chosen)); } diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index d9ab00e0f2..9f6650c276 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -58,7 +58,7 @@ public: MODE_SAVE_FILE }; - typedef Ref<Texture> (*GetIconFunc)(const String &); + typedef Ref<Texture2D> (*GetIconFunc)(const String &); typedef void (*RegisterFunc)(FileDialog *); static GetIconFunc get_icon_func; diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 46c59f42fc..6345bfe562 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -54,7 +54,6 @@ GradientEdit::GradientEdit() { checker = Ref<ImageTexture>(memnew(ImageTexture)); Ref<Image> img = memnew(Image(checker_bg_png)); - checker->create_from_image(img, ImageTexture::FLAG_REPEAT); } int GradientEdit::_get_point_from_pos(int x) { @@ -97,7 +96,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; - if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) { + if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && grabbed != -1) { points.remove(grabbed); grabbed = -1; @@ -303,8 +302,8 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { void GradientEdit::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - if (!picker->is_connected("color_changed", this, "_color_changed")) { - picker->connect("color_changed", this, "_color_changed"); + if (!picker->is_connected("color_changed", callable_mp(this, &GradientEdit::_color_changed))) { + picker->connect("color_changed", callable_mp(this, &GradientEdit::_color_changed)); } } if (p_what == NOTIFICATION_DRAW) { @@ -491,6 +490,5 @@ Vector<Gradient::Point> &GradientEdit::get_points() { void GradientEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &GradientEdit::_gui_input); - ClassDB::bind_method(D_METHOD("_color_changed"), &GradientEdit::_color_changed); ADD_SIGNAL(MethodInfo("ramp_changed")); } diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index c09b2414b2..4bc33b220e 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -257,9 +257,9 @@ void GraphEdit::add_child_notify(Node *p_child) { GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { gn->set_scale(Vector2(zoom, zoom)); - gn->connect("offset_changed", this, "_graph_node_moved", varray(gn)); - gn->connect("raise_request", this, "_graph_node_raised", varray(gn)); - gn->connect("item_rect_changed", connections_layer, "update"); + gn->connect("offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved), varray(gn)); + gn->connect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised), varray(gn)); + gn->connect("item_rect_changed", callable_mp((CanvasItem *)connections_layer, &CanvasItem::update)); _graph_node_moved(gn); gn->set_mouse_filter(MOUSE_FILTER_PASS); } @@ -273,8 +273,8 @@ void GraphEdit::remove_child_notify(Node *p_child) { } GraphNode *gn = Object::cast_to<GraphNode>(p_child); if (gn) { - gn->disconnect("offset_changed", this, "_graph_node_moved"); - gn->disconnect("raise_request", this, "_graph_node_raised"); + gn->disconnect("offset_changed", callable_mp(this, &GraphEdit::_graph_node_moved)); + gn->disconnect("raise_request", callable_mp(this, &GraphEdit::_graph_node_raised)); } } @@ -357,7 +357,7 @@ void GraphEdit::_notification(int p_what) { bool GraphEdit::_filter_input(const Point2 &p_point) { - Ref<Texture> port = get_icon("port", "GraphNode"); + Ref<Texture2D> port = get_icon("port", "GraphNode"); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -389,7 +389,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { Ref<InputEventMouseButton> mb = p_ev; if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { - Ref<Texture> port = get_icon("port", "GraphNode"); + Ref<Texture2D> port = get_icon("port", "GraphNode"); Vector2 mpos(mb->get_position().x, mb->get_position().y); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -501,7 +501,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_target = false; top_layer->update(); - Ref<Texture> port = get_icon("port", "GraphNode"); + Ref<Texture2D> port = get_icon("port", "GraphNode"); Vector2 mpos = mm->get_position(); for (int i = get_child_count() - 1; i >= 0; i--) { @@ -689,9 +689,9 @@ void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const colors.push_back(p_to_color); #ifdef TOOLS_ENABLED - p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE), true); + p_where->draw_polyline_colors(points, colors, Math::floor(2 * EDSCALE)); #else - p_where->draw_polyline_colors(points, colors, 2, true); + p_where->draw_polyline_colors(points, colors, 2); #endif } @@ -1043,22 +1043,22 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) { if (k.is_valid()) { - if (k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) { + if (k->get_keycode() == KEY_D && k->is_pressed() && k->get_command()) { emit_signal("duplicate_nodes_request"); accept_event(); } - if (k->get_scancode() == KEY_C && k->is_pressed() && k->get_command()) { + if (k->get_keycode() == KEY_C && k->is_pressed() && k->get_command()) { emit_signal("copy_nodes_request"); accept_event(); } - if (k->get_scancode() == KEY_V && k->is_pressed() && k->get_command()) { + if (k->get_keycode() == KEY_V && k->is_pressed() && k->get_command()) { emit_signal("paste_nodes_request"); accept_event(); } - if (k->get_scancode() == KEY_DELETE && k->is_pressed()) { + if (k->get_keycode() == KEY_DELETE && k->is_pressed()) { emit_signal("delete_nodes_request"); accept_event(); } @@ -1291,21 +1291,8 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_right_disconnects", "enable"), &GraphEdit::set_right_disconnects); ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled); - ClassDB::bind_method(D_METHOD("_graph_node_moved"), &GraphEdit::_graph_node_moved); - ClassDB::bind_method(D_METHOD("_graph_node_raised"), &GraphEdit::_graph_node_raised); - - ClassDB::bind_method(D_METHOD("_top_layer_input"), &GraphEdit::_top_layer_input); - ClassDB::bind_method(D_METHOD("_top_layer_draw"), &GraphEdit::_top_layer_draw); - ClassDB::bind_method(D_METHOD("_scroll_moved"), &GraphEdit::_scroll_moved); - ClassDB::bind_method(D_METHOD("_zoom_minus"), &GraphEdit::_zoom_minus); - ClassDB::bind_method(D_METHOD("_zoom_reset"), &GraphEdit::_zoom_reset); - ClassDB::bind_method(D_METHOD("_zoom_plus"), &GraphEdit::_zoom_plus); - ClassDB::bind_method(D_METHOD("_snap_toggled"), &GraphEdit::_snap_toggled); - ClassDB::bind_method(D_METHOD("_snap_value_changed"), &GraphEdit::_snap_value_changed); - ClassDB::bind_method(D_METHOD("_gui_input"), &GraphEdit::_gui_input); ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset); - ClassDB::bind_method(D_METHOD("_connections_layer_draw"), &GraphEdit::_connections_layer_draw); ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox); @@ -1315,17 +1302,17 @@ void GraphEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs"); ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "zoom"), "set_zoom", "get_zoom"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "zoom"), "set_zoom", "get_zoom"); - ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"))); - ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"))); + ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"))); + ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"))); ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position"))); ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("copy_nodes_request")); ADD_SIGNAL(MethodInfo("paste_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); - ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); + ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING_NAME, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); + ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING_NAME, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("delete_nodes_request")); ADD_SIGNAL(MethodInfo("_begin_node_move")); ADD_SIGNAL(MethodInfo("_end_node_move")); @@ -1341,12 +1328,12 @@ GraphEdit::GraphEdit() { add_child(top_layer); top_layer->set_mouse_filter(MOUSE_FILTER_PASS); top_layer->set_anchors_and_margins_preset(Control::PRESET_WIDE); - top_layer->connect("draw", this, "_top_layer_draw"); - top_layer->connect("gui_input", this, "_top_layer_input"); + top_layer->connect("draw", callable_mp(this, &GraphEdit::_top_layer_draw)); + top_layer->connect("gui_input", callable_mp(this, &GraphEdit::_top_layer_input)); connections_layer = memnew(Control); add_child(connections_layer); - connections_layer->connect("draw", this, "_connections_layer_draw"); + connections_layer->connect("draw", callable_mp(this, &GraphEdit::_connections_layer_draw)); connections_layer->set_name("CLAYER"); connections_layer->set_disable_visibility_clip(true); // so it can draw freely and be offset connections_layer->set_mouse_filter(MOUSE_FILTER_IGNORE); @@ -1373,8 +1360,8 @@ GraphEdit::GraphEdit() { v_scroll->set_min(-10000); v_scroll->set_max(10000); - h_scroll->connect("value_changed", this, "_scroll_moved"); - v_scroll->connect("value_changed", this, "_scroll_moved"); + h_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); + v_scroll->connect("value_changed", callable_mp(this, &GraphEdit::_scroll_moved)); zoom = 1; @@ -1385,25 +1372,25 @@ GraphEdit::GraphEdit() { zoom_minus = memnew(ToolButton); zoom_hb->add_child(zoom_minus); zoom_minus->set_tooltip(RTR("Zoom Out")); - zoom_minus->connect("pressed", this, "_zoom_minus"); + zoom_minus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_minus)); zoom_minus->set_focus_mode(FOCUS_NONE); zoom_reset = memnew(ToolButton); zoom_hb->add_child(zoom_reset); zoom_reset->set_tooltip(RTR("Zoom Reset")); - zoom_reset->connect("pressed", this, "_zoom_reset"); + zoom_reset->connect("pressed", callable_mp(this, &GraphEdit::_zoom_reset)); zoom_reset->set_focus_mode(FOCUS_NONE); zoom_plus = memnew(ToolButton); zoom_hb->add_child(zoom_plus); zoom_plus->set_tooltip(RTR("Zoom In")); - zoom_plus->connect("pressed", this, "_zoom_plus"); + zoom_plus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_plus)); zoom_plus->set_focus_mode(FOCUS_NONE); snap_button = memnew(ToolButton); snap_button->set_toggle_mode(true); snap_button->set_tooltip(RTR("Enable snap and show grid.")); - snap_button->connect("pressed", this, "_snap_toggled"); + snap_button->connect("pressed", callable_mp(this, &GraphEdit::_snap_toggled)); snap_button->set_pressed(true); snap_button->set_focus_mode(FOCUS_NONE); zoom_hb->add_child(snap_button); @@ -1413,7 +1400,7 @@ GraphEdit::GraphEdit() { snap_amount->set_max(100); snap_amount->set_step(1); snap_amount->set_value(20); - snap_amount->connect("value_changed", this, "_snap_value_changed"); + snap_amount->connect("value_changed", callable_mp(this, &GraphEdit::_snap_value_changed)); zoom_hb->add_child(snap_amount); setting_scroll_ofs = false; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 7b1bfdfdb5..82e890395a 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -170,7 +170,7 @@ bool GraphNode::has_point(const Point2 &p_point) const { if (comment) { Ref<StyleBox> comment = get_stylebox("comment"); - Ref<Texture> resizer = get_icon("resizer"); + Ref<Texture2D> resizer = get_icon("resizer"); if (Rect2(get_size() - resizer->get_size(), resizer->get_size()).has_point(p_point)) { return true; @@ -204,9 +204,9 @@ void GraphNode::_notification(int p_what) { //sb=sb->duplicate(); //sb->call("set_modulate",modulate); - Ref<Texture> port = get_icon("port"); - Ref<Texture> close = get_icon("close"); - Ref<Texture> resizer = get_icon("resizer"); + Ref<Texture2D> port = get_icon("port"); + Ref<Texture2D> close = get_icon("close"); + Ref<Texture2D> resizer = get_icon("resizer"); int close_offset = get_constant("close_offset"); int close_h_offset = get_constant("close_h_offset"); Color close_color = get_color("close_color"); @@ -259,14 +259,14 @@ void GraphNode::_notification(int p_what) { const Slot &s = slot_info[E->key()]; //left if (s.enable_left) { - Ref<Texture> p = port; + Ref<Texture2D> p = port; if (s.custom_slot_left.is_valid()) { p = s.custom_slot_left; } p->draw(get_canvas_item(), icofs + Point2(edgeofs, cache_y[E->key()]), s.color_left); } if (s.enable_right) { - Ref<Texture> p = port; + Ref<Texture2D> p = port; if (s.custom_slot_right.is_valid()) { p = s.custom_slot_right; } @@ -291,7 +291,7 @@ void GraphNode::_notification(int p_what) { } } -void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture> &p_custom_left, const Ref<Texture> &p_custom_right) { +void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) { ERR_FAIL_COND(p_idx < 0); @@ -379,7 +379,7 @@ Size2 GraphNode::get_minimum_size() const { Size2 minsize; minsize.x = title_font->get_string_size(title).x; if (show_close) { - Ref<Texture> close = get_icon("close"); + Ref<Texture2D> close = get_icon("close"); minsize.x += sep + close->get_width(); } @@ -606,7 +606,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) { return; } - Ref<Texture> resizer = get_icon("resizer"); + Ref<Texture2D> resizer = get_icon("resizer"); if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) { @@ -674,7 +674,7 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title); ClassDB::bind_method(D_METHOD("_gui_input"), &GraphNode::_gui_input); - ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture>()), DEFVAL(Ref<Texture>())); + ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot); ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots); ClassDB::bind_method(D_METHOD("is_slot_enabled_left", "idx"), &GraphNode::is_slot_enabled_left); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index e1a81b5f3d..a3eb8ed152 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -52,8 +52,8 @@ private: bool enable_right; int type_right; Color color_right; - Ref<Texture> custom_slot_left; - Ref<Texture> custom_slot_right; + Ref<Texture2D> custom_slot_left; + Ref<Texture2D> custom_slot_right; Slot() { enable_left = false; @@ -112,7 +112,7 @@ protected: public: bool has_point(const Point2 &p_point) const; - void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture> &p_custom_left = Ref<Texture>(), const Ref<Texture> &p_custom_right = Ref<Texture>()); + void set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left = Ref<Texture2D>(), const Ref<Texture2D> &p_custom_right = Ref<Texture2D>()); void clear_slot(int p_idx); void clear_all_slots(); bool is_slot_enabled_left(int p_idx) const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 526950dbb3..5e662b8df0 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -32,7 +32,7 @@ #include "core/os/os.h" #include "core/project_settings.h" -void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, bool p_selectable) { +void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) { Item item; item.icon = p_texture; @@ -51,7 +51,7 @@ void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, boo shape_changed = true; } -void ItemList::add_icon_item(const Ref<Texture> &p_item, bool p_selectable) { +void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) { Item item; item.icon = p_item; @@ -110,7 +110,7 @@ String ItemList::get_item_tooltip(int p_idx) const { return items[p_idx].tooltip; } -void ItemList::set_item_icon(int p_idx, const Ref<Texture> &p_icon) { +void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -119,9 +119,9 @@ void ItemList::set_item_icon(int p_idx, const Ref<Texture> &p_icon) { shape_changed = true; } -Ref<Texture> ItemList::get_item_icon(int p_idx) const { +Ref<Texture2D> ItemList::get_item_icon(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>()); return items[p_idx].icon; } @@ -201,7 +201,7 @@ Color ItemList::get_item_custom_fg_color(int p_idx) const { return items[p_idx].custom_fg; } -void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) { +void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -209,9 +209,9 @@ void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) { update(); shape_changed = true; } -Ref<Texture> ItemList::get_item_tag_icon(int p_idx) const { +Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>()); return items[p_idx].tag_icon; } @@ -1398,7 +1398,7 @@ void ItemList::_set_items(const Array &p_items) { for (int i = 0; i < p_items.size(); i += 3) { String text = p_items[i + 0]; - Ref<Texture> icon = p_items[i + 1]; + Ref<Texture2D> icon = p_items[i + 1]; bool disabled = p_items[i + 2]; int idx = get_item_count(); @@ -1542,7 +1542,6 @@ void ItemList::_bind_methods() { ClassDB::bind_method(D_METHOD("get_v_scroll"), &ItemList::get_v_scroll); - ClassDB::bind_method(D_METHOD("_scroll_changed"), &ItemList::_scroll_changed); ClassDB::bind_method(D_METHOD("_gui_input"), &ItemList::_gui_input); ClassDB::bind_method(D_METHOD("_set_items"), &ItemList::_set_items); @@ -1561,7 +1560,7 @@ void ItemList::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_column_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_fixed_column_width", "get_fixed_column_width"); ADD_GROUP("Icon", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "icon_mode", PROPERTY_HINT_ENUM, "Top,Left"), "set_icon_mode", "get_icon_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "icon_scale"), "set_icon_scale", "get_icon_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "icon_scale"), "set_icon_scale", "get_icon_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fixed_icon_size"), "set_fixed_icon_size", "get_fixed_icon_size"); BIND_ENUM_CONSTANT(ICON_MODE_TOP); @@ -1599,7 +1598,7 @@ ItemList::ItemList() { add_child(scroll_bar); shape_changed = true; - scroll_bar->connect("value_changed", this, "_scroll_changed"); + scroll_bar->connect("value_changed", callable_mp(this, &ItemList::_scroll_changed)); set_focus_mode(FOCUS_ALL); current_columns = 1; diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index d9b510c762..da9851dd7d 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -52,11 +52,11 @@ public: private: struct Item { - Ref<Texture> icon; + Ref<Texture2D> icon; bool icon_transposed; Rect2i icon_region; Color icon_modulate; - Ref<Texture> tag_icon; + Ref<Texture2D> tag_icon; String text; bool selectable; bool selected; @@ -125,14 +125,14 @@ protected: static void _bind_methods(); public: - void add_item(const String &p_item, const Ref<Texture> &p_texture = Ref<Texture>(), bool p_selectable = true); - void add_icon_item(const Ref<Texture> &p_item, bool p_selectable = true); + void add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true); + void add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true); void set_item_text(int p_idx, const String &p_text); String get_item_text(int p_idx) const; - void set_item_icon(int p_idx, const Ref<Texture> &p_icon); - Ref<Texture> get_item_icon(int p_idx) const; + void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_item_icon(int p_idx) const; void set_item_icon_transposed(int p_idx, const bool transposed); bool is_item_icon_transposed(int p_idx) const; @@ -152,8 +152,8 @@ public: void set_item_metadata(int p_idx, const Variant &p_metadata); Variant get_item_metadata(int p_idx) const; - void set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon); - Ref<Texture> get_item_tag_icon(int p_idx) const; + void set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon); + Ref<Texture2D> get_item_tag_icon(int p_idx) const; void set_item_tooltip_enabled(int p_idx, const bool p_enabled); bool is_item_tooltip_enabled(int p_idx) const; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 9b542cb179..c900b35d65 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -687,7 +687,7 @@ void Label::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1", PROPERTY_USAGE_EDITOR), "set_visible_characters", "get_visible_characters"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); ADD_PROPERTY(PropertyInfo(Variant::INT, "lines_skipped", PROPERTY_HINT_RANGE, "0,999,1"), "set_lines_skipped", "get_lines_skipped"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_lines_visible", PROPERTY_HINT_RANGE, "-1,999,1"), "set_max_lines_visible", "get_max_lines_visible"); } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 7cc47d351e..fdddf0b5fa 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -165,7 +165,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { #ifdef APPLE_STYLE_KEYS if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) { uint32_t remap_key = KEY_UNKNOWN; - switch (k->get_scancode()) { + switch (k->get_keycode()) { case KEY_F: { remap_key = KEY_RIGHT; } break; @@ -184,16 +184,22 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { case KEY_H: { remap_key = KEY_BACKSPACE; } break; + case KEY_A: { + remap_key = KEY_HOME; + } break; + case KEY_E: { + remap_key = KEY_END; + } break; } if (remap_key != KEY_UNKNOWN) { - k->set_scancode(remap_key); + k->set_keycode(remap_key); k->set_control(false); } } #endif - unsigned int code = k->get_scancode(); + unsigned int code = k->get_keycode(); if (k->get_command() && is_shortcut_keys_enabled()) { @@ -349,14 +355,23 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_LEFT: { - #ifndef APPLE_STYLE_KEYS - if (!k->get_alt()) + if (!k->get_alt()) { #endif + if (selection.enabled && !k->get_shift()) { + set_cursor_position(selection.begin); + deselect(); + handled = true; + break; + } + shift_selection_check_pre(k->get_shift()); +#ifndef APPLE_STYLE_KEYS + } +#endif #ifdef APPLE_STYLE_KEYS if (k->get_command()) { @@ -396,11 +411,23 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_RIGHT: { +#ifndef APPLE_STYLE_KEYS + if (!k->get_alt()) { +#endif + if (selection.enabled && !k->get_shift()) { + set_cursor_position(selection.end); + deselect(); + handled = true; + break; + } - shift_selection_check_pre(k->get_shift()); + shift_selection_check_pre(k->get_shift()); +#ifndef APPLE_STYLE_KEYS + } +#endif #ifdef APPLE_STYLE_KEYS if (k->get_command()) { @@ -503,7 +530,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_HOME: { @@ -516,7 +543,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_END: { @@ -544,7 +571,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (handled) { accept_event(); } else if (!k->get_command()) { - if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) { + if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) { if (editable) { selection_delete(); @@ -628,7 +655,7 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const { if (!clear_button_enabled || !has_point(p_pos)) { return false; } - Ref<Texture> icon = Control::get_icon("clear"); + Ref<Texture2D> icon = Control::get_icon("clear"); int x_ofs = get_stylebox("normal")->get_offset().x; return p_pos.x > get_size().width - icon->get_width() - x_ofs; } @@ -642,8 +669,8 @@ void LineEdit::_notification(int p_what) { cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false)); cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65)); - if (!EditorSettings::get_singleton()->is_connected("settings_changed", this, "_editor_settings_changed")) { - EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed"); + if (!EditorSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed))) { + EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed)); } } } break; @@ -742,7 +769,7 @@ void LineEdit::_notification(int p_what) { bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9); if (display_clear_icon) { if (clear_button_status.press_attempt && clear_button_status.pressing_inside) { @@ -1303,7 +1330,7 @@ void LineEdit::set_cursor_position(int p_pos) { int window_width = get_size().width - style->get_minimum_size().width; bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { - Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; + Ref<Texture2D> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; window_width -= r_icon->get_width(); } @@ -1644,7 +1671,7 @@ bool LineEdit::is_selecting_enabled() const { return selecting_enabled; } -void LineEdit::set_right_icon(const Ref<Texture> &p_icon) { +void LineEdit::set_right_icon(const Ref<Texture2D> &p_icon) { if (right_icon == p_icon) { return; } @@ -1653,7 +1680,7 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) { update(); } -Ref<Texture> LineEdit::get_right_icon() { +Ref<Texture2D> LineEdit::get_right_icon() { return right_icon; } @@ -1746,9 +1773,6 @@ void LineEdit::_generate_context_menu() { void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed); - ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret); - - ClassDB::bind_method("_editor_settings_changed", &LineEdit::_editor_settings_changed); ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align); ClassDB::bind_method(D_METHOD("get_align"), &LineEdit::get_align); @@ -1826,10 +1850,10 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); ADD_GROUP("Placeholder", "placeholder_"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha"); ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position"); } @@ -1864,7 +1888,7 @@ LineEdit::LineEdit() { caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); caret_blink_timer->set_wait_time(0.65); - caret_blink_timer->connect("timeout", this, "_toggle_draw_caret"); + caret_blink_timer->connect("timeout", callable_mp(this, &LineEdit::_toggle_draw_caret)); cursor_set_blink_enabled(false); context_menu_enabled = true; @@ -1872,7 +1896,7 @@ LineEdit::LineEdit() { add_child(menu); editable = false; // Initialise to opposite first, so we get past the early-out in set_editable. set_editable(true); - menu->connect("id_pressed", this, "menu_option"); + menu->connect("id_pressed", callable_mp(this, &LineEdit::menu_option)); expand_to_text_length = false; } diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 037238d682..938974453a 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -91,7 +91,7 @@ private: bool shortcut_keys_enabled; - Ref<Texture> right_icon; + Ref<Texture2D> right_icon; struct Selection { @@ -232,8 +232,8 @@ public: void set_selecting_enabled(bool p_enabled); bool is_selecting_enabled() const; - void set_right_icon(const Ref<Texture> &p_icon); - Ref<Texture> get_right_icon(); + void set_right_icon(const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_right_icon(); virtual bool is_text_field() const; LineEdit(); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 6e348054e2..2b163187c5 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "menu_button.h" + #include "core/os/keyboard.h" #include "scene/main/viewport.h" @@ -137,8 +138,8 @@ MenuButton::MenuButton() { popup->hide(); add_child(popup); popup->set_pass_on_modal_close_click(false); - popup->connect("about_to_show", this, "set_pressed", varray(true)); // For when switching from another MenuButton. - popup->connect("popup_hide", this, "set_pressed", varray(false)); + popup->connect("about_to_show", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true)); // For when switching from another MenuButton. + popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); } MenuButton::~MenuButton() { diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp index 945d1850d7..0ef1f53006 100644 --- a/scene/gui/nine_patch_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -70,7 +70,7 @@ void NinePatchRect::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_center"), "set_draw_center", "is_draw_center_enabled"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); @@ -88,7 +88,7 @@ void NinePatchRect::_bind_methods() { BIND_ENUM_CONSTANT(AXIS_STRETCH_MODE_TILE_FIT); } -void NinePatchRect::set_texture(const Ref<Texture> &p_tex) { +void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) { if (texture == p_tex) return; @@ -103,7 +103,7 @@ void NinePatchRect::set_texture(const Ref<Texture> &p_tex) { _change_notify("texture"); } -Ref<Texture> NinePatchRect::get_texture() const { +Ref<Texture2D> NinePatchRect::get_texture() const { return texture; } diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h index 3329c0a64c..0ef7f6b299 100644 --- a/scene/gui/nine_patch_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -47,7 +47,7 @@ public: bool draw_center; int margin[4]; Rect2 region_rect; - Ref<Texture> texture; + Ref<Texture2D> texture; AxisStretchMode axis_h, axis_v; @@ -57,8 +57,8 @@ protected: static void _bind_methods(); public: - void set_texture(const Ref<Texture> &p_tex); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_tex); + Ref<Texture2D> get_texture() const; void set_patch_margin(Margin p_margin, int p_size); int get_patch_margin(Margin p_margin) const; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 3f46afa8e8..c185761beb 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "option_button.h" + #include "core/print_string.h" Size2 OptionButton::get_minimum_size() const { @@ -58,7 +59,7 @@ void OptionButton::_notification(int p_what) { return; RID ci = get_canvas_item(); - Ref<Texture> arrow = Control::get_icon("arrow"); + Ref<Texture2D> arrow = Control::get_icon("arrow"); Color clr = Color(1, 1, 1); if (get_constant("modulate_arrow")) { switch (get_draw_mode()) { @@ -114,7 +115,7 @@ void OptionButton::pressed() { popup->popup(); } -void OptionButton::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id) { +void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id) { popup->add_icon_radio_check_item(p_icon, p_label, p_id); if (popup->get_item_count() == 1) @@ -134,7 +135,7 @@ void OptionButton::set_item_text(int p_idx, const String &p_text) { if (current == p_idx) set_text(p_text); } -void OptionButton::set_item_icon(int p_idx, const Ref<Texture> &p_icon) { +void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { popup->set_item_icon(p_idx, p_icon); @@ -161,7 +162,7 @@ String OptionButton::get_item_text(int p_idx) const { return popup->get_item_text(p_idx); } -Ref<Texture> OptionButton::get_item_icon(int p_idx) const { +Ref<Texture2D> OptionButton::get_item_icon(int p_idx) const { return popup->get_item_icon(p_idx); } @@ -289,7 +290,7 @@ void OptionButton::_set_items(const Array &p_items) { for (int i = 0; i < p_items.size(); i += 5) { String text = p_items[i + 0]; - Ref<Texture> icon = p_items[i + 1]; + Ref<Texture2D> icon = p_items[i + 1]; bool disabled = p_items[i + 2]; int id = p_items[i + 3]; Variant meta = p_items[i + 4]; @@ -309,9 +310,6 @@ void OptionButton::get_translatable_strings(List<String> *p_strings) const { void OptionButton::_bind_methods() { - ClassDB::bind_method(D_METHOD("_selected"), &OptionButton::_selected); - ClassDB::bind_method(D_METHOD("_focused"), &OptionButton::_focused); - ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &OptionButton::set_item_text); @@ -363,9 +361,9 @@ OptionButton::OptionButton() { popup->set_pass_on_modal_close_click(false); popup->set_notify_transform(true); popup->set_allow_search(true); - popup->connect("index_pressed", this, "_selected"); - popup->connect("id_focused", this, "_focused"); - popup->connect("popup_hide", this, "set_pressed", varray(false)); + popup->connect("index_pressed", callable_mp(this, &OptionButton::_selected)); + popup->connect("id_focused", callable_mp(this, &OptionButton::_focused)); + popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false)); } OptionButton::~OptionButton() { diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 04bd28fe28..9658e1fea8 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -57,17 +57,17 @@ protected: static void _bind_methods(); public: - void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1); + void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1); void add_item(const String &p_label, int p_id = -1); void set_item_text(int p_idx, const String &p_text); - void set_item_icon(int p_idx, const Ref<Texture> &p_icon); + void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon); void set_item_id(int p_idx, int p_id); void set_item_metadata(int p_idx, const Variant &p_metadata); void set_item_disabled(int p_idx, bool p_disabled); String get_item_text(int p_idx) const; - Ref<Texture> get_item_icon(int p_idx) const; + Ref<Texture2D> get_item_icon(int p_idx) const; int get_item_id(int p_idx) const; int get_item_index(int p_id) const; Variant get_item_metadata(int p_idx) const; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 87f17838cf..e75dadd5e0 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "popup_menu.h" + #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -467,9 +468,9 @@ void PopupMenu::_notification(int p_what) { Ref<StyleBox> hover = get_stylebox("hover"); Ref<Font> font = get_font("font"); // In Item::checkable_type enum order (less the non-checkable member) - Ref<Texture> check[] = { get_icon("checked"), get_icon("radio_checked") }; - Ref<Texture> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") }; - Ref<Texture> submenu = get_icon("submenu"); + Ref<Texture2D> check[] = { get_icon("checked"), get_icon("radio_checked") }; + Ref<Texture2D> uncheck[] = { get_icon("unchecked"), get_icon("radio_unchecked") }; + Ref<Texture2D> submenu = get_icon("submenu"); Ref<StyleBox> separator = get_stylebox("separator"); Ref<StyleBox> labeled_separator_left = get_stylebox("labeled_separator_left"); Ref<StyleBox> labeled_separator_right = get_stylebox("labeled_separator_right"); @@ -549,7 +550,7 @@ void PopupMenu::_notification(int p_what) { Color icon_color(1, 1, 1, items[i].disabled ? 0.5 : 1); if (items[i].checkable_type) { - Texture *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); + Texture2D *icon = (items[i].checked ? check[items[i].checkable_type - 1] : uncheck[items[i].checkable_type - 1]).ptr(); icon->draw(ci, item_ofs + Point2(0, Math::floor((h - icon->get_height()) / 2.0)), icon_color); } @@ -651,7 +652,7 @@ void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) { minimum_size_changed(); } -void PopupMenu::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { +void PopupMenu::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { Item item; ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); @@ -671,7 +672,7 @@ void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel minimum_size_changed(); } -void PopupMenu::add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { +void PopupMenu::add_icon_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { Item item; ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); @@ -692,7 +693,7 @@ void PopupMenu::add_radio_check_item(const String &p_label, int p_id, uint32_t p minimum_size_changed(); } -void PopupMenu::add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { +void PopupMenu::add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { Item item; ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); @@ -732,7 +733,7 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g minimum_size_changed(); } -void PopupMenu::add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); @@ -752,7 +753,7 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo minimum_size_changed(); } -void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); @@ -773,7 +774,7 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_ minimum_size_changed(); } -void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { +void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); @@ -810,7 +811,7 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) { update(); minimum_size_changed(); } -void PopupMenu::set_item_icon(int p_idx, const Ref<Texture> &p_icon) { +void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].icon = p_icon; @@ -893,9 +894,9 @@ int PopupMenu::get_item_idx_from_text(const String &text) const { return -1; } -Ref<Texture> PopupMenu::get_item_icon(int p_idx) const { +Ref<Texture2D> PopupMenu::get_item_icon(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>()); return items[p_idx].icon; } @@ -1074,7 +1075,7 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo Ref<InputEventKey> k = p_event; if (k.is_valid()) { - code = k->get_scancode(); + code = k->get_keycode(); if (code == 0) code = k->get_unicode(); if (k->get_control()) @@ -1233,7 +1234,7 @@ void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) { if (!shortcut_refcount.has(p_sc)) { shortcut_refcount[p_sc] = 1; - p_sc->connect("changed", this, "update"); + p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); } else { shortcut_refcount[p_sc] += 1; } @@ -1244,7 +1245,7 @@ void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) { ERR_FAIL_COND(!shortcut_refcount.has(p_sc)); shortcut_refcount[p_sc]--; if (shortcut_refcount[p_sc] == 0) { - p_sc->disconnect("changed", this, "update"); + p_sc->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update)); shortcut_refcount.erase(p_sc); } } @@ -1257,7 +1258,7 @@ void PopupMenu::_set_items(const Array &p_items) { for (int i = 0; i < p_items.size(); i += 10) { String text = p_items[i + 0]; - Ref<Texture> icon = p_items[i + 1]; + Ref<Texture2D> icon = p_items[i + 1]; // For compatibility, use false/true for no/checkbox and integers for other values bool checkable = p_items[i + 2]; bool radio_checkable = (int)p_items[i + 2] == Item::CHECKABLE_TYPE_RADIO_BUTTON; @@ -1471,13 +1472,11 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("set_allow_search", "allow"), &PopupMenu::set_allow_search); ClassDB::bind_method(D_METHOD("get_allow_search"), &PopupMenu::get_allow_search); - ClassDB::bind_method(D_METHOD("_submenu_timeout"), &PopupMenu::_submenu_timeout); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_item_selection"), "set_hide_on_item_selection", "is_hide_on_item_selection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_checkable_item_selection"), "set_hide_on_checkable_item_selection", "is_hide_on_checkable_item_selection"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_on_state_item_selection"), "set_hide_on_state_item_selection", "is_hide_on_state_item_selection"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "submenu_popup_delay"), "set_submenu_popup_delay", "get_submenu_popup_delay"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_search"), "set_allow_search", "get_allow_search"); ADD_SIGNAL(MethodInfo("id_pressed", PropertyInfo(Variant::INT, "id"))); @@ -1514,7 +1513,7 @@ PopupMenu::PopupMenu() { submenu_timer = memnew(Timer); submenu_timer->set_wait_time(0.3); submenu_timer->set_one_shot(true); - submenu_timer->connect("timeout", this, "_submenu_timeout"); + submenu_timer->connect("timeout", callable_mp(this, &PopupMenu::_submenu_timeout)); add_child(submenu_timer); } diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index f77ede0a8b..a3a858cfde 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -38,7 +38,7 @@ class PopupMenu : public Popup { GDCLASS(PopupMenu, Popup); struct Item { - Ref<Texture> icon; + Ref<Texture2D> icon; String text; String xl_text; bool checked; @@ -121,25 +121,25 @@ protected: public: void add_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); - void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); + void add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); - void add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); + void add_icon_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_radio_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); - void add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); + void add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0); void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1); void set_item_text(int p_idx, const String &p_text); - void set_item_icon(int p_idx, const Ref<Texture> &p_icon); + void set_item_icon(int p_idx, const Ref<Texture2D> &p_icon); void set_item_checked(int p_idx, bool p_checked); void set_item_id(int p_idx, int p_id); void set_item_accelerator(int p_idx, uint32_t p_accel); @@ -160,7 +160,7 @@ public: String get_item_text(int p_idx) const; int get_item_idx_from_text(const String &text) const; - Ref<Texture> get_item_icon(int p_idx) const; + Ref<Texture2D> get_item_icon(int p_idx) const; bool is_item_checked(int p_idx) const; int get_item_id(int p_idx) const; int get_item_index(int p_id) const; diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index 6b6f5bca93..adc5f81465 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -267,15 +267,15 @@ void Range::_bind_methods() { ClassDB::bind_method(D_METHOD("share", "with"), &Range::_share); ClassDB::bind_method(D_METHOD("unshare"), &Range::unshare); - ADD_SIGNAL(MethodInfo("value_changed", PropertyInfo(Variant::REAL, "value"))); + ADD_SIGNAL(MethodInfo("value_changed", PropertyInfo(Variant::FLOAT, "value"))); ADD_SIGNAL(MethodInfo("changed")); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value"), "set_min", "get_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value"), "set_max", "get_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "page"), "set_page", "get_page"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "value"), "set_value", "get_value"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ratio", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_as_ratio", "get_as_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_value"), "set_min", "get_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_value"), "set_max", "get_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "page"), "set_page", "get_page"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "value"), "set_value", "get_value"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_as_ratio", "get_as_ratio"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exp_edit"), "set_exp_ratio", "is_ratio_exp"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rounded"), "set_use_rounded_values", "is_using_rounded_values"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_greater"), "set_allow_greater", "is_greater_allowed"); diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp index c5b1685ff9..0f5926ea1c 100644 --- a/scene/gui/rich_text_effect.cpp +++ b/scene/gui/rich_text_effect.cpp @@ -91,7 +91,7 @@ void CharFXTransform::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "relative_index"), "set_relative_index", "get_relative_index"); ADD_PROPERTY(PropertyInfo(Variant::INT, "absolute_index"), "set_absolute_index", "get_absolute_index"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "elapsed_time"), "set_elapsed_time", "get_elapsed_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "elapsed_time"), "set_elapsed_time", "get_elapsed_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visibility", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index af5d0e2f45..bc1510d6f6 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -204,6 +204,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int line_ascent = cfont->get_ascent(); int line_descent = cfont->get_descent(); + int backtrack = 0; // for dynamic hidden content. + int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW Variant meta; @@ -214,6 +216,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & { \ if (p_mode != PROCESS_CACHE) { \ line++; \ + backtrack = 0; \ if (!line_is_blank) { \ nonblank_line_count++; \ } \ @@ -263,7 +266,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \ l.minimum_width = MAX(l.minimum_width, m_width); \ } \ - if (wofs + m_width > p_width) { \ + if (wofs - backtrack + m_width > p_width) { \ line_wrapped = true; \ if (p_mode == PROCESS_CACHE) { \ if (spaces > 0) \ @@ -390,6 +393,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int fw = 0; lh = 0; + if (p_mode != PROCESS_CACHE) { lh = line < l.height_caches.size() ? l.height_caches[line] : 1; line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; @@ -432,13 +436,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & { - int ofs = 0; + int ofs = 0 - backtrack; for (int i = 0; i < end; i++) { int pofs = wofs + ofs; if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) { - //int o = (wofs+w)-p_click_pos.x; int cw = font->get_char_size(c[i], c[i + 1]).x; @@ -481,7 +484,10 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) && faded_visibility > 0.0f); + const bool previously_visible = visible; + for (int j = 0; j < fx_stack.size(); j++) { + ItemFX *item_fx = fx_stack[j]; if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) { @@ -575,6 +581,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & } else { cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color); } + } else if (previously_visible) { + backtrack += font->get_char_size(fx_char, c[i + 1]).x; } p_char_count++; @@ -648,6 +656,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & case ITEM_NEWLINE: { lh = 0; + if (p_mode != PROCESS_CACHE) { lh = line < l.height_caches.size() ? l.height_caches[line] : 1; line_is_blank = true; @@ -1199,49 +1208,59 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { if (k.is_valid()) { if (k->is_pressed() && !k->get_alt() && !k->get_shift()) { - bool handled = true; - switch (k->get_scancode()) { + bool handled = false; + switch (k->get_keycode()) { case KEY_PAGEUP: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(vscroll->get_value() - vscroll->get_page()); + handled = true; + } } break; case KEY_PAGEDOWN: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(vscroll->get_value() + vscroll->get_page()); + handled = true; + } } break; case KEY_UP: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(vscroll->get_value() - get_font("normal_font")->get_height()); + handled = true; + } } break; case KEY_DOWN: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(vscroll->get_value() + get_font("normal_font")->get_height()); + handled = true; + } } break; case KEY_HOME: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(0); + handled = true; + } } break; case KEY_END: { - if (vscroll->is_visible_in_tree()) + if (vscroll->is_visible_in_tree()) { vscroll->set_value(vscroll->get_max()); + handled = true; + } } break; case KEY_INSERT: case KEY_C: { if (k->get_command()) { selection_copy(); - } else { - handled = false; + handled = true; } } break; - default: handled = false; } if (handled) @@ -1648,7 +1667,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub } } -void RichTextLabel::add_image(const Ref<Texture> &p_image, const int p_width, const int p_height) { +void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) { if (current->type == ITEM_TABLE) return; @@ -2204,7 +2223,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1); - Ref<Texture> texture = ResourceLoader::load(image, "Texture"); + Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D"); if (texture.is_valid()) add_image(texture); @@ -2230,7 +2249,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1); - Ref<Texture> texture = ResourceLoader::load(image, "Texture"); + Ref<Texture2D> texture = ResourceLoader::load(image, "Texture"); if (texture.is_valid()) add_image(texture, width, height); @@ -2655,7 +2674,7 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) { Vector<Variant> RichTextLabel::get_effects() { Vector<Variant> r; for (int i = 0; i < custom_effects.size(); i++) { - r.push_back(custom_effects[i].get_ref_ptr()); + r.push_back(custom_effects[i]); } return r; } @@ -2680,7 +2699,6 @@ int RichTextLabel::get_content_height() { void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input); - ClassDB::bind_method(D_METHOD("_scroll_changed"), &RichTextLabel::_scroll_changed); ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text); ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text); ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text); @@ -2762,7 +2780,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "bbcode_text", PROPERTY_HINT_MULTILINE_TEXT), "set_bbcode", "get_bbcode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); @@ -2944,7 +2962,7 @@ RichTextLabel::RichTextLabel() { vscroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); vscroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); vscroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); - vscroll->connect("value_changed", this, "_scroll_changed"); + vscroll->connect("value_changed", callable_mp(this, &RichTextLabel::_scroll_changed)); vscroll->set_step(1); vscroll->hide(); current_idx = 1; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 61ac0bd86c..409aec0ca6 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -147,7 +147,7 @@ private: }; struct ItemImage : public Item { - Ref<Texture> image; + Ref<Texture2D> image; Size2 size; ItemImage() { type = ITEM_IMAGE; } }; @@ -407,7 +407,7 @@ protected: public: String get_text(); void add_text(const String &p_text); - void add_image(const Ref<Texture> &p_image, const int p_width = 0, const int p_height = 0); + void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0); void add_newline(); bool remove_line(const int p_line); void push_font(const Ref<Font> &p_font); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 45fa212886..fef5e00984 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -71,8 +71,8 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) { if (b->is_pressed()) { double ofs = orientation == VERTICAL ? b->get_position().y : b->get_position().x; - Ref<Texture> decr = get_icon("decrement"); - Ref<Texture> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width(); @@ -148,7 +148,7 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) { if (drag.active) { double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x; - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> decr = get_icon("decrement"); double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); ofs -= decr_size; @@ -159,8 +159,8 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) { } else { double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x; - Ref<Texture> decr = get_icon("decrement"); - Ref<Texture> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width(); double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width(); @@ -233,8 +233,8 @@ void ScrollBar::_notification(int p_what) { RID ci = get_canvas_item(); - Ref<Texture> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement"); - Ref<Texture> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment"); + Ref<Texture2D> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement"); + Ref<Texture2D> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment"); Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll"); Ref<StyleBox> grabber; @@ -296,15 +296,15 @@ void ScrollBar::_notification(int p_what) { } if (drag_node) { - drag_node->connect("gui_input", this, "_drag_node_input"); - drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT); + drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), varray(), CONNECT_ONESHOT); } } if (p_what == NOTIFICATION_EXIT_TREE) { if (drag_node) { - drag_node->disconnect("gui_input", this, "_drag_node_input"); - drag_node->disconnect("tree_exiting", this, "_drag_node_exit"); + drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit)); } drag_node = NULL; @@ -500,8 +500,8 @@ double ScrollBar::get_grabber_offset() const { Size2 ScrollBar::get_minimum_size() const { - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); Ref<StyleBox> bg = get_stylebox("scroll"); Size2 minsize; @@ -539,7 +539,7 @@ float ScrollBar::get_custom_step() const { void ScrollBar::_drag_node_exit() { if (drag_node) { - drag_node->disconnect("gui_input", this, "_drag_node_input"); + drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); } drag_node = NULL; } @@ -611,8 +611,8 @@ void ScrollBar::set_drag_node(const NodePath &p_path) { if (is_inside_tree()) { if (drag_node) { - drag_node->disconnect("gui_input", this, "_drag_node_input"); - drag_node->disconnect("tree_exiting", this, "_drag_node_exit"); + drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit)); } } @@ -627,8 +627,8 @@ void ScrollBar::set_drag_node(const NodePath &p_path) { } if (drag_node) { - drag_node->connect("gui_input", this, "_drag_node_input"); - drag_node->connect("tree_exiting", this, "_drag_node_exit", varray(), CONNECT_ONESHOT); + drag_node->connect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input)); + drag_node->connect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit), varray(), CONNECT_ONESHOT); } } } @@ -651,12 +651,10 @@ void ScrollBar::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollBar::_gui_input); ClassDB::bind_method(D_METHOD("set_custom_step", "step"), &ScrollBar::set_custom_step); ClassDB::bind_method(D_METHOD("get_custom_step"), &ScrollBar::get_custom_step); - ClassDB::bind_method(D_METHOD("_drag_node_input"), &ScrollBar::_drag_node_input); - ClassDB::bind_method(D_METHOD("_drag_node_exit"), &ScrollBar::_drag_node_exit); ADD_SIGNAL(MethodInfo("scrolling")); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "custom_step", PROPERTY_HINT_RANGE, "-1,4096"), "set_custom_step", "get_custom_step"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_step", PROPERTY_HINT_RANGE, "-1,4096"), "set_custom_step", "get_custom_step"); } ScrollBar::ScrollBar(Orientation p_orientation) { diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 509e6d19f6..c25a6d5a0c 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -267,7 +267,7 @@ void ScrollContainer::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { - get_viewport()->connect("gui_focus_changed", this, "_ensure_focused_visible"); + get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible)); } if (p_what == NOTIFICATION_SORT_CHILDREN) { @@ -570,14 +570,12 @@ VScrollBar *ScrollContainer::get_v_scrollbar() { void ScrollContainer::_bind_methods() { - ClassDB::bind_method(D_METHOD("_scroll_moved"), &ScrollContainer::_scroll_moved); ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input); ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll); ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled); ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll); ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled); ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position); - ClassDB::bind_method(D_METHOD("_ensure_focused_visible"), &ScrollContainer::_ensure_focused_visible); ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll); ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll); ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll); @@ -610,12 +608,12 @@ ScrollContainer::ScrollContainer() { h_scroll = memnew(HScrollBar); h_scroll->set_name("_h_scroll"); add_child(h_scroll); - h_scroll->connect("value_changed", this, "_scroll_moved"); + h_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved)); v_scroll = memnew(VScrollBar); v_scroll->set_name("_v_scroll"); add_child(v_scroll); - v_scroll->connect("value_changed", this, "_scroll_moved"); + v_scroll->connect("value_changed", callable_mp(this, &ScrollContainer::_scroll_moved)); drag_speed = Vector2(); drag_touching = false; diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp index 9b3ed35e6e..85887ef7b1 100644 --- a/scene/gui/slider.cpp +++ b/scene/gui/slider.cpp @@ -36,7 +36,7 @@ Size2 Slider::get_minimum_size() const { Ref<StyleBox> style = get_stylebox("slider"); Size2i ss = style->get_minimum_size() + style->get_center_size(); - Ref<Texture> grabber = get_icon("grabber"); + Ref<Texture2D> grabber = get_icon("grabber"); Size2i rs = grabber->get_size(); if (orientation == HORIZONTAL) @@ -57,7 +57,7 @@ void Slider::_gui_input(Ref<InputEvent> p_event) { if (mb->get_button_index() == BUTTON_LEFT) { if (mb->is_pressed()) { - Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber"); + Ref<Texture2D> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber"); grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x; double grab_width = (double)grabber->get_size().width; @@ -87,7 +87,7 @@ void Slider::_gui_input(Ref<InputEvent> p_event) { if (grab.active) { Size2i size = get_size(); - Ref<Texture> grabber = get_icon("grabber"); + Ref<Texture2D> grabber = get_icon("grabber"); float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos; if (orientation == VERTICAL) motion = -motion; @@ -167,8 +167,8 @@ void Slider::_notification(int p_what) { Size2i size = get_size(); Ref<StyleBox> style = get_stylebox("slider"); Ref<StyleBox> grabber_area = get_stylebox("grabber_area"); - Ref<Texture> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled"); - Ref<Texture> tick = get_icon("tick"); + Ref<Texture2D> grabber = get_icon(editable ? ((mouse_inside || has_focus()) ? "grabber_highlight" : "grabber") : "grabber_disabled"); + Ref<Texture2D> tick = get_icon("tick"); double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio(); if (orientation == VERTICAL) { diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 92377949f8..576de98a4f 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -182,7 +182,7 @@ void SpinBox::_line_edit_focus_exit() { _text_entered(line_edit->get_text()); } -inline void SpinBox::_adjust_width_for_icon(const Ref<Texture> &icon) { +inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) { int w = icon->get_width(); if (w != last_w) { @@ -195,7 +195,7 @@ void SpinBox::_notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { - Ref<Texture> updown = get_icon("updown"); + Ref<Texture2D> updown = get_icon("updown"); _adjust_width_for_icon(updown); @@ -267,7 +267,6 @@ void SpinBox::_bind_methods() { //ClassDB::bind_method(D_METHOD("_value_changed"),&SpinBox::_value_changed); ClassDB::bind_method(D_METHOD("_gui_input"), &SpinBox::_gui_input); - ClassDB::bind_method(D_METHOD("_text_entered"), &SpinBox::_text_entered); ClassDB::bind_method(D_METHOD("set_align", "align"), &SpinBox::set_align); ClassDB::bind_method(D_METHOD("get_align"), &SpinBox::get_align); ClassDB::bind_method(D_METHOD("set_suffix", "suffix"), &SpinBox::set_suffix); @@ -277,10 +276,7 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("set_editable", "editable"), &SpinBox::set_editable); ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable); ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply); - ClassDB::bind_method(D_METHOD("_line_edit_focus_exit"), &SpinBox::_line_edit_focus_exit); ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit); - ClassDB::bind_method(D_METHOD("_line_edit_input"), &SpinBox::_line_edit_input); - ClassDB::bind_method(D_METHOD("_range_click_timeout"), &SpinBox::_range_click_timeout); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); @@ -297,12 +293,12 @@ SpinBox::SpinBox() { line_edit->set_anchors_and_margins_preset(Control::PRESET_WIDE); line_edit->set_mouse_filter(MOUSE_FILTER_PASS); //connect("value_changed",this,"_value_changed"); - line_edit->connect("text_entered", this, "_text_entered", Vector<Variant>(), CONNECT_DEFERRED); - line_edit->connect("focus_exited", this, "_line_edit_focus_exit", Vector<Variant>(), CONNECT_DEFERRED); - line_edit->connect("gui_input", this, "_line_edit_input"); + line_edit->connect("text_entered", callable_mp(this, &SpinBox::_text_entered), Vector<Variant>(), CONNECT_DEFERRED); + line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), Vector<Variant>(), CONNECT_DEFERRED); + line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input)); drag.enabled = false; range_click_timer = memnew(Timer); - range_click_timer->connect("timeout", this, "_range_click_timeout"); + range_click_timer->connect("timeout", callable_mp(this, &SpinBox::_range_click_timeout)); add_child(range_click_timer); } diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 04491c8477..d3a3d8fe3d 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -62,7 +62,7 @@ class SpinBox : public Range { void _line_edit_focus_exit(); - inline void _adjust_width_for_icon(const Ref<Texture> &icon); + inline void _adjust_width_for_icon(const Ref<Texture2D> &icon); protected: void _gui_input(const Ref<InputEvent> &p_event); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 079907db07..255278be2b 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -74,7 +74,7 @@ void SplitContainer::_resort() { bool second_expanded = (vertical ? second->get_v_size_flags() : second->get_h_size_flags()) & SIZE_EXPAND; // Determine the separation between items - Ref<Texture> g = get_icon("grabber"); + Ref<Texture2D> g = get_icon("grabber"); int sep = get_constant("separation"); sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; @@ -123,7 +123,7 @@ Size2 SplitContainer::get_minimum_size() const { /* Calculate MINIMUM SIZE */ Size2i minimum; - Ref<Texture> g = get_icon("grabber"); + Ref<Texture2D> g = get_icon("grabber"); int sep = get_constant("separation"); sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0; @@ -182,7 +182,7 @@ void SplitContainer::_notification(int p_what) { return; int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_constant("separation") : 0; - Ref<Texture> tex = get_icon("grabber"); + Ref<Texture2D> tex = get_icon("grabber"); Size2 size = get_size(); if (vertical) diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index b045ff4fe1..6290d364fc 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -58,7 +58,7 @@ int TabContainer::_get_top_margin() const { if (!c->has_meta("_tab_icon")) continue; - Ref<Texture> tex = c->get_meta("_tab_icon"); + Ref<Texture2D> tex = c->get_meta("_tab_icon"); if (!tex.is_valid()) continue; content_height = MAX(content_height, tex->get_size().height); @@ -81,7 +81,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { return; // Handle menu button. - Ref<Texture> menu = get_icon("menu"); + Ref<Texture2D> menu = get_icon("menu"); if (popup && pos.x > size.width - menu->get_width()) { emit_signal("pre_popup_pressed"); @@ -107,8 +107,8 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { popup_ofs = menu->get_width(); } - Ref<Texture> increment = get_icon("increment"); - Ref<Texture> decrement = get_icon("decrement"); + Ref<Texture2D> increment = get_icon("increment"); + Ref<Texture2D> decrement = get_icon("decrement"); if (pos.x > size.width - increment->get_width() - popup_ofs) { if (last_tab_cache < tabs.size() - 1) { first_tab_cache += 1; @@ -159,7 +159,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { return; } - Ref<Texture> menu = get_icon("menu"); + Ref<Texture2D> menu = get_icon("menu"); if (popup) { if (pos.x >= size.width - menu->get_width()) { @@ -191,8 +191,8 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { popup_ofs = menu->get_width(); } - Ref<Texture> increment = get_icon("increment"); - Ref<Texture> decrement = get_icon("decrement"); + Ref<Texture2D> increment = get_icon("increment"); + Ref<Texture2D> decrement = get_icon("decrement"); if (pos.x >= size.width - increment->get_width() - popup_ofs) { if (highlight_arrow != 1) { @@ -225,9 +225,9 @@ void TabContainer::_notification(int p_what) { Vector<Control *> tabs = _get_tabs(); int side_margin = get_constant("side_margin"); - Ref<Texture> menu = get_icon("menu"); - Ref<Texture> increment = get_icon("increment"); - Ref<Texture> decrement = get_icon("decrement"); + Ref<Texture2D> menu = get_icon("menu"); + Ref<Texture2D> increment = get_icon("increment"); + Ref<Texture2D> decrement = get_icon("decrement"); int header_width = get_size().width - side_margin * 2; // Find the width of the header area. @@ -272,12 +272,12 @@ void TabContainer::_notification(int p_what) { Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); - Ref<Texture> increment = get_icon("increment"); - Ref<Texture> increment_hl = get_icon("increment_highlight"); - Ref<Texture> decrement = get_icon("decrement"); - Ref<Texture> decrement_hl = get_icon("decrement_highlight"); - Ref<Texture> menu = get_icon("menu"); - Ref<Texture> menu_hl = get_icon("menu_highlight"); + Ref<Texture2D> increment = get_icon("increment"); + Ref<Texture2D> increment_hl = get_icon("increment_highlight"); + Ref<Texture2D> decrement = get_icon("decrement"); + Ref<Texture2D> decrement_hl = get_icon("decrement_highlight"); + Ref<Texture2D> menu = get_icon("menu"); + Ref<Texture2D> menu_hl = get_icon("menu_highlight"); Ref<Font> font = get_font("font"); Color font_color_fg = get_color("font_color_fg"); Color font_color_bg = get_color("font_color_bg"); @@ -383,7 +383,7 @@ void TabContainer::_notification(int p_what) { // Draw the tab icon. if (control->has_meta("_tab_icon")) { - Ref<Texture> icon = control->get_meta("_tab_icon"); + Ref<Texture2D> icon = control->get_meta("_tab_icon"); if (icon.is_valid()) { int y = y_center - (icon->get_height() / 2); icon->draw(canvas, Point2i(x_content, y)); @@ -464,7 +464,7 @@ int TabContainer::_get_tab_width(int p_index) const { // Add space for a tab icon. if (control->has_meta("_tab_icon")) { - Ref<Texture> icon = control->get_meta("_tab_icon"); + Ref<Texture2D> icon = control->get_meta("_tab_icon"); if (icon.is_valid()) { width += icon->get_width(); if (text != "") @@ -537,8 +537,8 @@ void TabContainer::add_child_notify(Node *p_child) { c->set_margin(Margin(MARGIN_BOTTOM), c->get_margin(Margin(MARGIN_BOTTOM)) - sb->get_margin(Margin(MARGIN_BOTTOM))); update(); - p_child->connect("renamed", this, "_child_renamed_callback"); - if (first) + p_child->connect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); + if (first && is_inside_tree()) emit_signal("tab_changed", current); } @@ -620,7 +620,7 @@ void TabContainer::remove_child_notify(Node *p_child) { call_deferred("_update_current_tab"); - p_child->disconnect("renamed", this, "_child_renamed_callback"); + p_child->disconnect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback)); update(); } @@ -648,7 +648,7 @@ Variant TabContainer::get_drag_data(const Point2 &p_point) { HBoxContainer *drag_preview = memnew(HBoxContainer); - Ref<Texture> icon = get_tab_icon(tab_over); + Ref<Texture2D> icon = get_tab_icon(tab_over); if (!icon.is_null()) { TextureRect *tf = memnew(TextureRect); tf->set_texture(icon); @@ -745,12 +745,12 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const { int right_ofs = 0; if (popup) { - Ref<Texture> menu = get_icon("menu"); + Ref<Texture2D> menu = get_icon("menu"); right_ofs += menu->get_width(); } if (buttons_visible_cache) { - Ref<Texture> increment = get_icon("increment"); - Ref<Texture> decrement = get_icon("decrement"); + Ref<Texture2D> increment = get_icon("increment"); + Ref<Texture2D> decrement = get_icon("decrement"); right_ofs += increment->get_width() + decrement->get_width(); } if (p_point.x > size.width - right_ofs) { @@ -834,21 +834,21 @@ String TabContainer::get_tab_title(int p_tab) const { return child->get_name(); } -void TabContainer::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) { +void TabContainer::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { Control *child = _get_tab(p_tab); ERR_FAIL_COND(!child); child->set_meta("_tab_icon", p_icon); update(); } -Ref<Texture> TabContainer::get_tab_icon(int p_tab) const { +Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const { Control *child = _get_tab(p_tab); - ERR_FAIL_COND_V(!child, Ref<Texture>()); + ERR_FAIL_COND_V(!child, Ref<Texture2D>()); if (child->has_meta("_tab_icon")) return child->get_meta("_tab_icon"); else - return Ref<Texture>(); + return Ref<Texture2D>(); } void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) { @@ -1011,9 +1011,7 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_hidden_tabs_for_min_size", "enabled"), &TabContainer::set_use_hidden_tabs_for_min_size); ClassDB::bind_method(D_METHOD("get_use_hidden_tabs_for_min_size"), &TabContainer::get_use_hidden_tabs_for_min_size); - ClassDB::bind_method(D_METHOD("_child_renamed_callback"), &TabContainer::_child_renamed_callback); ClassDB::bind_method(D_METHOD("_on_theme_changed"), &TabContainer::_on_theme_changed); - ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &TabContainer::_on_mouse_exited); ClassDB::bind_method(D_METHOD("_update_current_tab"), &TabContainer::_update_current_tab); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); @@ -1048,5 +1046,5 @@ TabContainer::TabContainer() { tabs_rearrange_group = -1; use_hidden_tabs_for_min_size = false; - connect("mouse_exited", this, "_on_mouse_exited"); + connect("mouse_exited", callable_mp(this, &TabContainer::_on_mouse_exited)); } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index c5a9045ca6..38c029475c 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -93,8 +93,8 @@ public: void set_tab_title(int p_tab, const String &p_title); String get_tab_title(int p_tab) const; - void set_tab_icon(int p_tab, const Ref<Texture> &p_icon); - Ref<Texture> get_tab_icon(int p_tab) const; + void set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_tab_icon(int p_tab) const; void set_tab_disabled(int p_tab, bool p_disabled); bool get_tab_disabled(int p_tab) const; diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 6cd95e73fc..901408919a 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -46,7 +46,7 @@ Size2 Tabs::get_minimum_size() const { for (int i = 0; i < tabs.size(); i++) { - Ref<Texture> tex = tabs[i].icon; + Ref<Texture2D> tex = tabs[i].icon; if (tex.is_valid()) { ms.height = MAX(ms.height, tex->get_size().height); if (tabs[i].text != "") @@ -63,7 +63,7 @@ Size2 Tabs::get_minimum_size() const { ms.width += tab_bg->get_minimum_size().width; if (tabs[i].right_button.is_valid()) { - Ref<Texture> rb = tabs[i].right_button; + Ref<Texture2D> rb = tabs[i].right_button; Size2 bms = rb->get_size(); bms.width += get_constant("hseparation"); ms.width += bms.width; @@ -71,7 +71,7 @@ Size2 Tabs::get_minimum_size() const { } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<Texture> cb = get_icon("close"); + Ref<Texture2D> cb = get_icon("close"); Size2 bms = cb->get_size(); bms.width += get_constant("hseparation"); ms.width += bms.width; @@ -94,8 +94,8 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { highlight_arrow = -1; if (buttons_visible) { - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); @@ -163,8 +163,8 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { if (buttons_visible) { - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); @@ -245,7 +245,7 @@ void Tabs::_notification(int p_what) { Color color_fg = get_color("font_color_fg"); Color color_bg = get_color("font_color_bg"); Color color_disabled = get_color("font_color_disabled"); - Ref<Texture> close = get_icon("close"); + Ref<Texture2D> close = get_icon("close"); int h = get_size().height; int w = 0; @@ -267,10 +267,10 @@ void Tabs::_notification(int p_what) { w = 0; } - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); - Ref<Texture> incr_hl = get_icon("increment_highlight"); - Ref<Texture> decr_hl = get_icon("decrement_highlight"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); + Ref<Texture2D> incr_hl = get_icon("increment_highlight"); + Ref<Texture2D> decr_hl = get_icon("decrement_highlight"); int limit = get_size().width - incr->get_size().width - decr->get_size().width; @@ -313,7 +313,7 @@ void Tabs::_notification(int p_what) { w += sb->get_margin(MARGIN_LEFT); Size2i sb_ms = sb->get_minimum_size(); - Ref<Texture> icon = tabs[i].icon; + Ref<Texture2D> icon = tabs[i].icon; if (icon.is_valid()) { icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); @@ -328,7 +328,7 @@ void Tabs::_notification(int p_what) { if (tabs[i].right_button.is_valid()) { Ref<StyleBox> style = get_stylebox("button"); - Ref<Texture> rb = tabs[i].right_button; + Ref<Texture2D> rb = tabs[i].right_button; w += get_constant("hseparation"); @@ -352,7 +352,7 @@ void Tabs::_notification(int p_what) { if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { Ref<StyleBox> style = get_stylebox("button"); - Ref<Texture> cb = close; + Ref<Texture2D> cb = close; w += get_constant("hseparation"); @@ -449,7 +449,7 @@ String Tabs::get_tab_title(int p_tab) const { return tabs[p_tab].text; } -void Tabs::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) { +void Tabs::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].icon = p_icon; @@ -457,9 +457,9 @@ void Tabs::set_tab_icon(int p_tab, const Ref<Texture> &p_icon) { minimum_size_changed(); } -Ref<Texture> Tabs::get_tab_icon(int p_tab) const { +Ref<Texture2D> Tabs::get_tab_icon(int p_tab) const { - ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>()); return tabs[p_tab].icon; } @@ -475,7 +475,7 @@ bool Tabs::get_tab_disabled(int p_tab) const { return tabs[p_tab].disabled; } -void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) { +void Tabs::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].right_button = p_right_button; @@ -483,9 +483,9 @@ void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) { update(); minimum_size_changed(); } -Ref<Texture> Tabs::get_tab_right_button(int p_tab) const { +Ref<Texture2D> Tabs::get_tab_right_button(int p_tab) const { - ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>()); return tabs[p_tab].right_button; } @@ -536,8 +536,8 @@ void Tabs::_update_cache() { Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); Ref<Font> font = get_font("font"); - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); int w = 0; @@ -580,7 +580,7 @@ void Tabs::_update_cache() { slen -= get_constant("hseparation"); } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { - Ref<Texture> cb = get_icon("close"); + Ref<Texture2D> cb = get_icon("close"); slen -= cb->get_width(); slen -= get_constant("hseparation"); } @@ -604,7 +604,7 @@ void Tabs::_on_mouse_exited() { update(); } -void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { +void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { Tab t; t.text = p_str; @@ -806,7 +806,7 @@ int Tabs::get_tab_width(int p_idx) const { int x = 0; - Ref<Texture> tex = tabs[p_idx].icon; + Ref<Texture2D> tex = tabs[p_idx].icon; if (tex.is_valid()) { x += tex->get_width(); if (tabs[p_idx].text != "") @@ -823,13 +823,13 @@ int Tabs::get_tab_width(int p_idx) const { x += tab_bg->get_minimum_size().width; if (tabs[p_idx].right_button.is_valid()) { - Ref<Texture> rb = tabs[p_idx].right_button; + Ref<Texture2D> rb = tabs[p_idx].right_button; x += rb->get_width(); x += get_constant("hseparation"); } if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_idx == current)) { - Ref<Texture> cb = get_icon("close"); + Ref<Texture2D> cb = get_icon("close"); x += cb->get_width(); x += get_constant("hseparation"); } @@ -842,8 +842,8 @@ void Tabs::_ensure_no_over_offset() { if (!is_inside_tree()) return; - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); @@ -885,8 +885,8 @@ void Tabs::ensure_tab_visible(int p_idx) { } int prev_offset = offset; - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + Ref<Texture2D> incr = get_icon("increment"); + Ref<Texture2D> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); for (int i = offset; i <= p_idx; i++) { if (tabs[i].ofs_cache + tabs[i].size_cache > limit) { @@ -956,7 +956,6 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input); ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover); - ClassDB::bind_method(D_METHOD("_on_mouse_exited"), &Tabs::_on_mouse_exited); ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab); @@ -967,7 +966,7 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &Tabs::set_tab_disabled); ClassDB::bind_method(D_METHOD("get_tab_disabled", "tab_idx"), &Tabs::get_tab_disabled); ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &Tabs::remove_tab); - ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture>())); + ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>())); ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align); ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align); ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset); @@ -1034,5 +1033,5 @@ Tabs::Tabs() { drag_to_rearrange_enabled = false; tabs_rearrange_group = -1; - connect("mouse_exited", this, "_on_mouse_exited"); + connect("mouse_exited", callable_mp(this, &Tabs::_on_mouse_exited)); } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index c06e47a54a..3170acb46f 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -59,7 +59,7 @@ private: String text; String xl_text; - Ref<Texture> icon; + Ref<Texture2D> icon; int ofs_cache; bool disabled; int size_cache; @@ -67,7 +67,7 @@ private: int x_cache; int x_size_cache; - Ref<Texture> right_button; + Ref<Texture2D> right_button; Rect2 rb_rect; Rect2 cb_rect; }; @@ -115,19 +115,19 @@ protected: int get_tab_idx_at_point(const Point2 &p_point) const; public: - void add_tab(const String &p_str = "", const Ref<Texture> &p_icon = Ref<Texture>()); + void add_tab(const String &p_str = "", const Ref<Texture2D> &p_icon = Ref<Texture2D>()); void set_tab_title(int p_tab, const String &p_title); String get_tab_title(int p_tab) const; - void set_tab_icon(int p_tab, const Ref<Texture> &p_icon); - Ref<Texture> get_tab_icon(int p_tab) const; + void set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_tab_icon(int p_tab) const; void set_tab_disabled(int p_tab, bool p_disabled); bool get_tab_disabled(int p_tab) const; - void set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button); - Ref<Texture> get_tab_right_button(int p_tab) const; + void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button); + Ref<Texture2D> get_tab_right_button(int p_tab) const; void set_tab_align(TabAlign p_align); TabAlign get_tab_align() const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 93d0ae080b..5e925bf37f 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -753,10 +753,18 @@ void TextEdit::_notification(int p_what) { } } - if (line_length_guideline) { - int x = xmargin_beg + (int)cache.font->get_char_size('0').width * line_length_guideline_col - cursor.x_ofs; - if (x > xmargin_beg && x < xmargin_end) { - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(x, 0), Point2(x, size.height), cache.line_length_guideline_color); + if (line_length_guidelines) { + const int hard_x = xmargin_beg + (int)cache.font->get_char_size('0').width * line_length_guideline_hard_col - cursor.x_ofs; + if (hard_x > xmargin_beg && hard_x < xmargin_end) { + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(hard_x, 0), Point2(hard_x, size.height), cache.line_length_guideline_color); + } + + // Draw a "Soft" line length guideline, less visible than the hard line length guideline. + // It's usually set to a lower column compared to the hard line length guideline. + // Only drawn if its column differs from the hard line length guideline. + const int soft_x = xmargin_beg + (int)cache.font->get_char_size('0').width * line_length_guideline_soft_col - cursor.x_ofs; + if (hard_x != soft_x && soft_x > xmargin_beg && soft_x < xmargin_end) { + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(soft_x, 0), Point2(soft_x, size.height), cache.line_length_guideline_color * Color(1, 1, 1, 0.5)); } } @@ -1216,7 +1224,7 @@ void TextEdit::_notification(int p_what) { int horizontal_gap = (cache.info_gutter_width * 30) / 100; int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width; - Ref<Texture> info_icon = text.get_info_icon(line); + Ref<Texture2D> info_icon = text.get_info_icon(line); // Ensure the icon fits the gutter size. Size2i icon_size = info_icon->get_size(); if (icon_size.width > cache.info_gutter_width - horizontal_gap) { @@ -1645,7 +1653,7 @@ void TextEdit::_notification(int p_what) { Point2 title_pos(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs); // Draw completion icon if it is valid. - Ref<Texture> icon = completion_options[l].icon; + Ref<Texture2D> icon = completion_options[l].icon; Rect2 icon_area(completion_rect.position.x, completion_rect.position.y + i * get_row_height(), icon_area_size.width, icon_area_size.height); if (icon.is_valid()) { const real_t max_scale = 0.7f; @@ -1844,6 +1852,42 @@ void TextEdit::_consume_pair_symbol(CharType ch) { } } + String line = text[cursor.line]; + + bool in_single_quote = false; + bool in_double_quote = false; + + int c = 0; + while (c < line.length()) { + if (line[c] == '\\') { + c++; // Skip quoted anything. + + if (cursor.column == c) { + break; + } + } else { + if (line[c] == '\'' && !in_double_quote) { + in_single_quote = !in_single_quote; + } else if (line[c] == '"' && !in_single_quote) { + in_double_quote = !in_double_quote; + } + } + + c++; + + if (cursor.column == c) { + break; + } + } + + // Disallow inserting duplicated quotes while already in string + if ((in_single_quote || in_double_quote) && (ch == '"' || ch == '\'')) { + insert_text_at_cursor(ch_single); + cursor_set_column(cursor_position_to_move); + + return; + } + insert_text_at_cursor(ch_pair); cursor_set_column(cursor_position_to_move); } @@ -2520,9 +2564,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { k = k->duplicate(); // It will be modified later on. #ifdef OSX_ENABLED - if (k->get_scancode() == KEY_META) { + if (k->get_keycode() == KEY_META) { #else - if (k->get_scancode() == KEY_CONTROL) { + if (k->get_keycode() == KEY_CONTROL) { #endif if (select_identifiers_enabled) { @@ -2553,7 +2597,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (valid) { if (!k->get_alt()) { - if (k->get_scancode() == KEY_UP) { + if (k->get_keycode() == KEY_UP) { if (completion_index > 0) { completion_index--; @@ -2567,7 +2611,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_DOWN) { + if (k->get_keycode() == KEY_DOWN) { if (completion_index < completion_options.size() - 1) { completion_index++; @@ -2581,7 +2625,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_PAGEUP) { + if (k->get_keycode() == KEY_PAGEUP) { completion_index -= get_constant("completion_lines"); if (completion_index < 0) @@ -2592,7 +2636,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_PAGEDOWN) { + if (k->get_keycode() == KEY_PAGEDOWN) { completion_index += get_constant("completion_lines"); if (completion_index >= completion_options.size()) @@ -2603,7 +2647,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_HOME && completion_index > 0) { + if (k->get_keycode() == KEY_HOME && completion_index > 0) { completion_index = 0; completion_current = completion_options[completion_index]; @@ -2612,7 +2656,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_END && completion_index < completion_options.size() - 1) { + if (k->get_keycode() == KEY_END && completion_index < completion_options.size() - 1) { completion_index = completion_options.size() - 1; completion_current = completion_options[completion_index]; @@ -2621,14 +2665,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_KP_ENTER || k->get_scancode() == KEY_ENTER || k->get_scancode() == KEY_TAB) { + if (k->get_keycode() == KEY_KP_ENTER || k->get_keycode() == KEY_ENTER || k->get_keycode() == KEY_TAB) { _confirm_completion(); accept_event(); return; } - if (k->get_scancode() == KEY_BACKSPACE) { + if (k->get_keycode() == KEY_BACKSPACE) { _reset_caret_blink_timer(); @@ -2638,7 +2682,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_SHIFT) { + if (k->get_keycode() == KEY_SHIFT) { accept_event(); return; } @@ -2682,20 +2726,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { /* TEST CONTROL FIRST! */ // Some remaps for duplicate functions. - if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) { + if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) { - k->set_scancode(KEY_C); + k->set_keycode(KEY_C); } - if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) { + if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) { - k->set_scancode(KEY_V); + k->set_keycode(KEY_V); k->set_command(true); k->set_shift(false); } #ifdef APPLE_STYLE_KEYS if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) { uint32_t remap_key = KEY_UNKNOWN; - switch (k->get_scancode()) { + switch (k->get_keycode()) { case KEY_F: { remap_key = KEY_RIGHT; } break; @@ -2717,7 +2761,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (remap_key != KEY_UNKNOWN) { - k->set_scancode(remap_key); + k->set_keycode(remap_key); k->set_control(false); } } @@ -2735,7 +2779,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { bool unselect = false; bool dobreak = false; - switch (k->get_scancode()) { + switch (k->get_keycode()) { case KEY_TAB: { if (k->get_shift()) { @@ -2809,11 +2853,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { selection.selecting_text = false; - bool scancode_handled = true; + bool keycode_handled = true; - // Special scancode test. + // Special keycode test. - switch (k->get_scancode()) { + switch (k->get_keycode()) { case KEY_KP_ENTER: case KEY_ENTER: { @@ -2935,7 +2979,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { completion_hint = ""; update(); } else { - scancode_handled = false; + keycode_handled = false; } } break; case KEY_TAB: { @@ -3008,7 +3052,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (k->get_alt() && cursor.column > 1) { #else if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } else if (k->get_command() && cursor.column > 1) { #endif @@ -3065,10 +3109,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_4: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_LEFT: { @@ -3101,7 +3145,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } else if (k->get_alt()) { #else if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } else if (k->get_command()) { #endif @@ -3141,10 +3185,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_6: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_RIGHT: { @@ -3163,7 +3207,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } else if (k->get_alt()) { #else if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } else if (k->get_command()) { #endif @@ -3202,15 +3246,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_8: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_UP: { if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } #ifndef APPLE_STYLE_KEYS @@ -3255,15 +3299,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_2: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_DOWN: { if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } #ifndef APPLE_STYLE_KEYS @@ -3323,7 +3367,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (k->get_alt() && cursor.column < curline_len - 1) { #else if (k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } else if (k->get_command() && cursor.column < curline_len - 1) { #endif @@ -3378,10 +3422,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_7: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_HOME: { #ifdef APPLE_STYLE_KEYS @@ -3439,10 +3483,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_1: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_END: { #ifdef APPLE_STYLE_KEYS @@ -3486,10 +3530,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_9: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_PAGEUP: { @@ -3509,10 +3553,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; case KEY_KP_3: { if (k->get_unicode() != 0) { - scancode_handled = false; + keycode_handled = false; break; } - FALLTHROUGH; + [[fallthrough]]; } case KEY_PAGEDOWN: { @@ -3534,7 +3578,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { #ifndef APPLE_STYLE_KEYS if (!k->get_control() || k->get_shift() || k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } if (is_shortcut_keys_enabled()) { @@ -3542,7 +3586,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } #else if ((!k->get_command() && !k->get_control())) { - scancode_handled = false; + keycode_handled = false; break; } if (!k->get_shift() && k->get_command() && is_shortcut_keys_enabled()) @@ -3573,7 +3617,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { case KEY_E: { if (!k->get_control() || k->get_command() || k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } @@ -3598,7 +3642,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { break; } if (!k->get_command() || k->get_shift() || k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } if (is_shortcut_keys_enabled()) { @@ -3609,7 +3653,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { case KEY_C: { if (!k->get_command() || k->get_shift() || k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } @@ -3625,7 +3669,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (!k->get_command()) { - scancode_handled = false; + keycode_handled = false; break; } @@ -3643,7 +3687,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (!k->get_command()) { - scancode_handled = false; + keycode_handled = false; break; } @@ -3656,7 +3700,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { break; } if (!k->get_command() || k->get_shift() || k->get_alt()) { - scancode_handled = false; + keycode_handled = false; break; } @@ -3673,9 +3717,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { #endif query_code_comple(); - scancode_handled = true; + keycode_handled = true; } else { - scancode_handled = false; + keycode_handled = false; } } break; @@ -3692,20 +3736,20 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { default: { - scancode_handled = false; + keycode_handled = false; } break; } - if (scancode_handled) + if (keycode_handled) accept_event(); - if (k->get_scancode() == KEY_INSERT) { + if (k->get_keycode() == KEY_INSERT) { set_insert_mode(!insert_mode); accept_event(); return; } - if (!scancode_handled && !k->get_command()) { // For German keyboards. + if (!keycode_handled && !k->get_command()) { // For German keyboards. if (k->get_unicode() >= 32) { @@ -5446,11 +5490,11 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc return col; } -PoolVector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const { +Vector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const { int col, line; if (search(p_key, p_search_flags, p_from_line, p_from_column, line, col)) { - PoolVector<int> result; + Vector<int> result; result.resize(2); result.set(SEARCH_RESULT_COLUMN, col); result.set(SEARCH_RESULT_LINE, line); @@ -5458,7 +5502,7 @@ PoolVector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_fl } else { - return PoolVector<int>(); + return Vector<int>(); } } @@ -5690,7 +5734,7 @@ void TextEdit::remove_breakpoints() { } } -void TextEdit::set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info) { +void TextEdit::set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) { ERR_FAIL_INDEX(p_line, text.size()); text.set_info_icon(p_line, p_icon, p_info); update(); @@ -6530,6 +6574,10 @@ void TextEdit::_update_completion_candidates() { Vector<float> sim_cache; bool single_quote = s.begins_with("'"); Vector<ScriptCodeCompletionOption> completion_options_casei; + Vector<ScriptCodeCompletionOption> completion_options_subseq; + Vector<ScriptCodeCompletionOption> completion_options_subseq_casei; + + String s_lower = s.to_lower(); for (List<ScriptCodeCompletionOption>::Element *E = completion_sources.front(); E; E = E->next()) { ScriptCodeCompletionOption &option = E->get(); @@ -6544,31 +6592,68 @@ void TextEdit::_update_completion_candidates() { option.insert_text = option.insert_text.quote(quote); } - if (option.display.begins_with(s)) { + if (option.display.length() == 0) { + continue; + } else if (s.length() == 0) { completion_options.push_back(option); - } else if (option.display.to_lower().begins_with(s.to_lower())) { - completion_options_casei.push_back(option); - } - } + } else { - completion_options.append_array(completion_options_casei); + // This code works the same as: + /* + if (option.display.begins_with(s)) { + completion_options.push_back(option); + } else if (option.display.to_lower().begins_with(s.to_lower())) { + completion_options_casei.push_back(option); + } else if (s.is_subsequence_of(option.display)) { + completion_options_subseq.push_back(option); + } else if (s.is_subsequence_ofi(option.display)) { + completion_options_subseq_casei.push_back(option); + } + */ + // But is more performant due to being inlined and looping over the characters only once - if (completion_options.size() == 0) { - for (int i = 0; i < completion_sources.size(); i++) { - if (s.is_subsequence_of(completion_sources[i].display)) { - completion_options.push_back(completion_sources[i]); + String display_lower = option.display.to_lower(); + + const CharType *ssq = &s[0]; + const CharType *ssq_lower = &s_lower[0]; + + const CharType *tgt = &option.display[0]; + const CharType *tgt_lower = &display_lower[0]; + + const CharType *ssq_last_tgt = NULL; + const CharType *ssq_lower_last_tgt = NULL; + + for (; *tgt; tgt++, tgt_lower++) { + if (*ssq == *tgt) { + ssq++; + ssq_last_tgt = tgt; + } + if (*ssq_lower == *tgt_lower) { + ssq_lower++; + ssq_lower_last_tgt = tgt; + } } - } - } - if (completion_options.size() == 0) { - for (int i = 0; i < completion_sources.size(); i++) { - if (s.is_subsequence_ofi(completion_sources[i].display)) { - completion_options.push_back(completion_sources[i]); + if (!*ssq) { // Matched the whole subsequence in s + if (ssq_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters + completion_options.push_back(option); + } else { + completion_options_subseq.push_back(option); + } + } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower + if (ssq_lower_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters + completion_options_casei.push_back(option); + } else { + completion_options_subseq_casei.push_back(option); + } } } } + completion_options.append_array(completion_options_casei); + completion_options.append_array(completion_options_subseq); + completion_options.append_array(completion_options_subseq_casei); + if (completion_options.size() == 0) { // No options to complete, cancel. _cancel_completion(); @@ -6757,13 +6842,18 @@ bool TextEdit::is_show_line_numbers_enabled() const { return line_numbers; } -void TextEdit::set_show_line_length_guideline(bool p_show) { - line_length_guideline = p_show; +void TextEdit::set_show_line_length_guidelines(bool p_show) { + line_length_guidelines = p_show; + update(); +} + +void TextEdit::set_line_length_guideline_soft_column(int p_column) { + line_length_guideline_soft_col = p_column; update(); } -void TextEdit::set_line_length_guideline_column(int p_column) { - line_length_guideline_col = p_column; +void TextEdit::set_line_length_guideline_hard_column(int p_column) { + line_length_guideline_hard_col = p_column; update(); } @@ -6954,13 +7044,8 @@ PopupMenu *TextEdit::get_menu() const { void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &TextEdit::_gui_input); - ClassDB::bind_method(D_METHOD("_scroll_moved"), &TextEdit::_scroll_moved); ClassDB::bind_method(D_METHOD("_cursor_changed_emit"), &TextEdit::_cursor_changed_emit); ClassDB::bind_method(D_METHOD("_text_changed_emit"), &TextEdit::_text_changed_emit); - ClassDB::bind_method(D_METHOD("_push_current_op"), &TextEdit::_push_current_op); - ClassDB::bind_method(D_METHOD("_click_selection_held"), &TextEdit::_click_selection_held); - ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &TextEdit::_toggle_draw_caret); - ClassDB::bind_method(D_METHOD("_v_scroll_input"), &TextEdit::_v_scroll_input); ClassDB::bind_method(D_METHOD("_update_wrap_at"), &TextEdit::_update_wrap_at); BIND_ENUM_CONSTANT(SEARCH_MATCH_CASE); @@ -7106,10 +7191,10 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "scroll_vertical"), "set_v_scroll", "get_v_scroll"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scroll_vertical"), "set_v_scroll", "get_v_scroll"); ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll"); ADD_GROUP("Minimap", "minimap_"); @@ -7119,7 +7204,7 @@ void TextEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_moving_by_right_click"), "set_right_click_moves_caret", "is_right_click_moving_caret"); ADD_SIGNAL(MethodInfo("cursor_changed")); @@ -7139,7 +7224,7 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_MAX); GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3); - ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::REAL, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers. + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::FLOAT, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers. } TextEdit::TextEdit() { @@ -7182,10 +7267,10 @@ TextEdit::TextEdit() { updating_scrolls = false; selection.active = false; - h_scroll->connect("value_changed", this, "_scroll_moved"); - v_scroll->connect("value_changed", this, "_scroll_moved"); + h_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); + v_scroll->connect("value_changed", callable_mp(this, &TextEdit::_scroll_moved)); - v_scroll->connect("scrolling", this, "_v_scroll_input"); + v_scroll->connect("scrolling", callable_mp(this, &TextEdit::_v_scroll_input)); cursor_changed_dirty = false; text_changed_dirty = false; @@ -7202,7 +7287,7 @@ TextEdit::TextEdit() { caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); caret_blink_timer->set_wait_time(0.65); - caret_blink_timer->connect("timeout", this, "_toggle_draw_caret"); + caret_blink_timer->connect("timeout", callable_mp(this, &TextEdit::_toggle_draw_caret)); cursor_set_blink_enabled(false); right_click_moves_caret = true; @@ -7210,12 +7295,12 @@ TextEdit::TextEdit() { add_child(idle_detect); idle_detect->set_one_shot(true); idle_detect->set_wait_time(GLOBAL_GET("gui/timers/text_edit_idle_detect_sec")); - idle_detect->connect("timeout", this, "_push_current_op"); + idle_detect->connect("timeout", callable_mp(this, &TextEdit::_push_current_op)); click_select_held = memnew(Timer); add_child(click_select_held); click_select_held->set_wait_time(0.05); - click_select_held->connect("timeout", this, "_click_selection_held"); + click_select_held->connect("timeout", callable_mp(this, &TextEdit::_click_selection_held)); current_op.type = TextOperation::TYPE_NONE; undo_enabled = true; @@ -7232,8 +7317,9 @@ TextEdit::TextEdit() { tooltip_obj = NULL; line_numbers = false; line_numbers_zero_padded = false; - line_length_guideline = false; - line_length_guideline_col = 80; + line_length_guidelines = false; + line_length_guideline_soft_col = 80; + line_length_guideline_hard_col = 100; draw_bookmark_gutter = false; draw_breakpoint_gutter = false; draw_fold_gutter = false; @@ -7273,7 +7359,7 @@ TextEdit::TextEdit() { add_child(menu); readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. set_readonly(false); - menu->connect("id_pressed", this, "menu_option"); + menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option)); first_draw = true; executing_line = -1; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index b4e7dcfebb..6e267f5a47 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -85,7 +85,7 @@ public: bool has_info : 1; int wrap_amount_cache : 24; Map<int, ColorRegionInfo> region_info; - Ref<Texture> info_icon; + Ref<Texture2D> info_icon; String info; String data; Line() { @@ -129,7 +129,7 @@ public: bool is_hidden(int p_line) const { return text[p_line].hidden; } void set_safe(int p_line, bool p_safe) { text.write[p_line].safe = p_safe; } bool is_safe(int p_line) const { return text[p_line].safe; } - void set_info_icon(int p_line, Ref<Texture> p_icon, String p_info) { + void set_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info) { if (p_icon.is_null()) { text.write[p_line].has_info = false; return; @@ -139,7 +139,7 @@ public: text.write[p_line].has_info = true; } bool has_info_icon(int p_line) const { return text[p_line].has_info; } - const Ref<Texture> &get_info_icon(int p_line) const { return text[p_line].info_icon; } + const Ref<Texture2D> &get_info_icon(int p_line) const { return text[p_line].info_icon; } const String &get_info(int p_line) const { return text[p_line].info; } void insert(int p_at, const String &p_text); void remove(int p_at); @@ -208,12 +208,12 @@ private: struct Cache { - Ref<Texture> tab_icon; - Ref<Texture> space_icon; - Ref<Texture> can_fold_icon; - Ref<Texture> folded_icon; - Ref<Texture> folded_eol_icon; - Ref<Texture> executing_icon; + Ref<Texture2D> tab_icon; + Ref<Texture2D> space_icon; + Ref<Texture2D> can_fold_icon; + Ref<Texture2D> folded_icon; + Ref<Texture2D> folded_eol_icon; + Ref<Texture2D> executing_icon; Ref<StyleBox> style_normal; Ref<StyleBox> style_focus; Ref<StyleBox> style_readonly; @@ -369,8 +369,9 @@ private: bool undo_enabled; bool line_numbers; bool line_numbers_zero_padded; - bool line_length_guideline; - int line_length_guideline_col; + bool line_length_guidelines; + int line_length_guideline_soft_col; + int line_length_guideline_hard_col; bool draw_bookmark_gutter; bool draw_breakpoint_gutter; int breakpoint_gutter_width; @@ -513,7 +514,7 @@ private: int _get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column); - PoolVector<int> _search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const; + Vector<int> _search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const; PopupMenu *menu; @@ -603,7 +604,7 @@ public: Array get_breakpoints_array() const; void remove_breakpoints(); - void set_line_info_icon(int p_line, Ref<Texture> p_icon, String p_info = ""); + void set_line_info_icon(int p_line, Ref<Texture2D> p_icon, String p_info = ""); void clear_info_icons(); void set_line_as_hidden(int p_line, bool p_hidden); @@ -765,8 +766,9 @@ public: void set_line_numbers_zero_padded(bool p_zero_padded); - void set_show_line_length_guideline(bool p_show); - void set_line_length_guideline_column(int p_column); + void set_show_line_length_guidelines(bool p_show); + void set_line_length_guideline_soft_column(int p_column); + void set_line_length_guideline_hard_column(int p_column); void set_bookmark_gutter_enabled(bool p_draw); bool is_bookmark_gutter_enabled() const; diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp index 9ffb69037a..5f2e4cf58e 100644 --- a/scene/gui/texture_button.cpp +++ b/scene/gui/texture_button.cpp @@ -122,7 +122,7 @@ void TextureButton::_notification(int p_what) { case NOTIFICATION_DRAW: { DrawMode draw_mode = get_draw_mode(); - Ref<Texture> texdraw; + Ref<Texture2D> texdraw; switch (draw_mode) { case DRAW_NORMAL: { @@ -252,11 +252,11 @@ void TextureButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureButton::get_stretch_mode); ADD_GROUP("Textures", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_hover_texture", "get_hover_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_disabled_texture", "get_disabled_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_focused_texture", "get_focused_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_texture", "get_normal_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_pressed_texture", "get_pressed_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_hover", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_hover_texture", "get_hover_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_disabled", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_disabled_texture", "get_disabled_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_focused", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_focused_texture", "get_focused_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_click_mask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_click_mask", "get_click_mask"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand", PROPERTY_HINT_RESOURCE_TYPE, "bool"), "set_expand", "get_expand"); ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); @@ -270,24 +270,24 @@ void TextureButton::_bind_methods() { BIND_ENUM_CONSTANT(STRETCH_KEEP_ASPECT_COVERED); } -void TextureButton::set_normal_texture(const Ref<Texture> &p_normal) { +void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) { normal = p_normal; update(); minimum_size_changed(); } -void TextureButton::set_pressed_texture(const Ref<Texture> &p_pressed) { +void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) { pressed = p_pressed; update(); } -void TextureButton::set_hover_texture(const Ref<Texture> &p_hover) { +void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) { hover = p_hover; update(); } -void TextureButton::set_disabled_texture(const Ref<Texture> &p_disabled) { +void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) { disabled = p_disabled; update(); @@ -298,19 +298,19 @@ void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) { update(); } -Ref<Texture> TextureButton::get_normal_texture() const { +Ref<Texture2D> TextureButton::get_normal_texture() const { return normal; } -Ref<Texture> TextureButton::get_pressed_texture() const { +Ref<Texture2D> TextureButton::get_pressed_texture() const { return pressed; } -Ref<Texture> TextureButton::get_hover_texture() const { +Ref<Texture2D> TextureButton::get_hover_texture() const { return hover; } -Ref<Texture> TextureButton::get_disabled_texture() const { +Ref<Texture2D> TextureButton::get_disabled_texture() const { return disabled; } @@ -319,12 +319,12 @@ Ref<BitMap> TextureButton::get_click_mask() const { return click_mask; } -Ref<Texture> TextureButton::get_focused_texture() const { +Ref<Texture2D> TextureButton::get_focused_texture() const { return focused; }; -void TextureButton::set_focused_texture(const Ref<Texture> &p_focused) { +void TextureButton::set_focused_texture(const Ref<Texture2D> &p_focused) { focused = p_focused; }; diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index e39b94abf0..43b10a8e8b 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -49,11 +49,11 @@ public: }; private: - Ref<Texture> normal; - Ref<Texture> pressed; - Ref<Texture> hover; - Ref<Texture> disabled; - Ref<Texture> focused; + Ref<Texture2D> normal; + Ref<Texture2D> pressed; + Ref<Texture2D> hover; + Ref<Texture2D> disabled; + Ref<Texture2D> focused; Ref<BitMap> click_mask; bool expand; StretchMode stretch_mode; @@ -69,18 +69,18 @@ protected: static void _bind_methods(); public: - void set_normal_texture(const Ref<Texture> &p_normal); - void set_pressed_texture(const Ref<Texture> &p_pressed); - void set_hover_texture(const Ref<Texture> &p_hover); - void set_disabled_texture(const Ref<Texture> &p_disabled); - void set_focused_texture(const Ref<Texture> &p_focused); + void set_normal_texture(const Ref<Texture2D> &p_normal); + void set_pressed_texture(const Ref<Texture2D> &p_pressed); + void set_hover_texture(const Ref<Texture2D> &p_hover); + void set_disabled_texture(const Ref<Texture2D> &p_disabled); + void set_focused_texture(const Ref<Texture2D> &p_focused); void set_click_mask(const Ref<BitMap> &p_click_mask); - Ref<Texture> get_normal_texture() const; - Ref<Texture> get_pressed_texture() const; - Ref<Texture> get_hover_texture() const; - Ref<Texture> get_disabled_texture() const; - Ref<Texture> get_focused_texture() const; + Ref<Texture2D> get_normal_texture() const; + Ref<Texture2D> get_pressed_texture() const; + Ref<Texture2D> get_hover_texture() const; + Ref<Texture2D> get_disabled_texture() const; + Ref<Texture2D> get_focused_texture() const; Ref<BitMap> get_click_mask() const; bool get_expand() const; diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp index 2d30ff7334..abf6b2ed49 100644 --- a/scene/gui/texture_progress.cpp +++ b/scene/gui/texture_progress.cpp @@ -32,19 +32,19 @@ #include "core/engine.h" -void TextureProgress::set_under_texture(const Ref<Texture> &p_texture) { +void TextureProgress::set_under_texture(const Ref<Texture2D> &p_texture) { under = p_texture; update(); minimum_size_changed(); } -Ref<Texture> TextureProgress::get_under_texture() const { +Ref<Texture2D> TextureProgress::get_under_texture() const { return under; } -void TextureProgress::set_over_texture(const Ref<Texture> &p_texture) { +void TextureProgress::set_over_texture(const Ref<Texture2D> &p_texture) { over = p_texture; update(); @@ -53,7 +53,7 @@ void TextureProgress::set_over_texture(const Ref<Texture> &p_texture) { } } -Ref<Texture> TextureProgress::get_over_texture() const { +Ref<Texture2D> TextureProgress::get_over_texture() const { return over; } @@ -94,14 +94,14 @@ Size2 TextureProgress::get_minimum_size() const { return Size2(1, 1); } -void TextureProgress::set_progress_texture(const Ref<Texture> &p_texture) { +void TextureProgress::set_progress_texture(const Ref<Texture2D> &p_texture) { progress = p_texture; update(); minimum_size_changed(); } -Ref<Texture> TextureProgress::get_progress_texture() const { +Ref<Texture2D> TextureProgress::get_progress_texture() const { return progress; } @@ -201,7 +201,7 @@ Point2 TextureProgress::get_relative_center() { return p; } -void TextureProgress::draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate) { +void TextureProgress::draw_nine_patch_stretched(const Ref<Texture2D> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate) { Vector2 texture_size = p_texture->get_size(); Vector2 topleft = Vector2(stretch_margin[MARGIN_LEFT], stretch_margin[MARGIN_TOP]); Vector2 bottomright = Vector2(stretch_margin[MARGIN_RIGHT], stretch_margin[MARGIN_BOTTOM]); @@ -501,17 +501,17 @@ void TextureProgress::_bind_methods() { ClassDB::bind_method(D_METHOD("get_nine_patch_stretch"), &TextureProgress::get_nine_patch_stretch); ADD_GROUP("Textures", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_under_texture", "get_under_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_over_texture", "get_over_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_progress_texture", "get_progress_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_under_texture", "get_under_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_over_texture", "get_over_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_progress_texture", "get_progress_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom), Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode"); ADD_GROUP("Tint", "tint_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under"), "set_tint_under", "get_tint_under"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_over"), "set_tint_over", "get_tint_over"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_progress"), "set_tint_progress", "get_tint_progress"); ADD_GROUP("Radial Fill", "radial_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "radial_center_offset"), "set_radial_center_offset", "get_radial_center_offset"); ADD_GROUP("Stretch", "stretch_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "nine_patch_stretch"), "set_nine_patch_stretch", "get_nine_patch_stretch"); diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h index e4a40fd6a3..e05f89aa3e 100644 --- a/scene/gui/texture_progress.h +++ b/scene/gui/texture_progress.h @@ -37,9 +37,9 @@ class TextureProgress : public Range { GDCLASS(TextureProgress, Range); - Ref<Texture> under; - Ref<Texture> progress; - Ref<Texture> over; + Ref<Texture2D> under; + Ref<Texture2D> progress; + Ref<Texture2D> over; protected: static void _bind_methods(); @@ -70,14 +70,14 @@ public: void set_radial_center_offset(const Point2 &p_off); Point2 get_radial_center_offset(); - void set_under_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_under_texture() const; + void set_under_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_under_texture() const; - void set_progress_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_progress_texture() const; + void set_progress_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_progress_texture() const; - void set_over_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_over_texture() const; + void set_over_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_over_texture() const; void set_stretch_margin(Margin p_margin, int p_size); int get_stretch_margin(Margin p_margin) const; @@ -109,7 +109,7 @@ private: Point2 unit_val_to_uv(float val); Point2 get_relative_center(); - void draw_nine_patch_stretched(const Ref<Texture> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate); + void draw_nine_patch_stretched(const Ref<Texture2D> &p_texture, FillMode p_mode, double p_ratio, const Color &p_modulate); }; VARIANT_ENUM_CAST(TextureProgress::FillMode); diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp index 514eff358e..6dafd3bf4f 100644 --- a/scene/gui/texture_rect.cpp +++ b/scene/gui/texture_rect.cpp @@ -127,9 +127,8 @@ void TextureRect::_bind_methods() { ClassDB::bind_method(D_METHOD("is_flipped_v"), &TextureRect::is_flipped_v); ClassDB::bind_method(D_METHOD("set_stretch_mode", "stretch_mode"), &TextureRect::set_stretch_mode); ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode); - ClassDB::bind_method(D_METHOD("_texture_changed"), &TextureRect::_texture_changed); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); @@ -153,27 +152,27 @@ void TextureRect::_texture_changed() { } } -void TextureRect::set_texture(const Ref<Texture> &p_tex) { +void TextureRect::set_texture(const Ref<Texture2D> &p_tex) { if (p_tex == texture) { return; } if (texture.is_valid()) { - texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureRect::_texture_changed)); } texture = p_tex; if (texture.is_valid()) { - texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &TextureRect::_texture_changed)); } update(); minimum_size_changed(); } -Ref<Texture> TextureRect::get_texture() const { +Ref<Texture2D> TextureRect::get_texture() const { return texture; } diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h index ef970fa051..77a2828fd4 100644 --- a/scene/gui/texture_rect.h +++ b/scene/gui/texture_rect.h @@ -53,7 +53,7 @@ private: bool expand; bool hflip; bool vflip; - Ref<Texture> texture; + Ref<Texture2D> texture; StretchMode stretch_mode; void _texture_changed(); @@ -64,8 +64,8 @@ protected: static void _bind_methods(); public: - void set_texture(const Ref<Texture> &p_tex); - Ref<Texture> get_texture() const; + void set_texture(const Ref<Texture2D> &p_tex); + Ref<Texture2D> get_texture() const; void set_expand(bool p_expand); bool has_expand() const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 964f376dbd..12b3d56938 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -129,7 +129,7 @@ void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) { c.step = 1; c.val = 0; c.checked = false; - c.icon = Ref<Texture>(); + c.icon = Ref<Texture2D>(); c.text = ""; c.icon_max_w = 0; _changed_notify(p_column); @@ -198,16 +198,16 @@ String TreeItem::get_suffix(int p_column) const { return cells[p_column].suffix; } -void TreeItem::set_icon(int p_column, const Ref<Texture> &p_icon) { +void TreeItem::set_icon(int p_column, const Ref<Texture2D> &p_icon) { ERR_FAIL_INDEX(p_column, cells.size()); cells.write[p_column].icon = p_icon; _changed_notify(p_column); } -Ref<Texture> TreeItem::get_icon(int p_column) const { +Ref<Texture2D> TreeItem::get_icon(int p_column) const { - ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>()); return cells[p_column].icon; } @@ -522,7 +522,7 @@ void TreeItem::deselect(int p_column) { _cell_deselected(p_column); } -void TreeItem::add_button(int p_column, const Ref<Texture> &p_button, int p_id, bool p_disabled, const String &p_tooltip) { +void TreeItem::add_button(int p_column, const Ref<Texture2D> &p_button, int p_id, bool p_disabled, const String &p_tooltip) { ERR_FAIL_INDEX(p_column, cells.size()); ERR_FAIL_COND(!p_button.is_valid()); @@ -542,9 +542,9 @@ int TreeItem::get_button_count(int p_column) const { ERR_FAIL_INDEX_V(p_column, cells.size(), -1); return cells[p_column].buttons.size(); } -Ref<Texture> TreeItem::get_button(int p_column, int p_idx) const { - ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture>()); - ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture>()); +Ref<Texture2D> TreeItem::get_button(int p_column, int p_idx) const { + ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>()); + ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture2D>()); return cells[p_column].buttons[p_idx].texture; } String TreeItem::get_button_tooltip(int p_column, int p_idx) const { @@ -577,7 +577,7 @@ int TreeItem::get_button_by_id(int p_column, int p_id) const { return -1; } -void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture> &p_button) { +void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button) { ERR_FAIL_COND(p_button.is_null()); ERR_FAIL_INDEX(p_column, cells.size()); @@ -729,18 +729,18 @@ bool TreeItem::is_folding_disabled() const { return disable_folding; } -Variant TreeItem::_call_recursive_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant TreeItem::_call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 0; return Variant(); } - if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + if (p_args[0]->get_type() != Variant::STRING && p_args[0]->get_type() != Variant::STRING_NAME) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; - r_error.expected = Variant::STRING; + r_error.expected = Variant::STRING_NAME; return Variant(); } @@ -750,7 +750,7 @@ Variant TreeItem::_call_recursive_bind(const Variant **p_args, int p_argcount, V return Variant(); } -void recursive_call_aux(TreeItem *p_item, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +void recursive_call_aux(TreeItem *p_item, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (!p_item) { return; } @@ -762,7 +762,7 @@ void recursive_call_aux(TreeItem *p_item, const StringName &p_method, const Vari } } -void TreeItem::call_recursive(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +void TreeItem::call_recursive(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { recursive_call_aux(this, p_method, p_args, p_argcount, r_error); } @@ -861,7 +861,7 @@ void TreeItem::_bind_methods() { { MethodInfo mi; mi.name = "call_recursive"; - mi.arguments.push_back(PropertyInfo(Variant::STRING, "method")); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_recursive", &TreeItem::_call_recursive_bind, mi); } @@ -1020,13 +1020,13 @@ int Tree::compute_item_height(TreeItem *p_item) const { int check_icon_h = cache.checked->get_height(); if (height < check_icon_h) height = check_icon_h; - FALLTHROUGH; + [[fallthrough]]; } case TreeItem::CELL_MODE_STRING: case TreeItem::CELL_MODE_CUSTOM: case TreeItem::CELL_MODE_ICON: { - Ref<Texture> icon = p_item->cells[i].icon; + Ref<Texture2D> icon = p_item->cells[i].icon; if (!icon.is_null()) { Size2i s = p_item->cells[i].get_icon_size(); @@ -1121,7 +1121,7 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co } rect.position.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent(); - font->draw(ci, rect.position, text, p_color, rect.size.x); + font->draw(ci, rect.position, text, p_color, MAX(0, rect.size.width)); } int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item) { @@ -1190,7 +1190,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int bw = 0; for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { - Ref<Texture> b = p_item->cells[i].buttons[j].texture; + Ref<Texture2D> b = p_item->cells[i].buttons[j].texture; Size2 s = b->get_size() + cache.button_pressed->get_minimum_size(); if (s.height < label_h) s.height = label_h; @@ -1305,8 +1305,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } break; case TreeItem::CELL_MODE_CHECK: { - Ref<Texture> checked = cache.checked; - Ref<Texture> unchecked = cache.unchecked; + Ref<Texture2D> checked = cache.checked; + Ref<Texture2D> unchecked = cache.unchecked; Point2i check_ofs = item_rect.position; check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2); @@ -1350,7 +1350,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].suffix != String()) s += " " + p_item->cells[i].suffix; - Ref<Texture> downarrow = cache.select_arrow; + Ref<Texture2D> downarrow = cache.select_arrow; font->draw(ci, text_pos, s, col, item_rect.size.x - downarrow->get_width()); @@ -1361,7 +1361,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 downarrow->draw(ci, arrow_pos); } else { - Ref<Texture> updown = cache.updown; + Ref<Texture2D> updown = cache.updown; String valtext = String::num(p_item->cells[i].val, Math::range_step_decimals(p_item->cells[i].step)); @@ -1399,7 +1399,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } break; case TreeItem::CELL_MODE_CUSTOM: { - if (p_item->cells[i].custom_draw_obj) { + if (p_item->cells[i].custom_draw_obj.is_valid()) { Object *cdo = ObjectDB::get_instance(p_item->cells[i].custom_draw_obj); if (cdo) @@ -1412,7 +1412,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 break; } - Ref<Texture> downarrow = cache.select_arrow; + Ref<Texture2D> downarrow = cache.select_arrow; Rect2i ir = item_rect; @@ -1462,7 +1462,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (!p_item->disable_folding && !hide_folding && p_item->children) { //has children, draw the guide box - Ref<Texture> arrow; + Ref<Texture2D> arrow; if (p_item->collapsed) { @@ -1775,7 +1775,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool bool already_cursor = (p_item == selected_item) && col == selected_col; for (int j = c.buttons.size() - 1; j >= 0; j--) { - Ref<Texture> b = c.buttons[j].texture; + Ref<Texture2D> b = c.buttons[j].texture; int w = b->get_size().width + cache.button_pressed->get_minimum_size().width; if (x > col_width - w) { @@ -2439,7 +2439,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { return; } else { - if (k->get_scancode() != KEY_SHIFT) + if (k->get_keycode() != KEY_SHIFT) last_keypress = 0; } } @@ -3630,6 +3630,17 @@ TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_select return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable); } +TreeItem *Tree::get_item_with_text(const String &p_find) const { + for (TreeItem *current = root; current; current = current->get_next_visible()) { + for (int i = 0; i < columns.size(); i++) { + if (current->get_text(i) == p_find) { + return current; + } + } + } + return NULL; +} + void Tree::_do_incr_search(const String &p_add) { uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec @@ -3814,7 +3825,7 @@ String Tree::get_tooltip(const Point2 &p_pos) const { pos.x -= get_column_width(i); for (int j = c.buttons.size() - 1; j >= 0; j--) { - Ref<Texture> b = c.buttons[j].texture; + Ref<Texture2D> b = c.buttons[j].texture; Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); if (pos.x > col_width - size.width) { String tooltip = c.buttons[j].tooltip; @@ -3903,13 +3914,7 @@ bool Tree::get_allow_reselect() const { void Tree::_bind_methods() { - ClassDB::bind_method(D_METHOD("_range_click_timeout"), &Tree::_range_click_timeout); ClassDB::bind_method(D_METHOD("_gui_input"), &Tree::_gui_input); - ClassDB::bind_method(D_METHOD("_popup_select"), &Tree::popup_select); - ClassDB::bind_method(D_METHOD("_text_editor_enter"), &Tree::text_editor_enter); - ClassDB::bind_method(D_METHOD("_text_editor_modal_close"), &Tree::_text_editor_modal_close); - ClassDB::bind_method(D_METHOD("_value_editor_changed"), &Tree::value_editor_changed); - ClassDB::bind_method(D_METHOD("_scroll_moved"), &Tree::_scroll_moved); ClassDB::bind_method(D_METHOD("clear"), &Tree::clear); ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::_create_item, DEFVAL(Variant()), DEFVAL(-1)); @@ -4032,15 +4037,15 @@ Tree::Tree() { add_child(v_scroll); range_click_timer = memnew(Timer); - range_click_timer->connect("timeout", this, "_range_click_timeout"); + range_click_timer->connect("timeout", callable_mp(this, &Tree::_range_click_timeout)); add_child(range_click_timer); - h_scroll->connect("value_changed", this, "_scroll_moved"); - v_scroll->connect("value_changed", this, "_scroll_moved"); - text_editor->connect("text_entered", this, "_text_editor_enter"); - text_editor->connect("modal_closed", this, "_text_editor_modal_close"); - popup_menu->connect("id_pressed", this, "_popup_select"); - value_editor->connect("value_changed", this, "_value_editor_changed"); + h_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved)); + v_scroll->connect("value_changed", callable_mp(this, &Tree::_scroll_moved)); + text_editor->connect("text_entered", callable_mp(this, &Tree::text_editor_enter)); + text_editor->connect("modal_closed", callable_mp(this, &Tree::_text_editor_modal_close)); + popup_menu->connect("id_pressed", callable_mp(this, &Tree::popup_select)); + value_editor->connect("value_changed", callable_mp(this, &Tree::value_editor_changed)); value_editor->set_as_toplevel(true); text_editor->set_as_toplevel(true); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index d87de6e773..b179c5bcba 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -66,7 +66,7 @@ private: TreeCellMode mode; - Ref<Texture> icon; + Ref<Texture2D> icon; Rect2i icon_region; String text; String suffix; @@ -97,7 +97,7 @@ private: struct Button { int id; bool disabled; - Ref<Texture> texture; + Ref<Texture2D> texture; Color color; String tooltip; Button() { @@ -112,7 +112,7 @@ private: Cell() { - custom_draw_obj = 0; + custom_draw_obj = ObjectID(); custom_button = false; mode = TreeItem::CELL_MODE_STRING; min = 0; @@ -172,7 +172,7 @@ protected: remove_child(Object::cast_to<TreeItem>(p_child)); } - Variant _call_recursive_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant _call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); public: /* cell mode */ @@ -189,8 +189,8 @@ public: void set_suffix(int p_column, String p_suffix); String get_suffix(int p_column) const; - void set_icon(int p_column, const Ref<Texture> &p_icon); - Ref<Texture> get_icon(int p_column) const; + void set_icon(int p_column, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_icon(int p_column) const; void set_icon_region(int p_column, const Rect2 &p_icon_region); Rect2 get_icon_region(int p_column) const; @@ -201,14 +201,14 @@ public: void set_icon_max_width(int p_column, int p_max); int get_icon_max_width(int p_column) const; - void add_button(int p_column, const Ref<Texture> &p_button, int p_id = -1, bool p_disabled = false, const String &p_tooltip = ""); + void add_button(int p_column, const Ref<Texture2D> &p_button, int p_id = -1, bool p_disabled = false, const String &p_tooltip = ""); int get_button_count(int p_column) const; String get_button_tooltip(int p_column, int p_idx) const; - Ref<Texture> get_button(int p_column, int p_idx) const; + Ref<Texture2D> get_button(int p_column, int p_idx) const; int get_button_id(int p_column, int p_idx) const; void erase_button(int p_column, int p_idx); int get_button_by_id(int p_column, int p_id) const; - void set_button(int p_column, int p_idx, const Ref<Texture> &p_button); + void set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button); void set_button_color(int p_column, int p_idx, const Color &p_color); void set_button_disabled(int p_column, int p_idx, bool p_disabled); bool is_button_disabled(int p_column, int p_idx) const; @@ -282,7 +282,7 @@ public: void set_disable_folding(bool p_disable); bool is_folding_disabled() const; - void call_recursive(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + void call_recursive(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); ~TreeItem(); }; @@ -374,7 +374,7 @@ private: int compute_item_height(TreeItem *p_item) const; int get_item_height(TreeItem *p_item) const; - //void draw_item_text(String p_text,const Ref<Texture>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color); + //void draw_item_text(String p_text,const Ref<Texture2D>& p_icon,int p_icon_max_w,bool p_tool,Rect2i p_rect,const Color& p_color); void draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color); int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item); void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = NULL, bool *r_in_range = NULL, bool p_force_deselect = false); @@ -416,12 +416,12 @@ private: Color title_button_color; - Ref<Texture> checked; - Ref<Texture> unchecked; - Ref<Texture> arrow_collapsed; - Ref<Texture> arrow; - Ref<Texture> select_arrow; - Ref<Texture> updown; + Ref<Texture2D> checked; + Ref<Texture2D> unchecked; + Ref<Texture2D> arrow_collapsed; + Ref<Texture2D> arrow; + Ref<Texture2D> select_arrow; + Ref<Texture2D> updown; Color font_color; Color font_color_selected; @@ -577,7 +577,10 @@ public: Rect2 get_item_rect(TreeItem *p_item, int p_column = -1) const; bool edit_selected(); + // First item that starts with the text, from the current focused item down and wraps around. TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false); + // First item that matches the whole text, from the first item down. + TreeItem *get_item_with_text(const String &p_find) const; Point2 get_scroll() const; void scroll_to_item(TreeItem *p_item); diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 0a693d4023..ac1e4a5629 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -375,12 +375,12 @@ void VideoPlayer::set_stream_position(float p_position) { playback->seek(p_position); } -Ref<Texture> VideoPlayer::get_video_texture() const { +Ref<Texture2D> VideoPlayer::get_video_texture() const { if (playback.is_valid()) return playback->get_texture(); - return Ref<Texture>(); + return Ref<Texture2D>(); } void VideoPlayer::set_autoplay(bool p_enable) { @@ -473,15 +473,15 @@ void VideoPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_track", PROPERTY_HINT_RANGE, "0,128,1"), "set_audio_track", "get_audio_track"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "VideoStream"), "set_stream", "get_stream"); //ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), "set_loop", "has_loop") ; - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume", PROPERTY_HINT_EXP_RANGE, "0,15,0.01", 0), "set_volume", "get_volume"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume", PROPERTY_HINT_EXP_RANGE, "0,15,0.01", 0), "set_volume", "get_volume"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "has_autoplay"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_paused", "is_paused"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); ADD_PROPERTY(PropertyInfo(Variant::INT, "buffering_msec", PROPERTY_HINT_RANGE, "10,1000"), "set_buffering_msec", "get_buffering_msec"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "stream_position", PROPERTY_HINT_RANGE, "0,1280000,0.1", 0), "set_stream_position", "get_stream_position"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stream_position", PROPERTY_HINT_RANGE, "0,1280000,0.1", 0), "set_stream_position", "get_stream_position"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } VideoPlayer::VideoPlayer() { diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h index e740e3e4ed..78e7fa05f8 100644 --- a/scene/gui/video_player.h +++ b/scene/gui/video_player.h @@ -86,7 +86,7 @@ public: void set_expand(bool p_expand); bool has_expand() const; - Ref<Texture> get_video_texture() const; + Ref<Texture2D> get_video_texture() const; void set_stream(const Ref<VideoStream> &p_stream); Ref<VideoStream> get_stream() const; diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp index 4565b4b538..a76f2924d3 100644 --- a/scene/gui/viewport_container.cpp +++ b/scene/gui/viewport_container.cpp @@ -135,9 +135,9 @@ void ViewportContainer::_notification(int p_what) { continue; if (stretch) - draw_texture_rect(c->get_texture(), Rect2(Vector2(), get_size() * Size2(1, -1))); + draw_texture_rect(c->get_texture(), Rect2(Vector2(), get_size())); else - draw_texture_rect(c->get_texture(), Rect2(Vector2(), c->get_size() * Size2(1, -1))); + draw_texture_rect(c->get_texture(), Rect2(Vector2(), c->get_size())); } } } diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 4ae018a79a..2085fa3a60 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -200,7 +200,7 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) { if (custom_viewport) { custom_viewport_id = custom_viewport->get_instance_id(); } else { - custom_viewport_id = 0; + custom_viewport_id = ObjectID(); } if (is_inside_tree()) { @@ -307,15 +307,15 @@ void CanvasLayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer"); ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform"); ADD_GROUP("", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport"); ADD_GROUP("Follow Viewport", "follow_viewport"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enable"), "set_follow_viewport", "is_following_viewport"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale"); } CanvasLayer::CanvasLayer() { @@ -327,7 +327,7 @@ CanvasLayer::CanvasLayer() { layer = 1; canvas = VS::get_singleton()->canvas_create(); custom_viewport = NULL; - custom_viewport_id = 0; + sort_index = 0; follow_viewport = false; follow_viewport_scale = 1.0; diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 3c89069816..fee2ada76d 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -118,7 +118,7 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h client->set_blocking_mode(false); err = _request(); if (err != OK) { - call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray()); return ERR_CANT_CONNECT; } @@ -135,7 +135,7 @@ void HTTPRequest::_thread_func(void *p_userdata) { Error err = hr->_request(); if (err != OK) { - hr->call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); + hr->call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray()); } else { while (!hr->thread_request_quit) { @@ -180,7 +180,7 @@ void HTTPRequest::cancel_request() { bool HTTPRequest::_handle_response(bool *ret_value) { if (!client->has_response()) { - call_deferred("_request_done", RESULT_NO_RESPONSE, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_NO_RESPONSE, 0, PackedStringArray(), PackedByteArray()); *ret_value = true; return true; } @@ -200,7 +200,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) { if (max_redirects >= 0 && redirections >= max_redirects) { - call_deferred("_request_done", RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray()); *ret_value = true; return true; } @@ -246,7 +246,7 @@ bool HTTPRequest::_update_connection() { switch (client->get_status()) { case HTTPClient::STATUS_DISCONNECTED: { - call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray()); return true; // End it, since it's doing something } break; case HTTPClient::STATUS_RESOLVING: { @@ -255,7 +255,7 @@ bool HTTPRequest::_update_connection() { return false; } break; case HTTPClient::STATUS_CANT_RESOLVE: { - call_deferred("_request_done", RESULT_CANT_RESOLVE, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CANT_RESOLVE, 0, PackedStringArray(), PackedByteArray()); return true; } break; @@ -266,7 +266,7 @@ bool HTTPRequest::_update_connection() { } break; // Connecting to IP case HTTPClient::STATUS_CANT_CONNECT: { - call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray()); return true; } break; @@ -283,7 +283,7 @@ bool HTTPRequest::_update_connection() { if (_handle_response(&ret_value)) return ret_value; - call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PackedByteArray()); return true; } if (body_len < 0) { @@ -292,7 +292,7 @@ bool HTTPRequest::_update_connection() { return true; } - call_deferred("_request_done", RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PackedByteArray()); return true; // Request migh have been done } else { @@ -300,7 +300,7 @@ bool HTTPRequest::_update_connection() { Error err = client->request(method, request_string, headers, request_data); if (err != OK) { - call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; } @@ -325,7 +325,7 @@ bool HTTPRequest::_update_connection() { if (!client->is_response_chunked() && client->get_response_body_length() == 0) { - call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PackedByteArray()); return true; } @@ -334,7 +334,7 @@ bool HTTPRequest::_update_connection() { body_len = client->get_response_body_length(); if (body_size_limit >= 0 && body_len > body_size_limit) { - call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray()); return true; } @@ -342,7 +342,7 @@ bool HTTPRequest::_update_connection() { file = FileAccess::open(download_to_file, FileAccess::WRITE); if (!file) { - call_deferred("_request_done", RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray()); return true; } } @@ -350,14 +350,14 @@ bool HTTPRequest::_update_connection() { client->poll(); - PoolByteArray chunk = client->read_response_body_chunk(); + PackedByteArray chunk = client->read_response_body_chunk(); downloaded += chunk.size(); if (file) { - PoolByteArray::Read r = chunk.read(); - file->store_buffer(r.ptr(), chunk.size()); + const uint8_t *r = chunk.ptr(); + file->store_buffer(r, chunk.size()); if (file->get_error() != OK) { - call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_DOWNLOAD_FILE_WRITE_ERROR, response_code, response_headers, PackedByteArray()); return true; } } else { @@ -365,7 +365,7 @@ bool HTTPRequest::_update_connection() { } if (body_size_limit >= 0 && downloaded > body_size_limit) { - call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PoolByteArray()); + call_deferred("_request_done", RESULT_BODY_SIZE_LIMIT_EXCEEDED, response_code, response_headers, PackedByteArray()); return true; } @@ -384,11 +384,11 @@ bool HTTPRequest::_update_connection() { } break; // Request resulted in body: break which must be read case HTTPClient::STATUS_CONNECTION_ERROR: { - call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; } break; case HTTPClient::STATUS_SSL_HANDSHAKE_ERROR: { - call_deferred("_request_done", RESULT_SSL_HANDSHAKE_ERROR, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_SSL_HANDSHAKE_ERROR, 0, PackedStringArray(), PackedByteArray()); return true; } break; } @@ -396,7 +396,7 @@ bool HTTPRequest::_update_connection() { ERR_FAIL_V(false); } -void HTTPRequest::_request_done(int p_status, int p_code, const PoolStringArray &headers, const PoolByteArray &p_data) { +void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) { cancel_request(); emit_signal("request_completed", p_status, p_code, headers, p_data); @@ -505,12 +505,12 @@ int HTTPRequest::get_timeout() { void HTTPRequest::_timeout() { cancel_request(); - call_deferred("_request_done", RESULT_TIMEOUT, 0, PoolStringArray(), PoolByteArray()); + call_deferred("_request_done", RESULT_TIMEOUT, 0, PackedStringArray(), PackedByteArray()); } void HTTPRequest::_bind_methods() { - ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PoolStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); ClassDB::bind_method(D_METHOD("cancel_request"), &HTTPRequest::cancel_request); ClassDB::bind_method(D_METHOD("get_http_client_status"), &HTTPRequest::get_http_client_status); @@ -539,8 +539,6 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("set_download_chunk_size"), &HTTPRequest::set_download_chunk_size); ClassDB::bind_method(D_METHOD("get_download_chunk_size"), &HTTPRequest::get_download_chunk_size); - ClassDB::bind_method(D_METHOD("_timeout"), &HTTPRequest::_timeout); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::INT, "download_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_download_chunk_size", "get_download_chunk_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); @@ -548,7 +546,7 @@ void HTTPRequest::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); ADD_PROPERTY(PropertyInfo(Variant::INT, "timeout", PROPERTY_HINT_RANGE, "0,86400"), "set_timeout", "get_timeout"); - ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::POOL_STRING_ARRAY, "headers"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "body"))); + ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "headers"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "body"))); BIND_ENUM_CONSTANT(RESULT_SUCCESS); //BIND_ENUM_CONSTANT( RESULT_NO_BODY ); @@ -589,7 +587,7 @@ HTTPRequest::HTTPRequest() { timer = memnew(Timer); timer->set_one_shot(true); - timer->connect("timeout", this, "_timeout"); + timer->connect("timeout", callable_mp(this, &HTTPRequest::_timeout)); add_child(timer); timeout = 0; } diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 94b323ae8a..a3d95cd652 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -73,12 +73,12 @@ private: bool request_sent; Ref<HTTPClient> client; - PoolByteArray body; + PackedByteArray body; volatile bool use_threads; bool got_response; int response_code; - PoolVector<String> response_headers; + Vector<String> response_headers; String download_to_file; @@ -108,7 +108,7 @@ private: Thread *thread; - void _request_done(int p_status, int p_code, const PoolStringArray &headers, const PoolByteArray &p_data); + void _request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data); static void _thread_func(void *p_userdata); protected: diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index 0128d1a218..fe238af1c4 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -112,15 +112,10 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene return scene; } -void InstancePlaceholder::replace_by_instance(const Ref<PackedScene> &p_custom_scene) { - //Deprecated by - create_instance(true, p_custom_scene); -} - Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) { Dictionary ret; - PoolStringArray order; + PackedStringArray order; for (List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) { ret[E->get().name] = E->get().value; @@ -138,7 +133,6 @@ void InstancePlaceholder::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stored_values", "with_order"), &InstancePlaceholder::get_stored_values, DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_instance", "replace", "custom_scene"), &InstancePlaceholder::create_instance, DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("replace_by_instance", "custom_scene"), &InstancePlaceholder::replace_by_instance, DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("get_instance_path"), &InstancePlaceholder::get_instance_path); } diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index d570b8c247..9f7b84716d 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -61,7 +61,6 @@ public: Dictionary get_stored_values(bool p_with_order = false); Node *create_instance(bool p_replace = false, const Ref<PackedScene> &p_custom_scene = Ref<PackedScene>()); - void replace_by_instance(const Ref<PackedScene> &p_custom_scene = Ref<PackedScene>()); InstancePlaceholder(); }; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 761fe3f90f..973dff07d2 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -35,6 +35,7 @@ #include "core/message_queue.h" #include "core/print_string.h" #include "instance_placeholder.h" +#include "scene/debugger/scene_debugger.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" #include "viewport.h" @@ -43,6 +44,8 @@ #include "editor/editor_settings.h" #endif +#include <stdint.h> + VARIANT_ENUM_CAST(Node::PauseMode); int Node::orphan_node_count = 0; @@ -242,11 +245,7 @@ void Node::_propagate_enter_tree() { data.blocked--; #ifdef DEBUG_ENABLED - - if (ScriptDebugger::get_singleton() && data.filename != String()) { - //used for live edit - data.tree->live_scene_edit_cache[data.filename].insert(this); - } + SceneDebugger::add_to_cache(data.filename, this); #endif // enter groups } @@ -266,26 +265,7 @@ void Node::_propagate_exit_tree() { //block while removing children #ifdef DEBUG_ENABLED - - if (ScriptDebugger::get_singleton() && data.filename != String()) { - //used for live edit - Map<String, Set<Node *> >::Element *E = data.tree->live_scene_edit_cache.find(data.filename); - if (E) { - E->get().erase(this); - if (E->get().size() == 0) { - data.tree->live_scene_edit_cache.erase(E); - } - } - - Map<Node *, Map<ObjectID, Node *> >::Element *F = data.tree->live_edit_remove_list.find(this); - if (F) { - for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) { - - memdelete(G->get()); - } - data.tree->live_edit_remove_list.erase(F); - } - } + SceneDebugger::remove_from_cache(data.filename, this); #endif data.blocked++; @@ -498,22 +478,38 @@ bool Node::is_network_master() const { /***** RPC CONFIG ********/ -void Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { +uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) { - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { - data.rpc_methods.erase(p_method); + uint16_t mid = get_node_rpc_method_id(p_method); + if (mid == UINT16_MAX) { + // It's new + NetData nd; + nd.name = p_method; + nd.mode = p_mode; + data.rpc_methods.push_back(nd); + return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); } else { - data.rpc_methods[p_method] = p_mode; - }; + int c_mid = (~(1 << 15)) & mid; + data.rpc_methods.write[c_mid].mode = p_mode; + return mid; + } } -void Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { +uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) { - if (p_mode == MultiplayerAPI::RPC_MODE_DISABLED) { - data.rpc_properties.erase(p_property); + uint16_t pid = get_node_rset_property_id(p_property); + if (pid == UINT16_MAX) { + // It's new + NetData nd; + nd.name = p_property; + nd.mode = p_mode; + data.rpc_properties.push_back(nd); + return ((uint16_t)data.rpc_properties.size() - 1) | (1 << 15); } else { - data.rpc_properties[p_property] = p_mode; - }; + int c_pid = (~(1 << 15)) & pid; + data.rpc_properties.write[c_pid].mode = p_mode; + return pid; + } } /***** RPC FUNCTIONS ********/ @@ -574,16 +570,16 @@ void Node::rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ rpcp(p_peer_id, true, p_method, argptr, argc); } -Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; return Variant(); @@ -593,27 +589,27 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Variant::CallErr rpcp(0, false, method, &p_args[1], p_argcount - 1); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; return Variant(); } if (p_args[0]->get_type() != Variant::INT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; return Variant(); } if (p_args[1]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; return Variant(); @@ -624,20 +620,20 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Variant::Call rpcp(peer_id, false, method, &p_args[2], p_argcount - 2); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; return Variant(); @@ -647,27 +643,27 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Varia rpcp(0, true, method, &p_args[1], p_argcount - 1); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } -Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; return Variant(); } if (p_args[0]->get_type() != Variant::INT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; return Variant(); } if (p_args[1]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; return Variant(); @@ -678,7 +674,7 @@ Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Va rpcp(peer_id, true, method, &p_args[2], p_argcount - 2); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; return Variant(); } @@ -731,12 +727,94 @@ void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { multiplayer = p_multiplayer; } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rpc_mode(const StringName &p_method) { - return data.rpc_methods.find(p_method); +uint16_t Node::get_node_rpc_method_id(const StringName &p_method) const { + for (int i = 0; i < data.rpc_methods.size(); i++) { + if (data.rpc_methods[i].name == p_method) { + // Returns `i` with the high bit set to 1 so we know that this id comes + // from the node and not the script. + return i | (1 << 15); + } + } + return UINT16_MAX; +} + +StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rpc_method_id) > 0) { + int mid = (~(1 << 15)) & p_rpc_method_id; + if (mid < data.rpc_methods.size()) + return data.rpc_methods[mid].name; + } + return StringName(); +} + +MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rpc_method_id) > 0) { + int mid = (~(1 << 15)) & p_rpc_method_id; + if (mid < data.rpc_methods.size()) + return data.rpc_methods[mid].mode; + } + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode Node::get_node_rpc_mode(const StringName &p_method) const { + return get_node_rpc_mode_by_id(get_node_rpc_method_id(p_method)); +} + +uint16_t Node::get_node_rset_property_id(const StringName &p_property) const { + for (int i = 0; i < data.rpc_properties.size(); i++) { + if (data.rpc_properties[i].name == p_property) { + // Returns `i` with the high bit set to 1 so we know that this id comes + // from the node and not the script. + return i | (1 << 15); + } + } + return UINT16_MAX; +} + +StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const { + // Make sure this is a node generated ID. + if (((1 << 15) & p_rset_property_id) > 0) { + int mid = (~(1 << 15)) & p_rset_property_id; + if (mid < data.rpc_properties.size()) + return data.rpc_properties[mid].name; + } + return StringName(); +} + +MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const { + if (((1 << 15) & p_rset_property_id) > 0) { + int mid = (~(1 << 15)) & p_rset_property_id; + if (mid < data.rpc_properties.size()) + return data.rpc_properties[mid].mode; + } + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode Node::get_node_rset_mode(const StringName &p_property) const { + return get_node_rset_mode_by_id(get_node_rset_property_id(p_property)); } -const Map<StringName, MultiplayerAPI::RPCMode>::Element *Node::get_node_rset_mode(const StringName &p_property) { - return data.rpc_properties.find(p_property); +String Node::get_rpc_md5() const { + String rpc_list; + for (int i = 0; i < data.rpc_methods.size(); i += 1) { + rpc_list += String(data.rpc_methods[i].name); + } + for (int i = 0; i < data.rpc_properties.size(); i += 1) { + rpc_list += String(data.rpc_properties[i].name); + } + if (get_script_instance()) { + Vector<ScriptNetData> rpc = get_script_instance()->get_rpc_methods(); + for (int i = 0; i < rpc.size(); i += 1) { + rpc_list += String(rpc[i].name); + } + rpc = get_script_instance()->get_rset_properties(); + for (int i = 0; i < rpc.size(); i += 1) { + rpc_list += String(rpc[i].name); + } + } + return rpc_list.md5_text(); } bool Node::can_process_notification(int p_what) const { @@ -2260,7 +2338,7 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { NodePath p = p_original->get_path_to(this); Node *copy = p_copy->get_node(p); - Node *target = Object::cast_to<Node>(E->get().target); + Node *target = Object::cast_to<Node>(E->get().callable.get_object()); if (!target) { continue; } @@ -2268,15 +2346,18 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { Node *copytarget = target; - // Atempt to find a path to the duplicate target, if it seems it's not part + // Attempt to find a path to the duplicate target, if it seems it's not part // of the duplicated and not yet parented hierarchy then at least try to connect // to the same target as the original if (p_copy->has_node(ptarget)) copytarget = p_copy->get_node(ptarget); - if (copy && copytarget && !copy->is_connected(E->get().signal, copytarget, E->get().method)) { - copy->connect(E->get().signal, copytarget, E->get().method, E->get().binds, E->get().flags); + if (copy && copytarget) { + const Callable copy_callable = Callable(copytarget, E->get().callable.get_method()); + if (!copy->is_connected(E->get().signal.get_name(), copy_callable)) { + copy->connect(E->get().signal.get_name(), copy_callable, E->get().binds, E->get().flags); + } } } } @@ -2431,10 +2512,10 @@ void Node::_replace_connections_target(Node *p_new_target) { Connection &c = E->get(); if (c.flags & CONNECT_PERSIST) { - c.source->disconnect(c.signal, this, c.method); - bool valid = p_new_target->has_method(c.method) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.method); - ERR_CONTINUE_MSG(!valid, "Attempt to connect signal '" + c.source->get_class() + "." + c.signal + "' to nonexistent method '" + c.target->get_class() + "." + c.method + "'."); - c.source->connect(c.signal, p_new_target, c.method, c.binds, c.flags); + c.signal.get_object()->disconnect(c.signal.get_name(), Callable(this, c.callable.get_method())); + bool valid = p_new_target->has_method(c.callable.get_method()) || Ref<Script>(p_new_target->get_script()).is_null() || Ref<Script>(p_new_target->get_script())->has_method(c.callable.get_method()); + ERR_CONTINUE_MSG(!valid, "Attempt to connect signal '" + c.signal.get_object()->get_class() + "." + c.signal.get_name() + "' to nonexistent method '" + c.callable.get_object()->get_class() + "." + c.callable.get_method() + "'."); + c.signal.get_object()->connect(c.signal.get_name(), Callable(p_new_target, c.callable.get_method()), c.binds, c.flags); } } } @@ -2722,7 +2803,7 @@ void Node::_bind_methods() { GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE); ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); - ClassDB::bind_method(D_METHOD("add_child_below_node", "node", "child_node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_child_below_node", "preceding_node", "node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name); ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name); @@ -2826,7 +2907,7 @@ void Node::_bind_methods() { { MethodInfo mi; - mi.arguments.push_back(PropertyInfo(Variant::STRING, "method")); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); mi.name = "rpc"; ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "rpc", &Node::_rpc_bind, mi); @@ -2898,20 +2979,15 @@ void Node::_bind_methods() { ADD_GROUP("Pause", "pause_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode"); -#ifdef ENABLE_DEPRECATED - //no longer exists, but remains for compatibility (keep previous scenes folded - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", 0), "set_display_folded", "is_displayed_folded"); -#endif - - ADD_PROPERTY(PropertyInfo(Variant::STRING, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "name", PROPERTY_HINT_NONE, "", 0), "set_name", "get_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "filename", PROPERTY_HINT_NONE, "", 0), "set_filename", "get_filename"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "owner", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_owner", "get_owner"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "", "get_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); - BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta"))); - BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta"))); + BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta"))); + BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta"))); BIND_VMETHOD(MethodInfo("_enter_tree")); BIND_VMETHOD(MethodInfo("_exit_tree")); BIND_VMETHOD(MethodInfo("_ready")); diff --git a/scene/main/node.h b/scene/main/node.h index 6f5544d654..d1f75b71ec 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -85,6 +85,11 @@ private: GroupData() { persistent = false; } }; + struct NetData { + StringName name; + MultiplayerAPI::RPCMode mode; + }; + struct Data { String filename; @@ -118,8 +123,8 @@ private: Node *pause_owner; int network_master; - Map<StringName, MultiplayerAPI::RPCMode> rpc_methods; - Map<StringName, MultiplayerAPI::RPCMode> rpc_properties; + Vector<NetData> rpc_methods; + Vector<NetData> rpc_properties; // variables used to properly sort the node when processing, ignored otherwise //should move all the stuff below to bits @@ -180,10 +185,10 @@ private: Array _get_children() const; Array _get_groups() const; - Variant _rpc_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error); - Variant _rpc_unreliable_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error); - Variant _rpc_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error); - Variant _rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Variant _rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Variant _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Variant _rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); friend class SceneTree; @@ -427,8 +432,8 @@ public: int get_network_master() const; bool is_network_master() const; - void rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC - void rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC + uint16_t rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode); // config a local method for RPC + uint16_t rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode); // config a local property for RPC void rpc(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode void rpc_unreliable(const StringName &p_method, VARIANT_ARG_LIST); //rpc call, honors RPCMode @@ -446,8 +451,22 @@ public: Ref<MultiplayerAPI> get_multiplayer() const; Ref<MultiplayerAPI> get_custom_multiplayer() const; void set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rpc_mode(const StringName &p_method); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *get_node_rset_mode(const StringName &p_property); + + /// Returns the rpc method ID, otherwise UINT32_MAX + uint16_t get_node_rpc_method_id(const StringName &p_method) const; + StringName get_node_rpc_method(const uint16_t p_rpc_method_id) const; + MultiplayerAPI::RPCMode get_node_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + MultiplayerAPI::RPCMode get_node_rpc_mode(const StringName &p_method) const; + + /// Returns the rpc property ID, otherwise UINT32_MAX + uint16_t get_node_rset_property_id(const StringName &p_property) const; + StringName get_node_rset_property(const uint16_t p_rset_property_id) const; + MultiplayerAPI::RPCMode get_node_rset_mode_by_id(const uint16_t p_rpc_method_id) const; + MultiplayerAPI::RPCMode get_node_rset_mode(const StringName &p_property) const; + + /// Can be used to check if the rpc methods and the rset properties are the + /// same across the peers. + String get_rpc_md5() const; Node(); ~Node(); diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index 5582ed59b0..43a61834eb 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -35,7 +35,7 @@ void ResourcePreloader::_set_resources(const Array &p_data) { resources.clear(); ERR_FAIL_COND(p_data.size() != 2); - PoolVector<String> names = p_data[0]; + Vector<String> names = p_data[0]; Array resdata = p_data[1]; ERR_FAIL_COND(names.size() != resdata.size()); @@ -53,7 +53,7 @@ void ResourcePreloader::_set_resources(const Array &p_data) { Array ResourcePreloader::_get_resources() const { - PoolVector<String> names; + Vector<String> names; Array arr; arr.resize(resources.size()); names.resize(resources.size()); @@ -129,9 +129,9 @@ RES ResourcePreloader::get_resource(const StringName &p_name) const { return resources[p_name]; } -PoolVector<String> ResourcePreloader::_get_resource_list() const { +Vector<String> ResourcePreloader::_get_resource_list() const { - PoolVector<String> res; + Vector<String> res; res.resize(resources.size()); int i = 0; for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next(), i++) { diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index d03c784883..9ad219dd92 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -41,7 +41,7 @@ class ResourcePreloader : public Node { void _set_resources(const Array &p_data); Array _get_resources() const; - PoolVector<String> _get_resource_list() const; + Vector<String> _get_resource_list() const; protected: static void _bind_methods(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index c0e566eed5..370cf6a2a4 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -38,14 +38,16 @@ #include "core/os/os.h" #include "core/print_string.h" #include "core/project_settings.h" +#include "core/script_debugger_remote.h" #include "main/input_default.h" #include "node.h" -#include "scene/debugger/script_debugger_remote.h" +#include "scene/debugger/scene_debugger.h" #include "scene/resources/dynamic_font.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" +#include "servers/navigation_server.h" #include "servers/physics_2d_server.h" #include "servers/physics_server.h" #include "viewport.h" @@ -57,7 +59,7 @@ void SceneTreeTimer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_time_left", "time"), &SceneTreeTimer::set_time_left); ClassDB::bind_method(D_METHOD("get_time_left"), &SceneTreeTimer::get_time_left); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_left"), "set_time_left", "get_time_left"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_left"), "set_time_left", "get_time_left"); ADD_SIGNAL(MethodInfo("timeout")); } @@ -86,7 +88,7 @@ void SceneTreeTimer::release_connections() { for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { Connection const &connection = E->get(); - disconnect(connection.signal, connection.target, connection.method); + disconnect(connection.signal.get_name(), connection.callable); } } @@ -433,7 +435,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) { if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote()) { //quit from game window using F8 Ref<InputEventKey> k = ev; - if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_scancode() == KEY_F8) { + if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_F8) { ScriptDebugger::get_singleton()->request_quit(); } } @@ -791,11 +793,11 @@ Ref<Material> SceneTree::get_debug_navigation_material() { if (navigation_material.is_valid()) return navigation_material; - Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); line_material->set_albedo(get_debug_navigation_color()); navigation_material = line_material; @@ -808,11 +810,11 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material() { if (navigation_disabled_material.is_valid()) return navigation_disabled_material; - Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); line_material->set_albedo(get_debug_navigation_disabled_color()); navigation_disabled_material = line_material; @@ -824,11 +826,11 @@ Ref<Material> SceneTree::get_debug_collision_material() { if (collision_material.is_valid()) return collision_material; - Ref<SpatialMaterial> line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); line_material->set_albedo(get_debug_collisions_color()); collision_material = line_material; @@ -843,11 +845,11 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); - Ref<SpatialMaterial> mat = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + Ref<StandardMaterial3D> mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); mat->set_albedo(get_debug_collision_contact_color()); Vector3 diamond[6] = { @@ -872,11 +874,11 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { }; /* clang-format on */ - PoolVector<int> indices; + Vector<int> indices; for (int i = 0; i < 8 * 3; i++) indices.push_back(diamond_faces[i]); - PoolVector<Vector3> vertices; + Vector<Vector3> vertices; for (int i = 0; i < 6; i++) vertices.push_back(diamond[i] * 0.1); @@ -896,6 +898,7 @@ void SceneTree::set_pause(bool p_enabled) { if (p_enabled == pause) return; pause = p_enabled; + NavigationServer::get_singleton()->set_active(!p_enabled); PhysicsServer::get_singleton()->set_active(!p_enabled); Physics2DServer::get_singleton()->set_active(!p_enabled); if (get_root()) @@ -1002,14 +1005,14 @@ void SceneMainLoop::_update_listener_2d() { } */ -Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; ERR_FAIL_COND_V(p_argcount < 3, Variant()); ERR_FAIL_COND_V(!p_args[0]->is_num(), Variant()); - ERR_FAIL_COND_V(p_args[1]->get_type() != Variant::STRING, Variant()); - ERR_FAIL_COND_V(p_args[2]->get_type() != Variant::STRING, Variant()); + ERR_FAIL_COND_V(p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING, Variant()); + ERR_FAIL_COND_V(p_args[2]->get_type() != Variant::STRING_NAME && p_args[2]->get_type() != Variant::STRING, Variant()); int flags = *p_args[0]; StringName group = *p_args[1]; @@ -1025,13 +1028,13 @@ Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Var return Variant(); } -Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; ERR_FAIL_COND_V(p_argcount < 2, Variant()); - ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING, Variant()); - ERR_FAIL_COND_V(p_args[1]->get_type() != Variant::STRING, Variant()); + ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING, Variant()); + ERR_FAIL_COND_V(p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING, Variant()); StringName group = *p_args[0]; StringName method = *p_args[1]; @@ -1327,380 +1330,6 @@ void SceneTree::add_current_scene(Node *p_current) { root->add_child(p_current); } -#ifdef DEBUG_ENABLED - -static void _fill_array(Node *p_node, Array &array, int p_level) { - - array.push_back(p_node->get_child_count()); - array.push_back(p_node->get_name()); - array.push_back(p_node->get_class()); - array.push_back(p_node->get_instance_id()); - for (int i = 0; i < p_node->get_child_count(); i++) { - - _fill_array(p_node->get_child(i), array, p_level + 1); - } -} - -void SceneTree::_debugger_request_tree() { - - Array arr; - _fill_array(root, arr, 0); - ScriptDebugger::get_singleton()->send_message("scene_tree", arr); -} - -void SceneTree::_live_edit_node_path_func(const NodePath &p_path, int p_id) { - - live_edit_node_path_cache[p_id] = p_path; -} - -void SceneTree::_live_edit_res_path_func(const String &p_path, int p_id) { - - live_edit_resource_cache[p_id] = p_path; -} - -void SceneTree::_live_edit_node_set_func(int p_id, const StringName &p_prop, const Variant &p_value) { - - if (!live_edit_node_path_cache.has(p_id)) - return; - - NodePath np = live_edit_node_path_cache[p_id]; - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(np)) - continue; - Node *n2 = n->get_node(np); - - n2->set(p_prop, p_value); - } -} - -void SceneTree::_live_edit_node_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { - - RES r = ResourceLoader::load(p_value); - if (!r.is_valid()) - return; - _live_edit_node_set_func(p_id, p_prop, r); -} -void SceneTree::_live_edit_node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - - if (!live_edit_node_path_cache.has(p_id)) - return; - - NodePath np = live_edit_node_path_cache[p_id]; - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(np)) - continue; - Node *n2 = n->get_node(np); - - n2->call(p_method, VARIANT_ARG_PASS); - } -} -void SceneTree::_live_edit_res_set_func(int p_id, const StringName &p_prop, const Variant &p_value) { - - if (!live_edit_resource_cache.has(p_id)) - return; - - String resp = live_edit_resource_cache[p_id]; - - if (!ResourceCache::has(resp)) - return; - - RES r = ResourceCache::get(resp); - if (!r.is_valid()) - return; - - r->set(p_prop, p_value); -} -void SceneTree::_live_edit_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value) { - - RES r = ResourceLoader::load(p_value); - if (!r.is_valid()) - return; - _live_edit_res_set_func(p_id, p_prop, r); -} -void SceneTree::_live_edit_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - - if (!live_edit_resource_cache.has(p_id)) - return; - - String resp = live_edit_resource_cache[p_id]; - - if (!ResourceCache::has(resp)) - return; - - RES r = ResourceCache::get(resp); - if (!r.is_valid()) - return; - - r->call(p_method, VARIANT_ARG_PASS); -} - -void SceneTree::_live_edit_root_func(const NodePath &p_scene_path, const String &p_scene_from) { - - live_edit_root = p_scene_path; - live_edit_scene = p_scene_from; -} - -void SceneTree::_live_edit_create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_parent)) - continue; - Node *n2 = n->get_node(p_parent); - - Node *no = Object::cast_to<Node>(ClassDB::instance(p_type)); - if (!no) { - continue; - } - - no->set_name(p_name); - n2->add_child(no); - } -} -void SceneTree::_live_edit_instance_node_func(const NodePath &p_parent, const String &p_path, const String &p_name) { - - Ref<PackedScene> ps = ResourceLoader::load(p_path); - - if (!ps.is_valid()) - return; - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_parent)) - continue; - Node *n2 = n->get_node(p_parent); - - Node *no = ps->instance(); - if (!no) { - continue; - } - - no->set_name(p_name); - n2->add_child(no); - } -} -void SceneTree::_live_edit_remove_node_func(const NodePath &p_at) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F;) { - - Set<Node *>::Element *N = F->next(); - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_at)) - continue; - Node *n2 = n->get_node(p_at); - - memdelete(n2); - - F = N; - } -} -void SceneTree::_live_edit_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_keep_id) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F;) { - - Set<Node *>::Element *N = F->next(); - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_at)) - continue; - - Node *n2 = n->get_node(p_at); - - n2->get_parent()->remove_child(n2); - - live_edit_remove_list[n][p_keep_id] = n2; - - F = N; - } -} -void SceneTree::_live_edit_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_at_pos) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F;) { - - Set<Node *>::Element *N = F->next(); - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_at)) - continue; - Node *n2 = n->get_node(p_at); - - Map<Node *, Map<ObjectID, Node *> >::Element *EN = live_edit_remove_list.find(n); - - if (!EN) - continue; - - Map<ObjectID, Node *>::Element *FN = EN->get().find(p_id); - - if (!FN) - continue; - n2->add_child(FN->get()); - - EN->get().erase(FN); - - if (EN->get().size() == 0) { - live_edit_remove_list.erase(EN); - } - - F = N; - } -} -void SceneTree::_live_edit_duplicate_node_func(const NodePath &p_at, const String &p_new_name) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_at)) - continue; - Node *n2 = n->get_node(p_at); - - Node *dup = n2->duplicate(Node::DUPLICATE_SIGNALS | Node::DUPLICATE_GROUPS | Node::DUPLICATE_SCRIPTS); - - if (!dup) - continue; - - dup->set_name(p_new_name); - n2->get_parent()->add_child(dup); - } -} -void SceneTree::_live_edit_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) { - - Node *base = NULL; - if (root->has_node(live_edit_root)) - base = root->get_node(live_edit_root); - - Map<String, Set<Node *> >::Element *E = live_scene_edit_cache.find(live_edit_scene); - if (!E) - return; //scene not editable - - for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) { - - Node *n = F->get(); - - if (base && !base->is_a_parent_of(n)) - continue; - - if (!n->has_node(p_at)) - continue; - Node *nfrom = n->get_node(p_at); - - if (!n->has_node(p_new_place)) - continue; - Node *nto = n->get_node(p_new_place); - - nfrom->get_parent()->remove_child(nfrom); - nfrom->set_name(p_new_name); - - nto->add_child(nfrom); - if (p_at_pos >= 0) - nto->move_child(nfrom, p_at_pos); - } -} - -#endif - void SceneTree::drop_files(const Vector<String> &p_files, int p_from_screen) { emit_signal("files_dropped", p_files, p_from_screen); @@ -1764,21 +1393,21 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) { ERR_FAIL_COND(!p_multiplayer.is_valid()); if (multiplayer.is_valid()) { - multiplayer->disconnect("network_peer_connected", this, "_network_peer_connected"); - multiplayer->disconnect("network_peer_disconnected", this, "_network_peer_disconnected"); - multiplayer->disconnect("connected_to_server", this, "_connected_to_server"); - multiplayer->disconnect("connection_failed", this, "_connection_failed"); - multiplayer->disconnect("server_disconnected", this, "_server_disconnected"); + multiplayer->disconnect("network_peer_connected", callable_mp(this, &SceneTree::_network_peer_connected)); + multiplayer->disconnect("network_peer_disconnected", callable_mp(this, &SceneTree::_network_peer_disconnected)); + multiplayer->disconnect("connected_to_server", callable_mp(this, &SceneTree::_connected_to_server)); + multiplayer->disconnect("connection_failed", callable_mp(this, &SceneTree::_connection_failed)); + multiplayer->disconnect("server_disconnected", callable_mp(this, &SceneTree::_server_disconnected)); } multiplayer = p_multiplayer; multiplayer->set_root_node(root); - multiplayer->connect("network_peer_connected", this, "_network_peer_connected"); - multiplayer->connect("network_peer_disconnected", this, "_network_peer_disconnected"); - multiplayer->connect("connected_to_server", this, "_connected_to_server"); - multiplayer->connect("connection_failed", this, "_connection_failed"); - multiplayer->connect("server_disconnected", this, "_server_disconnected"); + multiplayer->connect("network_peer_connected", callable_mp(this, &SceneTree::_network_peer_connected)); + multiplayer->connect("network_peer_disconnected", callable_mp(this, &SceneTree::_network_peer_disconnected)); + multiplayer->connect("connected_to_server", callable_mp(this, &SceneTree::_connected_to_server)); + multiplayer->connect("connection_failed", callable_mp(this, &SceneTree::_connection_failed)); + multiplayer->connect("server_disconnected", callable_mp(this, &SceneTree::_server_disconnected)); } void SceneTree::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_network_peer) { @@ -1856,8 +1485,8 @@ void SceneTree::_bind_methods() { MethodInfo mi; mi.name = "call_group_flags"; mi.arguments.push_back(PropertyInfo(Variant::INT, "flags")); - mi.arguments.push_back(PropertyInfo(Variant::STRING, "group")); - mi.arguments.push_back(PropertyInfo(Variant::STRING, "method")); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "group")); + mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_group_flags", &SceneTree::_call_group_flags, mi); @@ -1866,8 +1495,8 @@ void SceneTree::_bind_methods() { MethodInfo mi2; mi2.name = "call_group"; - mi2.arguments.push_back(PropertyInfo(Variant::STRING, "group")); - mi2.arguments.push_back(PropertyInfo(Variant::STRING, "method")); + mi2.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "group")); + mi2.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_group", &SceneTree::_call_group, mi2); @@ -1899,11 +1528,6 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rpc_sender_id"), &SceneTree::get_rpc_sender_id); ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &SceneTree::set_refuse_new_network_connections); ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &SceneTree::is_refusing_new_network_connections); - ClassDB::bind_method(D_METHOD("_network_peer_connected"), &SceneTree::_network_peer_connected); - ClassDB::bind_method(D_METHOD("_network_peer_disconnected"), &SceneTree::_network_peer_disconnected); - ClassDB::bind_method(D_METHOD("_connected_to_server"), &SceneTree::_connected_to_server); - ClassDB::bind_method(D_METHOD("_connection_failed"), &SceneTree::_connection_failed); - ClassDB::bind_method(D_METHOD("_server_disconnected"), &SceneTree::_server_disconnected); ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &SceneTree::set_use_font_oversampling); ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &SceneTree::is_using_font_oversampling); @@ -1931,7 +1555,7 @@ void SceneTree::_bind_methods() { ADD_SIGNAL(MethodInfo("idle_frame")); ADD_SIGNAL(MethodInfo("physics_frame")); - ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "screen"))); + ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "screen"))); ADD_SIGNAL(MethodInfo("global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta"))); ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id"))); @@ -2071,22 +1695,10 @@ SceneTree::SceneTree() { root->set_as_audio_listener_2d(true); current_scene = NULL; - int ref_atlas_size = GLOBAL_DEF("rendering/quality/reflections/atlas_size", 2048); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_size", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_size", PROPERTY_HINT_RANGE, "0,8192,or_greater")); //next_power_of_2 will return a 0 as min value - int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/reflections/atlas_subdiv", PropertyInfo(Variant::INT, "rendering/quality/reflections/atlas_subdiv", PROPERTY_HINT_RANGE, "0,32,or_greater")); //next_power_of_2 will return a 0 as min value int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x")); root->set_msaa(Viewport::MSAA(msaa_mode)); - GLOBAL_DEF("rendering/quality/depth/hdr", true); - GLOBAL_DEF("rendering/quality/depth/hdr.mobile", false); - - bool hdr = GLOBAL_GET("rendering/quality/depth/hdr"); - root->set_hdr(hdr); - - VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv); - { //load default fallback environment //get possible extensions List<String> exts; @@ -2126,11 +1738,6 @@ SceneTree::SceneTree() { _update_root_rect(); if (ScriptDebugger::get_singleton()) { - if (ScriptDebugger::get_singleton()->is_remote()) { - ScriptDebuggerRemote *remote_debugger = static_cast<ScriptDebuggerRemote *>(ScriptDebugger::get_singleton()); - - remote_debugger->set_scene_tree(this); - } ScriptDebugger::get_singleton()->set_multiplayer(multiplayer); } @@ -2139,12 +1746,6 @@ SceneTree::SceneTree() { #ifdef TOOLS_ENABLED edited_scene_root = NULL; #endif - -#ifdef DEBUG_ENABLED - - live_edit_root = NodePath("/root"); - -#endif } SceneTree::~SceneTree() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 55304fb12d..1bef0d3131 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -44,6 +44,7 @@ class Node; class Viewport; class Material; class Mesh; +class SceneDebugger; class SceneTreeTimer : public Reference { GDCLASS(SceneTreeTimer, Reference); @@ -208,8 +209,8 @@ private: void _notify_group_pause(const StringName &p_group, int p_notification); void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input); - Variant _call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error); - Variant _call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant _call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Variant _call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error); void _flush_delete_queue(); //optimization @@ -219,39 +220,8 @@ private: SelfList<Node>::List xform_change_list; - friend class ScriptDebuggerRemote; -#ifdef DEBUG_ENABLED - - Map<int, NodePath> live_edit_node_path_cache; - Map<int, String> live_edit_resource_cache; - - NodePath live_edit_root; - String live_edit_scene; - - Map<String, Set<Node *> > live_scene_edit_cache; - Map<Node *, Map<ObjectID, Node *> > live_edit_remove_list; - - void _debugger_request_tree(); - - void _live_edit_node_path_func(const NodePath &p_path, int p_id); - void _live_edit_res_path_func(const String &p_path, int p_id); - - void _live_edit_node_set_func(int p_id, const StringName &p_prop, const Variant &p_value); - void _live_edit_node_set_res_func(int p_id, const StringName &p_prop, const String &p_value); - void _live_edit_node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE); - void _live_edit_res_set_func(int p_id, const StringName &p_prop, const Variant &p_value); - void _live_edit_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value); - void _live_edit_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE); - void _live_edit_root_func(const NodePath &p_scene_path, const String &p_scene_from); - - void _live_edit_create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name); - void _live_edit_instance_node_func(const NodePath &p_parent, const String &p_path, const String &p_name); - void _live_edit_remove_node_func(const NodePath &p_at); - void _live_edit_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_keep_id); - void _live_edit_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_at_pos); - void _live_edit_duplicate_node_func(const NodePath &p_at, const String &p_new_name); - void _live_edit_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos); - +#ifdef DEBUG_ENABLED // No live editor in release build. + friend class LiveEditor; #endif enum { @@ -411,6 +381,9 @@ public: bool is_refusing_new_network_connections() const; static void add_idle_callback(IdleCallback p_callback); + + //default texture settings + SceneTree(); ~SceneTree(); }; diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index cb213be731..7c847095e1 100755 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -206,11 +206,11 @@ void Timer::_bind_methods() { ADD_SIGNAL(MethodInfo("timeout")); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_timer_process_mode", "get_timer_process_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.001,4096,0.001,or_greater"), "set_wait_time", "get_wait_time"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wait_time", PROPERTY_HINT_EXP_RANGE, "0.001,4096,0.001,or_greater"), "set_wait_time", "get_wait_time"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "is_one_shot"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autostart"), "set_autostart", "has_autostart"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused", PROPERTY_HINT_NONE, "", 0), "set_paused", "is_paused"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_left", PROPERTY_HINT_NONE, "", 0), "", "get_time_left"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_left", PROPERTY_HINT_NONE, "", 0), "", "get_time_left"); BIND_ENUM_CONSTANT(TIMER_PROCESS_PHYSICS); BIND_ENUM_CONSTANT(TIMER_PROCESS_IDLE); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 72ab817e98..e027ec9b4b 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -74,10 +74,13 @@ void ViewportTexture::setup_local_to_scene() { vp->viewport_textures.insert(this); - VS::get_singleton()->texture_set_proxy(proxy, vp->texture_rid); - - vp->texture_flags = flags; - VS::get_singleton()->texture_set_flags(vp->texture_rid, flags); + if (proxy_ph.is_valid()) { + VS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid); + VS::get_singleton()->free(proxy_ph); + } else { + ERR_FAIL_COND(proxy.is_valid()); //should be invalid + proxy = VS::get_singleton()->texture_proxy_create(vp->texture_rid); + } } void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) { @@ -115,6 +118,10 @@ Size2 ViewportTexture::get_size() const { RID ViewportTexture::get_rid() const { //ERR_FAIL_COND_V_MSG(!vp, RID(), "Viewport Texture must be set to use it."); + if (proxy.is_null()) { + proxy_ph = VS::get_singleton()->texture_2d_placeholder_create(); + proxy = VS::get_singleton()->texture_proxy_create(proxy_ph); + } return proxy; } @@ -125,21 +132,7 @@ bool ViewportTexture::has_alpha() const { Ref<Image> ViewportTexture::get_data() const { ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it."); - return VS::get_singleton()->texture_get_data(vp->texture_rid); -} -void ViewportTexture::set_flags(uint32_t p_flags) { - flags = p_flags; - - if (!vp) - return; - - vp->texture_flags = flags; - VS::get_singleton()->texture_set_flags(vp->texture_rid, flags); -} - -uint32_t ViewportTexture::get_flags() const { - - return flags; + return VS::get_singleton()->texture_2d_get(vp->texture_rid); } void ViewportTexture::_bind_methods() { @@ -153,9 +146,7 @@ void ViewportTexture::_bind_methods() { ViewportTexture::ViewportTexture() { vp = NULL; - flags = 0; set_local_to_scene(true); - proxy = VS::get_singleton()->texture_create(); } ViewportTexture::~ViewportTexture() { @@ -164,7 +155,12 @@ ViewportTexture::~ViewportTexture() { vp->viewport_textures.erase(this); } - VS::get_singleton()->free(proxy); + if (proxy_ph.is_valid()) { + VS::get_singleton()->free(proxy_ph); + } + if (proxy.is_valid()) { + VS::get_singleton()->free(proxy); + } } ///////////////////////////////////// @@ -304,7 +300,7 @@ void Viewport::_notification(int p_what) { //3D PhysicsServer::get_singleton()->space_set_debug_contacts(find_world()->get_space(), get_tree()->get_collision_debug_contact_count()); contact_3d_debug_multimesh = VisualServer::get_singleton()->multimesh_create(); - VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT); + VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, true); VisualServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0); VisualServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid()); contact_3d_debug_instance = VisualServer::get_singleton()->instance_create(); @@ -416,7 +412,7 @@ void Viewport::_notification(int p_what) { #ifndef _3D_DISABLED Vector2 last_pos(1e20, 1e20); CollisionObject *last_object = NULL; - ObjectID last_id = 0; + ObjectID last_id; #endif PhysicsDirectSpaceState::RayResult result; Physics2DDirectSpaceState *ss2d = Physics2DServer::get_singleton()->space_get_direct_state(find_world_2d()->get_space()); @@ -536,7 +532,7 @@ void Viewport::_notification(int p_what) { } else { // This Viewport's builtin canvas canvas_transform = get_canvas_transform(); - canvas_layer_id = 0; + canvas_layer_id = ObjectID(); } Vector2 point = canvas_transform.affine_inverse().xform(pos); @@ -544,7 +540,7 @@ void Viewport::_notification(int p_what) { int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true); for (int i = 0; i < rc; i++) { - if (res[i].collider_id && res[i].collider) { + if (res[i].collider_id.is_valid() && res[i].collider) { CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider); if (co) { bool send_event = true; @@ -598,18 +594,18 @@ void Viewport::_notification(int p_what) { #ifndef _3D_DISABLED bool captured = false; - if (physics_object_capture != 0) { + if (physics_object_capture.is_valid()) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_capture)); if (co && camera) { _collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0); captured = true; if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) { - physics_object_capture = 0; + physics_object_capture = ObjectID(); } } else { - physics_object_capture = 0; + physics_object_capture = ObjectID(); } } @@ -617,7 +613,7 @@ void Viewport::_notification(int p_what) { //none } else if (pos == last_pos) { - if (last_id) { + if (last_id.is_valid()) { if (ObjectDB::get_instance(last_id) && last_object) { //good, exists _collision_object_input_event(last_object, camera, ev, result.position, result.normal, result.shape); @@ -637,7 +633,7 @@ void Viewport::_notification(int p_what) { if (space) { bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true); - ObjectID new_collider = 0; + ObjectID new_collider; if (col) { CollisionObject *co = Object::cast_to<CollisionObject>(result.collider); @@ -655,7 +651,7 @@ void Viewport::_notification(int p_what) { if (is_mouse && new_collider != physics_object_over) { - if (physics_object_over) { + if (physics_object_over.is_valid()) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over)); if (co) { @@ -663,7 +659,7 @@ void Viewport::_notification(int p_what) { } } - if (new_collider) { + if (new_collider.is_valid()) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(new_collider)); if (co) { @@ -1128,7 +1124,7 @@ void Viewport::set_world(const Ref<World> &p_world) { _propagate_exit_world(this); if (own_world.is_valid() && world.is_valid()) { - world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + world->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed)); } world = p_world; @@ -1136,7 +1132,7 @@ void Viewport::set_world(const Ref<World> &p_world) { if (own_world.is_valid()) { if (world.is_valid()) { own_world = world->duplicate(); - world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + world->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed)); } else { own_world = Ref<World>(memnew(World)); } @@ -1334,17 +1330,6 @@ Ref<ViewportTexture> Viewport::get_texture() const { return default_texture; } -void Viewport::set_vflip(bool p_enable) { - - vflip = p_enable; - VisualServer::get_singleton()->viewport_set_vflip(viewport, p_enable); -} - -bool Viewport::get_vflip() const { - - return vflip; -} - void Viewport::set_clear_mode(ClearMode p_mode) { clear_mode = p_mode; @@ -2488,7 +2473,7 @@ List<Control *>::Element *Viewport::_gui_add_root_control(Control *p_control) { List<Control *>::Element *Viewport::_gui_add_subwindow_control(Control *p_control) { - p_control->connect("visibility_changed", this, "_subwindow_visibility_changed"); + p_control->connect("visibility_changed", callable_mp(this, &Viewport::_subwindow_visibility_changed)); if (p_control->is_visible_in_tree()) { gui.subwindow_order_dirty = true; @@ -2519,7 +2504,7 @@ void Viewport::_gui_remove_from_modal_stack(List<Control *>::Element *MI, Object gui.modal_stack.erase(MI); - if (p_prev_focus_owner) { + if (p_prev_focus_owner.is_valid()) { // for previous window in stack, pass the focus so it feels more // natural @@ -2583,7 +2568,7 @@ void Viewport::_gui_remove_subwindow_control(List<Control *>::Element *SI) { Control *control = SI->get(); - control->disconnect("visibility_changed", this, "_subwindow_visibility_changed"); + control->disconnect("visibility_changed", callable_mp(this, &Viewport::_subwindow_visibility_changed)); List<Control *>::Element *E = gui.subwindows.find(control); if (E) @@ -2716,14 +2701,15 @@ void Viewport::_drop_physics_mouseover() { } #ifndef _3D_DISABLED - if (physics_object_over) { + if (physics_object_over.is_valid()) { CollisionObject *co = Object::cast_to<CollisionObject>(ObjectDB::get_instance(physics_object_over)); if (co) { co->_mouse_exit(); } } - physics_object_over = physics_object_capture = 0; + physics_object_over = ObjectID(); + physics_object_capture = ObjectID(); #endif } @@ -2733,7 +2719,7 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { if (gui.key_focus) p_control->_modal_set_prev_focus_owner(gui.key_focus->get_instance_id()); else - p_control->_modal_set_prev_focus_owner(0); + p_control->_modal_set_prev_focus_owner(ObjectID()); if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) { @@ -2864,12 +2850,12 @@ void Viewport::set_use_own_world(bool p_world) { if (!p_world) { own_world = Ref<World>(); if (world.is_valid()) { - world->disconnect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + world->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed)); } } else { if (world.is_valid()) { own_world = world->duplicate(); - world->connect(CoreStringNames::get_singleton()->changed, this, "_own_world_changed"); + world->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed)); } else { own_world = Ref<World>(memnew(World)); } @@ -2952,26 +2938,6 @@ bool Viewport::is_input_disabled() const { return disable_input; } -void Viewport::set_disable_3d(bool p_disable) { - disable_3d = p_disable; - VS::get_singleton()->viewport_set_disable_3d(viewport, p_disable); -} - -bool Viewport::is_3d_disabled() const { - - return disable_3d; -} - -void Viewport::set_keep_3d_linear(bool p_keep_3d_linear) { - keep_3d_linear = p_keep_3d_linear; - VS::get_singleton()->viewport_set_keep_3d_linear(viewport, keep_3d_linear); -} - -bool Viewport::get_keep_3d_linear() const { - - return keep_3d_linear; -} - Variant Viewport::gui_get_drag_data() const { return gui.drag_data; } @@ -3012,30 +2978,6 @@ Viewport::MSAA Viewport::get_msaa() const { return msaa; } -void Viewport::set_hdr(bool p_hdr) { - - if (hdr == p_hdr) - return; - - hdr = p_hdr; - VS::get_singleton()->viewport_set_hdr(viewport, p_hdr); -} - -bool Viewport::get_hdr() const { - - return hdr; -} - -void Viewport::set_usage(Usage p_usage) { - - usage = p_usage; - VS::get_singleton()->viewport_set_usage(viewport, VS::ViewportUsage(p_usage)); -} - -Viewport::Usage Viewport::get_usage() const { - return usage; -} - void Viewport::set_debug_draw(DebugDraw p_debug_draw) { debug_draw = p_debug_draw; @@ -3094,9 +3036,50 @@ bool Viewport::is_handling_input_locally() const { } void Viewport::_validate_property(PropertyInfo &property) const { +} - if (VisualServer::get_singleton()->is_low_end() && property.name == "hdr") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; +void Viewport::set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter) { + if (default_canvas_item_texture_filter == p_filter) { + return; + } + default_canvas_item_texture_filter = p_filter; + _propagate_update_default_filter(this); +} + +Viewport::DefaultCanvasItemTextureFilter Viewport::get_default_canvas_item_texture_filter() const { + return default_canvas_item_texture_filter; +} + +void Viewport::set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat) { + if (default_canvas_item_texture_repeat == p_repeat) { + return; + } + default_canvas_item_texture_repeat = p_repeat; + _propagate_update_default_repeat(this); +} +Viewport::DefaultCanvasItemTextureRepeat Viewport::get_default_canvas_item_texture_repeat() const { + return default_canvas_item_texture_repeat; +} + +void Viewport::_propagate_update_default_filter(Node *p_node) { + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci) { + ci->_update_texture_filter_changed(false); + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_update_default_filter(p_node->get_child(i)); + } +} + +void Viewport::_propagate_update_default_repeat(Node *p_node) { + CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); + if (ci) { + ci->_update_texture_repeat_changed(false); + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _propagate_update_default_repeat(p_node->get_child(i)); } } @@ -3135,9 +3118,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch); ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled); - ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip); - ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip); - ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &Viewport::set_clear_mode); ClassDB::bind_method(D_METHOD("get_clear_mode"), &Viewport::get_clear_mode); @@ -3147,12 +3127,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_msaa", "msaa"), &Viewport::set_msaa); ClassDB::bind_method(D_METHOD("get_msaa"), &Viewport::get_msaa); - ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr); - ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr); - - ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage); - ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage); - ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); @@ -3195,12 +3169,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input); ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled); - ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d); - ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled); - - ClassDB::bind_method(D_METHOD("set_keep_3d_linear", "keep_3d_linear"), &Viewport::set_keep_3d_linear); - ClassDB::bind_method(D_METHOD("get_keep_3d_linear"), &Viewport::get_keep_3d_linear); - ClassDB::bind_method(D_METHOD("_gui_show_tooltip"), &Viewport::_gui_show_tooltip); ClassDB::bind_method(D_METHOD("_gui_remove_focus"), &Viewport::_gui_remove_focus); ClassDB::bind_method(D_METHOD("_post_gui_grab_click_focus"), &Viewport::_post_gui_grab_click_focus); @@ -3220,9 +3188,11 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_handle_input_locally", "enable"), &Viewport::set_handle_input_locally); ClassDB::bind_method(D_METHOD("is_handling_input_locally"), &Viewport::is_handling_input_locally); - ClassDB::bind_method(D_METHOD("_subwindow_visibility_changed"), &Viewport::_subwindow_visibility_changed); + ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_filter", "mode"), &Viewport::set_default_canvas_item_texture_filter); + ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_filter"), &Viewport::get_default_canvas_item_texture_filter); - ClassDB::bind_method(D_METHOD("_own_world_changed"), &Viewport::_own_world_changed); + ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat); + ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr"); @@ -3235,16 +3205,14 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally"); ADD_GROUP("Rendering", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_direct_to_screen"), "set_use_render_direct_to_screen", "is_using_render_direct_to_screen"); ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Render Target", "render_target_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode"); + ADD_GROUP("Canvas Items", "canvas_item_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapLinear,MipmapNearest"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat"); ADD_GROUP("Audio Listener", "audio_listener_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener", "is_audio_listener"); @@ -3292,20 +3260,34 @@ void Viewport::_bind_methods() { BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW); BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME); + BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO); + BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING); + BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION); + BIND_ENUM_CONSTANT(DEBUG_DRAW_SHADOW_ATLAS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS); + BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE); + BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO); + BIND_ENUM_CONSTANT(MSAA_DISABLED); BIND_ENUM_CONSTANT(MSAA_2X); BIND_ENUM_CONSTANT(MSAA_4X); BIND_ENUM_CONSTANT(MSAA_8X); BIND_ENUM_CONSTANT(MSAA_16X); - BIND_ENUM_CONSTANT(USAGE_2D); - BIND_ENUM_CONSTANT(USAGE_2D_NO_SAMPLING); - BIND_ENUM_CONSTANT(USAGE_3D); - BIND_ENUM_CONSTANT(USAGE_3D_NO_EFFECTS); - BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS); BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER); BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME); + + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); + + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR); + BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX); } void Viewport::_subwindow_visibility_changed() { @@ -3321,14 +3303,13 @@ Viewport::Viewport() { viewport = VisualServer::get_singleton()->viewport_create(); texture_rid = VisualServer::get_singleton()->viewport_get_texture(viewport); - texture_flags = 0; render_direct_to_screen = false; default_texture.instance(); default_texture->vp = const_cast<Viewport *>(this); viewport_textures.insert(default_texture.ptr()); - VS::get_singleton()->texture_set_proxy(default_texture->proxy, texture_rid); + default_texture->proxy = VS::get_singleton()->texture_proxy_create(texture_rid); //internal_listener = SpatialSoundServer::get_singleton()->listener_create(); audio_listener = false; @@ -3346,14 +3327,10 @@ Viewport::Viewport() { size_override_size = Size2(1, 1); gen_mipmaps = false; - vflip = false; - //clear=true; update_mode = UPDATE_WHEN_VISIBLE; physics_object_picking = false; - physics_object_capture = 0; - physics_object_over = 0; physics_has_last_mousepos = false; physics_last_mousepos = Vector2(Math_INF, Math_INF); @@ -3373,15 +3350,13 @@ Viewport::Viewport() { unhandled_key_input_group = "_vp_unhandled_key_input" + id; disable_input = false; - disable_3d = false; - keep_3d_linear = false; //window tooltip gui.tooltip_timer = -1; //gui.tooltip_timer->force_parent_owned(); gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5); - ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::REAL, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers + ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers gui.tooltip = NULL; gui.tooltip_label = NULL; @@ -3393,9 +3368,7 @@ Viewport::Viewport() { gui.last_mouse_focus = NULL; msaa = MSAA_DISABLED; - hdr = true; - usage = USAGE_3D; debug_draw = DEBUG_DRAW_DISABLED; clear_mode = CLEAR_MODE_ALWAYS; @@ -3407,7 +3380,9 @@ Viewport::Viewport() { physics_last_mouse_state.mouse_mask = 0; local_input_handled = false; handle_input_locally = true; - physics_last_id = 0; //ensures first time there will be a check + + default_canvas_item_texture_filter = DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR; + default_canvas_item_texture_repeat = DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 79b606cda3..30c872b6ed 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -49,17 +49,17 @@ class Timer; class Viewport; class CollisionObject; -class ViewportTexture : public Texture { +class ViewportTexture : public Texture2D { - GDCLASS(ViewportTexture, Texture); + GDCLASS(ViewportTexture, Texture2D); NodePath path; friend class Viewport; Viewport *vp; - uint32_t flags; - RID proxy; + mutable RID proxy_ph; + mutable RID proxy; protected: static void _bind_methods(); @@ -77,9 +77,6 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - virtual Ref<Image> get_data() const; ViewportTexture(); @@ -107,7 +104,6 @@ public: SHADOW_ATLAS_QUADRANT_SUBDIV_256, SHADOW_ATLAS_QUADRANT_SUBDIV_1024, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX, - }; enum MSAA { @@ -118,13 +114,6 @@ public: MSAA_16X, }; - enum Usage { - USAGE_2D, - USAGE_2D_NO_SAMPLING, - USAGE_3D, - USAGE_3D_NO_EFFECTS, - }; - enum RenderInfo { RENDER_INFO_OBJECTS_IN_FRAME, @@ -139,8 +128,18 @@ public: enum DebugDraw { DEBUG_DRAW_DISABLED, DEBUG_DRAW_UNSHADED, + DEBUG_DRAW_LIGHTING, DEBUG_DRAW_OVERDRAW, DEBUG_DRAW_WIREFRAME, + DEBUG_DRAW_NORMAL_BUFFER, + DEBUG_DRAW_GI_PROBE_ALBEDO, + DEBUG_DRAW_GI_PROBE_LIGHTING, + DEBUG_DRAW_GI_PROBE_EMISSION, + DEBUG_DRAW_SHADOW_ATLAS, + DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS, + DEBUG_DRAW_SCENE_LUMINANCE, + DEBUG_DRAW_SSAO, + DEBUG_DRAW_ROUGHNESS_LIMITER }; enum ClearMode { @@ -150,6 +149,21 @@ public: CLEAR_MODE_ONLY_NEXT_FRAME }; + enum DefaultCanvasItemTextureFilter { + DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST, + DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR, + DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, + DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, + DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX + }; + + enum DefaultCanvasItemTextureRepeat { + DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, + DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED, + DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR, + DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX, + }; + private: friend class ViewportTexture; @@ -214,7 +228,6 @@ private: Rect2 last_vp_rect; bool transparent_bg; - bool vflip; ClearMode clear_mode; bool filter; bool gen_mipmaps; @@ -266,22 +279,15 @@ private: void _update_stretch_transform(); void _update_global_transform(); - bool disable_3d; - bool keep_3d_linear; UpdateMode update_mode; RID texture_rid; - uint32_t texture_flags; DebugDraw debug_draw; - Usage usage; - int shadow_atlas_size; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; MSAA msaa; - bool hdr; - Ref<ViewportTexture> default_texture; Set<ViewportTexture *> viewport_textures; @@ -320,6 +326,12 @@ private: GUI(); } gui; + DefaultCanvasItemTextureFilter default_canvas_item_texture_filter; + DefaultCanvasItemTextureRepeat default_canvas_item_texture_repeat; + + void _propagate_update_default_filter(Node *p_node); + void _propagate_update_default_repeat(Node *p_node); + bool disable_input; void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input); @@ -474,9 +486,6 @@ public: void set_size_override_stretch(bool p_enable); bool is_size_override_stretch_enabled() const; - void set_vflip(bool p_enable); - bool get_vflip() const; - void set_clear_mode(ClearMode p_mode); ClearMode get_clear_mode() const; @@ -493,9 +502,6 @@ public: void set_msaa(MSAA p_msaa); MSAA get_msaa() const; - void set_hdr(bool p_hdr); - bool get_hdr() const; - Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; @@ -508,12 +514,6 @@ public: void set_disable_input(bool p_disable); bool is_input_disabled() const; - void set_disable_3d(bool p_disable); - bool is_3d_disabled() const; - - void set_keep_3d_linear(bool p_keep_3d_linear); - bool get_keep_3d_linear() const; - void set_attach_to_screen_rect(const Rect2 &p_rect); Rect2 get_attach_to_screen_rect() const; @@ -536,9 +536,6 @@ public: virtual String get_configuration_warning() const; - void set_usage(Usage p_usage); - Usage get_usage() const; - void set_debug_draw(DebugDraw p_debug_draw); DebugDraw get_debug_draw() const; @@ -557,6 +554,12 @@ public: bool gui_is_dragging() const; + void set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter); + DefaultCanvasItemTextureFilter get_default_canvas_item_texture_filter() const; + + void set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat); + DefaultCanvasItemTextureRepeat get_default_canvas_item_texture_repeat() const; + Viewport(); ~Viewport(); }; @@ -564,9 +567,10 @@ public: VARIANT_ENUM_CAST(Viewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); -VARIANT_ENUM_CAST(Viewport::Usage); VARIANT_ENUM_CAST(Viewport::DebugDraw); VARIANT_ENUM_CAST(Viewport::ClearMode); VARIANT_ENUM_CAST(Viewport::RenderInfo); +VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter); +VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureRepeat); #endif diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index d53872df6e..dd00565929 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -50,6 +50,8 @@ #include "scene/2d/mesh_instance_2d.h" #include "scene/2d/multimesh_instance_2d.h" #include "scene/2d/navigation_2d.h" +#include "scene/2d/navigation_agent_2d.h" +#include "scene/2d/navigation_obstacle_2d.h" #include "scene/2d/parallax_background.h" #include "scene/2d/parallax_layer.h" #include "scene/2d/particles_2d.h" @@ -71,10 +73,10 @@ #include "scene/animation/animation_node_state_machine.h" #include "scene/animation/animation_player.h" #include "scene/animation/animation_tree.h" -#include "scene/animation/animation_tree_player.h" #include "scene/animation/root_motion_view.h" #include "scene/animation/tween.h" #include "scene/audio/audio_stream_player.h" +#include "scene/debugger/scene_debugger.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" #include "scene/gui/center_container.h" @@ -145,10 +147,10 @@ #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" +#include "scene/resources/navigation_mesh.h" #include "scene/resources/packed_scene.h" #include "scene/resources/particles_material.h" #include "scene/resources/physics_material.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/polygon_path_finder.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/ray_shape.h" @@ -166,11 +168,9 @@ #include "scene/resources/visual_shader_nodes.h" #include "scene/resources/world.h" #include "scene/resources/world_2d.h" +#include "scene/resources/world_margin_shape.h" #include "scene/scene_string_names.h" -#include "scene/3d/spatial.h" -#include "scene/3d/world_environment.h" - #ifndef _3D_DISABLED #include "scene/3d/area.h" #include "scene/3d/arvr_nodes.h" @@ -189,7 +189,9 @@ #include "scene/3d/mesh_instance.h" #include "scene/3d/multimesh_instance.h" #include "scene/3d/navigation.h" -#include "scene/3d/navigation_mesh.h" +#include "scene/3d/navigation_agent.h" +#include "scene/3d/navigation_obstacle.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/particles.h" #include "scene/3d/path.h" #include "scene/3d/physics_body.h" @@ -201,10 +203,12 @@ #include "scene/3d/remote_transform.h" #include "scene/3d/skeleton.h" #include "scene/3d/soft_body.h" +#include "scene/3d/spatial.h" #include "scene/3d/spring_arm.h" #include "scene/3d/sprite_3d.h" #include "scene/3d/vehicle_body.h" #include "scene/3d/visibility_notifier.h" +#include "scene/3d/world_environment.h" #include "scene/animation/skeleton_ik.h" #include "scene/resources/environment.h" #include "scene/resources/mesh_library.h" @@ -370,7 +374,6 @@ void register_scene_types() { ClassDB::register_class<AnimationPlayer>(); ClassDB::register_class<Tween>(); - ClassDB::register_class<AnimationTreePlayer>(); ClassDB::register_class<AnimationTree>(); ClassDB::register_class<AnimationNode>(); ClassDB::register_class<AnimationRootNode>(); @@ -417,14 +420,11 @@ void register_scene_types() { ClassDB::register_class<ReflectionProbe>(); ClassDB::register_class<GIProbe>(); ClassDB::register_class<GIProbeData>(); - ClassDB::register_class<BakedLightmap>(); - ClassDB::register_class<BakedLightmapData>(); + //ClassDB::register_class<BakedLightmap>(); + //ClassDB::register_class<BakedLightmapData>(); ClassDB::register_class<Particles>(); ClassDB::register_class<CPUParticles>(); ClassDB::register_class<Position3D>(); - ClassDB::register_class<NavigationMeshInstance>(); - ClassDB::register_class<NavigationMesh>(); - ClassDB::register_class<Navigation>(); ClassDB::register_class<RootMotionView>(); ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor @@ -469,9 +469,15 @@ void register_scene_types() { ClassDB::register_class<ConeTwistJoint>(); ClassDB::register_class<Generic6DOFJoint>(); + ClassDB::register_class<Navigation>(); + ClassDB::register_class<NavigationRegion>(); + ClassDB::register_class<NavigationAgent>(); + ClassDB::register_class<NavigationObstacle>(); + OS::get_singleton()->yield(); //may take time to init #endif + ClassDB::register_class<NavigationMesh>(); AcceptDialog::set_swap_ok_cancel(GLOBAL_DEF("gui/common/swap_ok_cancel", bool(OS::get_singleton()->get_swap_ok_cancel()))); @@ -482,17 +488,20 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeInput>(); ClassDB::register_virtual_class<VisualShaderNodeOutput>(); ClassDB::register_class<VisualShaderNodeGroupBase>(); - ClassDB::register_class<VisualShaderNodeScalarConstant>(); + ClassDB::register_class<VisualShaderNodeFloatConstant>(); + ClassDB::register_class<VisualShaderNodeIntConstant>(); ClassDB::register_class<VisualShaderNodeBooleanConstant>(); ClassDB::register_class<VisualShaderNodeColorConstant>(); ClassDB::register_class<VisualShaderNodeVec3Constant>(); ClassDB::register_class<VisualShaderNodeTransformConstant>(); - ClassDB::register_class<VisualShaderNodeScalarOp>(); + ClassDB::register_class<VisualShaderNodeFloatOp>(); + ClassDB::register_class<VisualShaderNodeIntOp>(); ClassDB::register_class<VisualShaderNodeVectorOp>(); ClassDB::register_class<VisualShaderNodeColorOp>(); ClassDB::register_class<VisualShaderNodeTransformMult>(); ClassDB::register_class<VisualShaderNodeTransformVecMult>(); - ClassDB::register_class<VisualShaderNodeScalarFunc>(); + ClassDB::register_class<VisualShaderNodeFloatFunc>(); + ClassDB::register_class<VisualShaderNodeIntFunc>(); ClassDB::register_class<VisualShaderNodeVectorFunc>(); ClassDB::register_class<VisualShaderNodeColorFunc>(); ClassDB::register_class<VisualShaderNodeTransformFunc>(); @@ -519,16 +528,17 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeVectorDecompose>(); ClassDB::register_class<VisualShaderNodeTransformDecompose>(); ClassDB::register_class<VisualShaderNodeTexture>(); - ClassDB::register_class<VisualShaderNodeCubeMap>(); + ClassDB::register_class<VisualShaderNodeCubemap>(); ClassDB::register_virtual_class<VisualShaderNodeUniform>(); - ClassDB::register_class<VisualShaderNodeScalarUniform>(); + ClassDB::register_class<VisualShaderNodeFloatUniform>(); + ClassDB::register_class<VisualShaderNodeIntUniform>(); ClassDB::register_class<VisualShaderNodeBooleanUniform>(); ClassDB::register_class<VisualShaderNodeColorUniform>(); ClassDB::register_class<VisualShaderNodeVec3Uniform>(); ClassDB::register_class<VisualShaderNodeTransformUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>(); - ClassDB::register_class<VisualShaderNodeCubeMapUniform>(); + ClassDB::register_class<VisualShaderNodeCubemapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); ClassDB::register_class<VisualShaderNodeScalarSwitch>(); @@ -616,9 +626,11 @@ void register_scene_types() { ClassDB::register_class<SphereMesh>(); ClassDB::register_class<PointMesh>(); ClassDB::register_virtual_class<Material>(); - ClassDB::register_class<SpatialMaterial>(); - SceneTree::add_idle_callback(SpatialMaterial::flush_changes); - SpatialMaterial::init_shaders(); + ClassDB::register_virtual_class<BaseMaterial3D>(); + ClassDB::register_class<StandardMaterial3D>(); + ClassDB::register_class<ORMMaterial3D>(); + SceneTree::add_idle_callback(BaseMaterial3D::flush_changes); + BaseMaterial3D::init_shaders(); ClassDB::register_class<MeshLibrary>(); @@ -631,7 +643,7 @@ void register_scene_types() { ClassDB::register_class<CapsuleShape>(); ClassDB::register_class<CylinderShape>(); ClassDB::register_class<HeightMapShape>(); - ClassDB::register_class<PlaneShape>(); + ClassDB::register_class<WorldMarginShape>(); ClassDB::register_class<ConvexPolygonShape>(); ClassDB::register_class<ConcavePolygonShape>(); @@ -643,8 +655,10 @@ void register_scene_types() { ClassDB::register_class<PhysicsMaterial>(); ClassDB::register_class<World>(); ClassDB::register_class<Environment>(); + ClassDB::register_class<CameraEffects>(); ClassDB::register_class<World2D>(); ClassDB::register_virtual_class<Texture>(); + ClassDB::register_virtual_class<Texture2D>(); ClassDB::register_virtual_class<Sky>(); ClassDB::register_class<PanoramaSky>(); ClassDB::register_class<ProceduralSky>(); @@ -658,10 +672,10 @@ void register_scene_types() { ClassDB::register_class<ProxyTexture>(); ClassDB::register_class<AnimatedTexture>(); ClassDB::register_class<CameraTexture>(); - ClassDB::register_class<CubeMap>(); ClassDB::register_virtual_class<TextureLayered>(); - ClassDB::register_class<Texture3D>(); - ClassDB::register_class<TextureArray>(); + ClassDB::register_class<Cubemap>(); + ClassDB::register_class<CubemapArray>(); + ClassDB::register_class<Texture2DArray>(); ClassDB::register_class<Animation>(); ClassDB::register_virtual_class<Font>(); ClassDB::register_class<BitmapFont>(); @@ -712,7 +726,9 @@ void register_scene_types() { ClassDB::register_class<Navigation2D>(); ClassDB::register_class<NavigationPolygon>(); - ClassDB::register_class<NavigationPolygonInstance>(); + ClassDB::register_class<NavigationRegion2D>(); + ClassDB::register_class<NavigationAgent2D>(); + ClassDB::register_class<NavigationObstacle2D>(); OS::get_singleton()->yield(); //may take time to init @@ -723,10 +739,16 @@ void register_scene_types() { ClassDB::register_virtual_class<SceneTreeTimer>(); //sorry, you can't create it #ifndef DISABLE_DEPRECATED - ClassDB::add_compatibility_class("ImageSkyBox", "PanoramaSky"); - ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial"); + ClassDB::add_compatibility_class("SpatialMaterial", "StandardMaterial3D"); ClassDB::add_compatibility_class("Mesh", "ArrayMesh"); - + ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); + ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion"); + ClassDB::add_compatibility_class("NavigationPolygonInstance", "NavigationRegion2D"); + ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape"); #endif OS::get_singleton()->yield(); //may take time to init @@ -767,10 +789,12 @@ void register_scene_types() { ERR_PRINT("Error loading custom theme '" + theme_path + "'"); } } + SceneDebugger::initialize(); } void unregister_scene_types() { + SceneDebugger::deinitialize(); clear_default_theme(); ResourceLoader::remove_resource_format_loader(resource_loader_dynamic_font); @@ -799,9 +823,9 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_bmfont); resource_loader_bmfont.unref(); - //SpatialMaterial is not initialised when 3D is disabled, so it shouldn't be cleaned up either + //StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either #ifndef _3D_DISABLED - SpatialMaterial::finish_shaders(); + BaseMaterial3D::finish_shaders(); #endif // _3D_DISABLED ParticlesMaterial::finish_shaders(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 91d1e32053..ba1f738115 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -91,11 +91,11 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (track_get_type(track) == TYPE_TRANSFORM) { TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]); - PoolVector<float> values = p_value; + Vector<float> values = p_value; int vcount = values.size(); ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 11 - PoolVector<float>::Read r = values.read(); + const float *r = values.ptr(); tt->transforms.resize(vcount / 12); @@ -140,7 +140,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { vt->update_mode = UpdateMode(um); } - PoolVector<float> times = d["times"]; + Vector<float> times = d["times"]; Array values = d["values"]; ERR_FAIL_COND_V(times.size() != values.size(), false); @@ -149,7 +149,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int valcount = times.size(); - PoolVector<float>::Read rt = times.read(); + const float *rt = times.ptr(); vt->values.resize(valcount); @@ -161,10 +161,10 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (d.has("transitions")) { - PoolVector<float> transitions = d["transitions"]; + Vector<float> transitions = d["transitions"]; ERR_FAIL_COND_V(transitions.size() != valcount, false); - PoolVector<float>::Read rtr = transitions.read(); + const float *rtr = transitions.ptr(); for (int i = 0; i < valcount; i++) { @@ -184,7 +184,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("values"), false); - PoolVector<float> times = d["times"]; + Vector<float> times = d["times"]; Array values = d["values"]; ERR_FAIL_COND_V(times.size() != values.size(), false); @@ -193,7 +193,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int valcount = times.size(); - PoolVector<float>::Read rt = times.read(); + const float *rt = times.ptr(); for (int i = 0; i < valcount; i++) { @@ -202,10 +202,10 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { if (d.has("transitions")) { - PoolVector<float> transitions = d["transitions"]; + Vector<float> transitions = d["transitions"]; ERR_FAIL_COND_V(transitions.size() != valcount, false); - PoolVector<float>::Read rtr = transitions.read(); + const float *rtr = transitions.ptr(); for (int i = 0; i < valcount; i++) { @@ -220,8 +220,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("points"), false); - PoolVector<float> times = d["times"]; - PoolRealArray values = d["points"]; + Vector<float> times = d["times"]; + PackedFloat32Array values = d["points"]; ERR_FAIL_COND_V(times.size() * 5 != values.size(), false); @@ -229,8 +229,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int valcount = times.size(); - PoolVector<float>::Read rt = times.read(); - PoolVector<float>::Read rv = values.read(); + const float *rt = times.ptr(); + const float *rv = values.ptr(); bt->values.resize(valcount); @@ -254,7 +254,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("clips"), false); - PoolVector<float> times = d["times"]; + Vector<float> times = d["times"]; Array clips = d["clips"]; ERR_FAIL_COND_V(clips.size() != times.size(), false); @@ -263,7 +263,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int valcount = times.size(); - PoolVector<float>::Read rt = times.read(); + const float *rt = times.ptr(); ad->values.clear(); @@ -295,8 +295,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("times"), false); ERR_FAIL_COND_V(!d.has("clips"), false); - PoolVector<float> times = d["times"]; - PoolVector<String> clips = d["clips"]; + Vector<float> times = d["times"]; + Vector<String> clips = d["clips"]; ERR_FAIL_COND_V(clips.size() != times.size(), false); @@ -304,8 +304,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { int valcount = times.size(); - PoolVector<float>::Read rt = times.read(); - PoolVector<String>::Read rc = clips.read(); + const float *rt = times.ptr(); + const String *rc = clips.ptr(); an->values.resize(valcount); @@ -373,11 +373,11 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { if (track_get_type(track) == TYPE_TRANSFORM) { - PoolVector<real_t> keys; + Vector<float> keys; int kk = track_get_key_count(track); keys.resize(kk * 12); - PoolVector<real_t>::Write w = keys.write(); + real_t *w = keys.ptrw(); int idx = 0; for (int i = 0; i < track_get_key_count(track); i++) { @@ -403,7 +403,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { w[idx++] = scale.z; } - w.release(); r_ret = keys; return true; @@ -413,8 +412,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - PoolVector<float> key_times; - PoolVector<float> key_transitions; + Vector<float> key_times; + Vector<float> key_transitions; Array key_values; int kk = vt->values.size(); @@ -423,8 +422,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { key_transitions.resize(kk); key_values.resize(kk); - PoolVector<float>::Write wti = key_times.write(); - PoolVector<float>::Write wtr = key_transitions.write(); + float *wti = key_times.ptrw(); + float *wtr = key_transitions.ptrw(); int idx = 0; @@ -438,9 +437,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti.release(); - wtr.release(); - d["times"] = key_times; d["transitions"] = key_transitions; d["values"] = key_values; @@ -456,8 +452,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - PoolVector<float> key_times; - PoolVector<float> key_transitions; + Vector<float> key_times; + Vector<float> key_transitions; Array key_values; int kk = track_get_key_count(track); @@ -466,8 +462,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { key_transitions.resize(kk); key_values.resize(kk); - PoolVector<float>::Write wti = key_times.write(); - PoolVector<float>::Write wtr = key_transitions.write(); + float *wti = key_times.ptrw(); + float *wtr = key_transitions.ptrw(); int idx = 0; for (int i = 0; i < track_get_key_count(track); i++) { @@ -478,9 +474,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti.release(); - wtr.release(); - d["times"] = key_times; d["transitions"] = key_transitions; d["values"] = key_values; @@ -497,16 +490,16 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - PoolVector<float> key_times; - PoolVector<float> key_points; + Vector<float> key_times; + Vector<float> key_points; int kk = bt->values.size(); key_times.resize(kk); key_points.resize(kk * 5); - PoolVector<float>::Write wti = key_times.write(); - PoolVector<float>::Write wpo = key_points.write(); + float *wti = key_times.ptrw(); + float *wpo = key_points.ptrw(); int idx = 0; @@ -523,9 +516,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti.release(); - wpo.release(); - d["times"] = key_times; d["points"] = key_points; @@ -538,14 +528,14 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - PoolVector<float> key_times; + Vector<float> key_times; Array clips; int kk = ad->values.size(); key_times.resize(kk); - PoolVector<float>::Write wti = key_times.write(); + float *wti = key_times.ptrw(); int idx = 0; @@ -562,8 +552,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti.release(); - d["times"] = key_times; d["clips"] = clips; @@ -576,16 +564,16 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { Dictionary d; - PoolVector<float> key_times; - PoolVector<String> clips; + Vector<float> key_times; + Vector<String> clips; int kk = an->values.size(); key_times.resize(kk); clips.resize(kk); - PoolVector<float>::Write wti = key_times.write(); - PoolVector<String>::Write wcl = clips.write(); + float *wti = key_times.ptrw(); + String *wcl = clips.ptrw(); const TKey<StringName> *vls = an->values.ptr(); @@ -595,9 +583,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { wcl[i] = vls[i].value; } - wti.release(); - wcl.release(); - d["times"] = key_times; d["clips"] = clips; @@ -1063,7 +1048,7 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY); Dictionary d = p_key; - ERR_FAIL_COND(!d.has("method") || d["method"].get_type() != Variant::STRING); + 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()); MethodKey k; @@ -1635,7 +1620,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a vformat |= 1 << type_pa; vformat |= 1 << type_pb; - if (vformat == ((1 << Variant::INT) | (1 << Variant::REAL)) || vformat == (1 << Variant::REAL)) { + if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) { //mix of real and int real_t p0 = p_pre_a; @@ -2825,9 +2810,9 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("clear"), &Animation::clear); ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step"); ADD_SIGNAL(MethodInfo("tracks_changed")); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 6ac0ea04d9..ea4f92878d 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -242,11 +242,11 @@ private: return ret; } - PoolVector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const { + Vector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const { List<int> idxs; value_track_get_key_indices(p_track, p_time, p_delta, &idxs); - PoolVector<int> idxr; + Vector<int> idxr; for (List<int>::Element *E = idxs.front(); E; E = E->next()) { @@ -254,11 +254,11 @@ private: } return idxr; } - PoolVector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const { + Vector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const { List<int> idxs; method_track_get_key_indices(p_track, p_time, p_delta, &idxs); - PoolVector<int> idxr; + Vector<int> idxr; for (List<int>::Element *E = idxs.front(); E; E = E->next()) { diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index a412d8a5e2..ed25729c40 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -477,7 +477,7 @@ float AudioStreamSample::get_length() const { return float(len) / mix_rate; } -void AudioStreamSample::set_data(const PoolVector<uint8_t> &p_data) { +void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->lock(); if (data) { @@ -489,28 +489,28 @@ void AudioStreamSample::set_data(const PoolVector<uint8_t> &p_data) { int datalen = p_data.size(); if (datalen) { - PoolVector<uint8_t>::Read r = p_data.read(); + const uint8_t *r = p_data.ptr(); int alloc_len = datalen + DATA_PAD * 2; data = AudioServer::get_singleton()->audio_data_alloc(alloc_len); //alloc with some padding for interpolation zeromem(data, alloc_len); uint8_t *dataptr = (uint8_t *)data; - copymem(dataptr + DATA_PAD, r.ptr(), datalen); + copymem(dataptr + DATA_PAD, r, datalen); data_bytes = datalen; } AudioServer::get_singleton()->unlock(); } -PoolVector<uint8_t> AudioStreamSample::get_data() const { +Vector<uint8_t> AudioStreamSample::get_data() const { - PoolVector<uint8_t> pv; + Vector<uint8_t> pv; if (data) { pv.resize(data_bytes); { - PoolVector<uint8_t>::Write w = pv.write(); + uint8_t *w = pv.ptrw(); uint8_t *dataptr = (uint8_t *)data; - copymem(w.ptr(), dataptr + DATA_PAD, data_bytes); + copymem(w, dataptr + DATA_PAD, data_bytes); } } @@ -566,8 +566,8 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { file->store_32(sub_chunk_2_size); //Subchunk2Size // Add data - PoolVector<uint8_t> data = get_data(); - PoolVector<uint8_t>::Read read_data = data.read(); + Vector<uint8_t> data = get_data(); + const uint8_t *read_data = data.ptr(); switch (format) { case AudioStreamSample::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { @@ -629,7 +629,7 @@ void AudioStreamSample::_bind_methods() { ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav); - ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format"); ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "Disabled,Forward,Ping-Pong,Backward"), "set_loop_mode", "get_loop_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_begin"), "set_loop_begin", "get_loop_begin"); diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index adcac14ea8..0b46bc1c75 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -138,8 +138,8 @@ public: virtual float get_length() const; //if supported, otherwise return 0 - void set_data(const PoolVector<uint8_t> &p_data); - PoolVector<uint8_t> get_data() const; + void set_data(const Vector<uint8_t> &p_data); + Vector<uint8_t> get_data() const; Error save_to_wav(const String &p_path); diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index 06323a8d31..6730f86e0c 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -52,7 +52,7 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol create(Size2(img->get_width(), img->get_height())); - PoolVector<uint8_t>::Read r = img->get_data().read(); + const uint8_t *r = img->get_data().ptr(); uint8_t *w = bitmask.ptrw(); for (int i = 0; i < width * height; i++) { @@ -426,7 +426,7 @@ struct FillBitsStackEntry { static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) { // Using a custom stack to work iteratively to avoid stack overflow on big bitmaps - PoolVector<FillBitsStackEntry> stack; + Vector<FillBitsStackEntry> stack; // Tracking size since we won't be shrinking the stack vector int stack_size = 0; @@ -601,11 +601,11 @@ Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) con const Vector<Vector2> &polygon = result[i]; - PoolVector2Array polygon_array; + PackedVector2Array polygon_array; polygon_array.resize(polygon.size()); { - PoolVector2Array::Write w = polygon_array.write(); + Vector2 *w = polygon_array.ptrw(); for (int j = 0; j < polygon.size(); j++) { w[j] = polygon[j]; } @@ -640,15 +640,13 @@ Ref<Image> BitMap::convert_to_image() const { Ref<Image> image; image.instance(); image->create(width, height, false, Image::FORMAT_L8); - image->lock(); + for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { image->set_pixel(i, j, get_bit(Point2(i, j)) ? Color(1, 1, 1) : Color(0, 0, 0)); } } - image->unlock(); - return image; } void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) { diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index dee3943b8e..e1f485bae6 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -48,6 +48,10 @@ Vector<Vector3> BoxShape::get_debug_mesh_lines() { return lines; } +real_t BoxShape::get_enclosing_radius() const { + return extents.length(); +} + void BoxShape::_update_shape() { PhysicsServer::get_singleton()->shape_set_data(get_shape(), extents); diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h index b577a70e1e..fb164cc300 100644 --- a/scene/resources/box_shape.h +++ b/scene/resources/box_shape.h @@ -48,6 +48,7 @@ public: Vector3 get_extents() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; BoxShape(); }; diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp index 61331a336d..dddbd7fef3 100644 --- a/scene/resources/capsule_shape.cpp +++ b/scene/resources/capsule_shape.cpp @@ -38,7 +38,7 @@ Vector<Vector3> CapsuleShape::get_debug_mesh_lines() { Vector<Vector3> points; - Vector3 d(0, 0, height * 0.5); + Vector3 d(0, height * 0.5, 0); for (int i = 0; i < 360; i++) { float ra = Math::deg2rad((float)i); @@ -46,29 +46,33 @@ Vector<Vector3> CapsuleShape::get_debug_mesh_lines() { Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; - points.push_back(Vector3(a.x, a.y, 0) + d); - points.push_back(Vector3(b.x, b.y, 0) + d); + points.push_back(Vector3(a.x, 0, a.y) + d); + points.push_back(Vector3(b.x, 0, b.y) + d); - points.push_back(Vector3(a.x, a.y, 0) - d); - points.push_back(Vector3(b.x, b.y, 0) - d); + points.push_back(Vector3(a.x, 0, a.y) - d); + points.push_back(Vector3(b.x, 0, b.y) - d); if (i % 90 == 0) { - points.push_back(Vector3(a.x, a.y, 0) + d); - points.push_back(Vector3(a.x, a.y, 0) - d); + points.push_back(Vector3(a.x, 0, a.y) + d); + points.push_back(Vector3(a.x, 0, a.y) - d); } Vector3 dud = i < 180 ? d : -d; - points.push_back(Vector3(0, a.y, a.x) + dud); - points.push_back(Vector3(0, b.y, b.x) + dud); - points.push_back(Vector3(a.y, 0, a.x) + dud); - points.push_back(Vector3(b.y, 0, b.x) + dud); + points.push_back(Vector3(0, a.x, a.y) + dud); + points.push_back(Vector3(0, b.x, b.y) + dud); + points.push_back(Vector3(a.y, a.x, 0) + dud); + points.push_back(Vector3(b.y, b.x, 0) + dud); } return points; } +real_t CapsuleShape::get_enclosing_radius() const { + return radius + height * 0.5; +} + void CapsuleShape::_update_shape() { Dictionary d; @@ -111,8 +115,8 @@ void CapsuleShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape::get_height); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height"); } CapsuleShape::CapsuleShape() : diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h index 8e7d7bcb94..f097e51175 100644 --- a/scene/resources/capsule_shape.h +++ b/scene/resources/capsule_shape.h @@ -51,6 +51,7 @@ public: float get_height() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; CapsuleShape(); }; diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp index 008e8bb13d..9b8083de97 100644 --- a/scene/resources/capsule_shape_2d.cpp +++ b/scene/resources/capsule_shape_2d.cpp @@ -97,6 +97,10 @@ Rect2 CapsuleShape2D::get_rect() const { return rect; } +real_t CapsuleShape2D::get_enclosing_radius() const { + return radius + height * 0.5; +} + void CapsuleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius); @@ -105,8 +109,8 @@ void CapsuleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height"), "set_height", "get_height"); } CapsuleShape2D::CapsuleShape2D() : diff --git a/scene/resources/capsule_shape_2d.h b/scene/resources/capsule_shape_2d.h index 8398fab839..fe401a610c 100644 --- a/scene/resources/capsule_shape_2d.h +++ b/scene/resources/capsule_shape_2d.h @@ -56,6 +56,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; CapsuleShape2D(); }; diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp index 7142309e28..37874e17ef 100644 --- a/scene/resources/circle_shape_2d.cpp +++ b/scene/resources/circle_shape_2d.cpp @@ -60,7 +60,7 @@ void CircleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CircleShape2D::set_radius); ClassDB::bind_method(D_METHOD("get_radius"), &CircleShape2D::get_radius); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,16384,0.5"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,16384,0.5"), "set_radius", "get_radius"); } Rect2 CircleShape2D::get_rect() const { @@ -70,6 +70,10 @@ Rect2 CircleShape2D::get_rect() const { return rect; } +real_t CircleShape2D::get_enclosing_radius() const { + return radius; +} + void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector<Vector2> points; diff --git a/scene/resources/circle_shape_2d.h b/scene/resources/circle_shape_2d.h index cafd291f13..8b064f4d9f 100644 --- a/scene/resources/circle_shape_2d.h +++ b/scene/resources/circle_shape_2d.h @@ -50,6 +50,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; CircleShape2D(); }; diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp index 48cc08eae4..fe123a2df7 100644 --- a/scene/resources/concave_polygon_shape.cpp +++ b/scene/resources/concave_polygon_shape.cpp @@ -36,11 +36,11 @@ Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() { Set<DrawEdge> edges; - PoolVector<Vector3> data = get_faces(); + Vector<Vector3> data = get_faces(); int datalen = data.size(); ERR_FAIL_COND_V((datalen % 3) != 0, Vector<Vector3>()); - PoolVector<Vector3>::Read r = data.read(); + const Vector3 *r = data.ptr(); for (int i = 0; i < datalen; i += 3) { @@ -64,17 +64,27 @@ Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() { return points; } +real_t ConcavePolygonShape::get_enclosing_radius() const { + Vector<Vector3> data = get_faces(); + const Vector3 *read = data.ptr(); + real_t r = 0; + for (int i(0); i < data.size(); i++) { + r = MAX(read[i].length_squared(), r); + } + return Math::sqrt(r); +} + void ConcavePolygonShape::_update_shape() { Shape::_update_shape(); } -void ConcavePolygonShape::set_faces(const PoolVector<Vector3> &p_faces) { +void ConcavePolygonShape::set_faces(const Vector<Vector3> &p_faces) { PhysicsServer::get_singleton()->shape_set_data(get_shape(), p_faces); notify_change_to_owners(); } -PoolVector<Vector3> ConcavePolygonShape::get_faces() const { +Vector<Vector3> ConcavePolygonShape::get_faces() const { return PhysicsServer::get_singleton()->shape_get_data(get_shape()); } @@ -83,7 +93,7 @@ void ConcavePolygonShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape::set_faces); ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces"); } ConcavePolygonShape::ConcavePolygonShape() : diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h index 5e371954d4..63aabb27d7 100644 --- a/scene/resources/concave_polygon_shape.h +++ b/scene/resources/concave_polygon_shape.h @@ -63,10 +63,11 @@ protected: virtual void _update_shape(); public: - void set_faces(const PoolVector<Vector3> &p_faces); - PoolVector<Vector3> get_faces() const; + void set_faces(const Vector<Vector3> &p_faces); + Vector<Vector3> get_faces() const; - Vector<Vector3> get_debug_mesh_lines(); + virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; ConcavePolygonShape(); }; diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp index 640f395158..c3e9e19721 100644 --- a/scene/resources/concave_polygon_shape_2d.cpp +++ b/scene/resources/concave_polygon_shape_2d.cpp @@ -35,12 +35,12 @@ bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { - PoolVector<Vector2> s = get_segments(); + Vector<Vector2> s = get_segments(); int len = s.size(); if (len == 0 || (len % 2) == 1) return false; - PoolVector<Vector2>::Read r = s.read(); + const Vector2 *r = s.ptr(); for (int i = 0; i < len; i += 2) { Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, &r[i]); if (p_point.distance_to(closest) < p_tolerance) @@ -50,25 +50,25 @@ bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, do return false; } -void ConcavePolygonShape2D::set_segments(const PoolVector<Vector2> &p_segments) { +void ConcavePolygonShape2D::set_segments(const Vector<Vector2> &p_segments) { Physics2DServer::get_singleton()->shape_set_data(get_rid(), p_segments); emit_changed(); } -PoolVector<Vector2> ConcavePolygonShape2D::get_segments() const { +Vector<Vector2> ConcavePolygonShape2D::get_segments() const { return Physics2DServer::get_singleton()->shape_get_data(get_rid()); } void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) { - PoolVector<Vector2> s = get_segments(); + Vector<Vector2> s = get_segments(); int len = s.size(); if (len == 0 || (len % 2) == 1) return; - PoolVector<Vector2>::Read r = s.read(); + const Vector2 *r = s.ptr(); for (int i = 0; i < len; i += 2) { VisualServer::get_singleton()->canvas_item_add_line(p_to_rid, r[i], r[i + 1], p_color, 2); } @@ -76,14 +76,14 @@ void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) { Rect2 ConcavePolygonShape2D::get_rect() const { - PoolVector<Vector2> s = get_segments(); + Vector<Vector2> s = get_segments(); int len = s.size(); if (len == 0) return Rect2(); Rect2 rect; - PoolVector<Vector2>::Read r = s.read(); + const Vector2 *r = s.ptr(); for (int i = 0; i < len; i++) { if (i == 0) rect.position = r[i]; @@ -94,16 +94,26 @@ Rect2 ConcavePolygonShape2D::get_rect() const { return rect; } +real_t ConcavePolygonShape2D::get_enclosing_radius() const { + Vector<Vector2> data = get_segments(); + const Vector2 *read = data.ptr(); + real_t r = 0; + for (int i(0); i < data.size(); i++) { + r = MAX(read[i].length_squared(), r); + } + return Math::sqrt(r); +} + void ConcavePolygonShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_segments", "segments"), &ConcavePolygonShape2D::set_segments); ClassDB::bind_method(D_METHOD("get_segments"), &ConcavePolygonShape2D::get_segments); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments"); } ConcavePolygonShape2D::ConcavePolygonShape2D() : Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) { - PoolVector<Vector2> empty; + Vector<Vector2> empty; set_segments(empty); } diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h index b95ed100e7..f89995567e 100644 --- a/scene/resources/concave_polygon_shape_2d.h +++ b/scene/resources/concave_polygon_shape_2d.h @@ -42,11 +42,12 @@ protected: public: virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; - void set_segments(const PoolVector<Vector2> &p_segments); - PoolVector<Vector2> get_segments() const; + void set_segments(const Vector<Vector2> &p_segments); + Vector<Vector2> get_segments() const; virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; ConcavePolygonShape2D(); }; diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index 1498eb4af9..b7463605b4 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -34,7 +34,7 @@ Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() { - PoolVector<Vector3> points = get_points(); + Vector<Vector3> points = get_points(); if (points.size() > 3) { @@ -55,20 +55,30 @@ Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() { return Vector<Vector3>(); } +real_t ConvexPolygonShape::get_enclosing_radius() const { + Vector<Vector3> data = get_points(); + const Vector3 *read = data.ptr(); + real_t r = 0; + for (int i(0); i < data.size(); i++) { + r = MAX(read[i].length_squared(), r); + } + return Math::sqrt(r); +} + void ConvexPolygonShape::_update_shape() { PhysicsServer::get_singleton()->shape_set_data(get_shape(), points); Shape::_update_shape(); } -void ConvexPolygonShape::set_points(const PoolVector<Vector3> &p_points) { +void ConvexPolygonShape::set_points(const Vector<Vector3> &p_points) { points = p_points; _update_shape(); notify_change_to_owners(); } -PoolVector<Vector3> ConvexPolygonShape::get_points() const { +Vector<Vector3> ConvexPolygonShape::get_points() const { return points; } diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h index 4725d09b26..fcd733887e 100644 --- a/scene/resources/convex_polygon_shape.h +++ b/scene/resources/convex_polygon_shape.h @@ -36,7 +36,7 @@ class ConvexPolygonShape : public Shape { GDCLASS(ConvexPolygonShape, Shape); - PoolVector<Vector3> points; + Vector<Vector3> points; protected: static void _bind_methods(); @@ -44,10 +44,11 @@ protected: virtual void _update_shape(); public: - void set_points(const PoolVector<Vector3> &p_points); - PoolVector<Vector3> get_points() const; + void set_points(const Vector<Vector3> &p_points); + Vector<Vector3> get_points() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; ConvexPolygonShape(); }; diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index c404190398..95967429c9 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -74,7 +74,7 @@ void ConvexPolygonShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape2D::set_points); ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape2D::get_points); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "points"), "set_points", "get_points"); } void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) { @@ -97,6 +97,14 @@ Rect2 ConvexPolygonShape2D::get_rect() const { return rect; } +real_t ConvexPolygonShape2D::get_enclosing_radius() const { + real_t r = 0; + for (int i(0); i < get_points().size(); i++) { + r = MAX(get_points()[i].length_squared(), r); + } + return Math::sqrt(r); +} + ConvexPolygonShape2D::ConvexPolygonShape2D() : Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) { } diff --git a/scene/resources/convex_polygon_shape_2d.h b/scene/resources/convex_polygon_shape_2d.h index ed6be738ab..83c250c0ce 100644 --- a/scene/resources/convex_polygon_shape_2d.h +++ b/scene/resources/convex_polygon_shape_2d.h @@ -51,6 +51,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; ConvexPolygonShape2D(); }; diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 397f6ca906..a68eb77378 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -392,7 +392,7 @@ void Curve::set_data(Array input) { for (int i = 0; i < input.size(); i += ELEMS) { ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2); ERR_FAIL_COND(!input[i + 1].is_num()); - ERR_FAIL_COND(input[i + 2].get_type() != Variant::REAL); + ERR_FAIL_COND(input[i + 2].get_type() != Variant::FLOAT); ERR_FAIL_COND(input[i + 3].get_type() != Variant::INT); int left_mode = input[i + 3]; @@ -524,8 +524,8 @@ void Curve::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_data"), &Curve::get_data); ClassDB::bind_method(D_METHOD("_set_data", "data"), &Curve::set_data); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "min_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_min_value", "get_min_value"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_min_value", "get_min_value"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_resolution", PROPERTY_HINT_RANGE, "1,1000,1"), "set_bake_resolution", "get_bake_resolution"); ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); @@ -741,7 +741,7 @@ void Curve2D::_bake() const { pointlist.push_back(lastpos); baked_point_cache.resize(pointlist.size()); - PoolVector2Array::Write w = baked_point_cache.write(); + Vector2 *w = baked_point_cache.ptrw(); int idx = 0; for (List<Vector2>::Element *E = pointlist.front(); E; E = E->next()) { @@ -771,7 +771,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { return baked_point_cache.get(0); int bpc = baked_point_cache.size(); - PoolVector2Array::Read r = baked_point_cache.read(); + const Vector2 *r = baked_point_cache.ptr(); if (p_offset < 0) return r[0]; @@ -800,7 +800,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { } } -PoolVector2Array Curve2D::get_baked_points() const { +PackedVector2Array Curve2D::get_baked_points() const { if (baked_cache_dirty) _bake(); @@ -833,7 +833,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { if (pc == 1) return baked_point_cache.get(0); - PoolVector2Array::Read r = baked_point_cache.read(); + const Vector2 *r = baked_point_cache.ptr(); Vector2 nearest; float nearest_dist = -1.0f; @@ -869,7 +869,7 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { if (pc == 1) return 0.0f; - PoolVector2Array::Read r = baked_point_cache.read(); + const Vector2 *r = baked_point_cache.ptr(); float nearest = 0.0f; float nearest_dist = -1.0f; @@ -899,9 +899,9 @@ Dictionary Curve2D::_get_data() const { Dictionary dc; - PoolVector2Array d; + PackedVector2Array d; d.resize(points.size() * 3); - PoolVector2Array::Write w = d.write(); + Vector2 *w = d.ptrw(); for (int i = 0; i < points.size(); i++) { @@ -910,8 +910,6 @@ Dictionary Curve2D::_get_data() const { w[i * 3 + 2] = points[i].pos; } - w = PoolVector2Array::Write(); - dc["points"] = d; return dc; @@ -920,11 +918,11 @@ void Curve2D::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("points")); - PoolVector2Array rp = p_data["points"]; + PackedVector2Array rp = p_data["points"]; int pc = rp.size(); ERR_FAIL_COND(pc % 3 != 0); points.resize(pc / 3); - PoolVector2Array::Read r = rp.read(); + const Vector2 *r = rp.ptr(); for (int i = 0; i < points.size(); i++) { @@ -936,9 +934,9 @@ void Curve2D::_set_data(const Dictionary &p_data) { baked_cache_dirty = true; } -PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const { +PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const { - PoolVector2Array tess; + PackedVector2Array tess; if (points.size() == 0) { return tess; @@ -956,7 +954,7 @@ PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const } tess.resize(pc); - PoolVector2Array::Write bpw = tess.write(); + Vector2 *bpw = tess.ptrw(); bpw[0] = points[0].pos; int pidx = 0; @@ -972,8 +970,6 @@ PoolVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const bpw[pidx] = points[i + 1].pos; } - bpw = PoolVector2Array::Write(); - return tess; } @@ -1005,7 +1001,7 @@ void Curve2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_data"), &Curve2D::_get_data); ClassDB::bind_method(D_METHOD("_set_data"), &Curve2D::_set_data); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval"); + 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_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); } @@ -1258,14 +1254,14 @@ void Curve3D::_bake() const { pointlist.push_back(Plane(lastpos, lastilt)); baked_point_cache.resize(pointlist.size()); - PoolVector3Array::Write w = baked_point_cache.write(); + Vector3 *w = baked_point_cache.ptrw(); int idx = 0; baked_tilt_cache.resize(pointlist.size()); - PoolRealArray::Write wt = baked_tilt_cache.write(); + real_t *wt = baked_tilt_cache.ptrw(); baked_up_vector_cache.resize(up_vector_enabled ? pointlist.size() : 0); - PoolVector3Array::Write up_write = baked_up_vector_cache.write(); + Vector3 *up_write = baked_up_vector_cache.ptrw(); Vector3 sideways; Vector3 up; @@ -1333,7 +1329,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { return baked_point_cache.get(0); int bpc = baked_point_cache.size(); - PoolVector3Array::Read r = baked_point_cache.read(); + const Vector3 *r = baked_point_cache.ptr(); if (p_offset < 0) return r[0]; @@ -1375,7 +1371,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { return baked_tilt_cache.get(0); int bpc = baked_tilt_cache.size(); - PoolRealArray::Read r = baked_tilt_cache.read(); + const real_t *r = baked_tilt_cache.ptr(); if (p_offset < 0) return r[0]; @@ -1410,9 +1406,9 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) if (count == 1) return baked_up_vector_cache.get(0); - PoolVector3Array::Read r = baked_up_vector_cache.read(); - PoolVector3Array::Read rp = baked_point_cache.read(); - PoolRealArray::Read rt = baked_tilt_cache.read(); + const Vector3 *r = baked_up_vector_cache.ptr(); + const Vector3 *rp = baked_point_cache.ptr(); + const real_t *rt = baked_tilt_cache.ptr(); float offset = CLAMP(p_offset, 0.0f, baked_max_ofs); @@ -1441,7 +1437,7 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) return up.rotated(axis, up.angle_to(up1) * frac); } -PoolVector3Array Curve3D::get_baked_points() const { +PackedVector3Array Curve3D::get_baked_points() const { if (baked_cache_dirty) _bake(); @@ -1449,7 +1445,7 @@ PoolVector3Array Curve3D::get_baked_points() const { return baked_point_cache; } -PoolRealArray Curve3D::get_baked_tilts() const { +PackedFloat32Array Curve3D::get_baked_tilts() const { if (baked_cache_dirty) _bake(); @@ -1457,7 +1453,7 @@ PoolRealArray Curve3D::get_baked_tilts() const { return baked_tilt_cache; } -PoolVector3Array Curve3D::get_baked_up_vectors() const { +PackedVector3Array Curve3D::get_baked_up_vectors() const { if (baked_cache_dirty) _bake(); @@ -1478,7 +1474,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { if (pc == 1) return baked_point_cache.get(0); - PoolVector3Array::Read r = baked_point_cache.read(); + const Vector3 *r = baked_point_cache.ptr(); Vector3 nearest; float nearest_dist = -1.0f; @@ -1514,7 +1510,7 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { if (pc == 1) return 0.0f; - PoolVector3Array::Read r = baked_point_cache.read(); + const Vector3 *r = baked_point_cache.ptr(); float nearest = 0.0f; float nearest_dist = -1.0f; @@ -1568,12 +1564,12 @@ Dictionary Curve3D::_get_data() const { Dictionary dc; - PoolVector3Array d; + PackedVector3Array d; d.resize(points.size() * 3); - PoolVector3Array::Write w = d.write(); - PoolRealArray t; + Vector3 *w = d.ptrw(); + PackedFloat32Array t; t.resize(points.size()); - PoolRealArray::Write wt = t.write(); + real_t *wt = t.ptrw(); for (int i = 0; i < points.size(); i++) { @@ -1583,9 +1579,6 @@ Dictionary Curve3D::_get_data() const { wt[i] = points[i].tilt; } - w = PoolVector3Array::Write(); - wt = PoolRealArray::Write(); - dc["points"] = d; dc["tilts"] = t; @@ -1596,13 +1589,13 @@ void Curve3D::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("points")); ERR_FAIL_COND(!p_data.has("tilts")); - PoolVector3Array rp = p_data["points"]; + PackedVector3Array rp = p_data["points"]; int pc = rp.size(); ERR_FAIL_COND(pc % 3 != 0); points.resize(pc / 3); - PoolVector3Array::Read r = rp.read(); - PoolRealArray rtl = p_data["tilts"]; - PoolRealArray::Read rt = rtl.read(); + const Vector3 *r = rp.ptr(); + PackedFloat32Array rtl = p_data["tilts"]; + const real_t *rt = rtl.ptr(); for (int i = 0; i < points.size(); i++) { @@ -1615,9 +1608,9 @@ void Curve3D::_set_data(const Dictionary &p_data) { baked_cache_dirty = true; } -PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const { +PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const { - PoolVector3Array tess; + PackedVector3Array tess; if (points.size() == 0) { return tess; @@ -1635,7 +1628,7 @@ PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const } tess.resize(pc); - PoolVector3Array::Write bpw = tess.write(); + Vector3 *bpw = tess.ptrw(); bpw[0] = points[0].pos; int pidx = 0; @@ -1651,8 +1644,6 @@ PoolVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const bpw[pidx] = points[i + 1].pos; } - bpw = PoolVector3Array::Write(); - return tess; } @@ -1691,7 +1682,7 @@ void Curve3D::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_data"), &Curve3D::_get_data); ClassDB::bind_method(D_METHOD("_set_data"), &Curve3D::_set_data); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval"); + 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_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); ADD_GROUP("Up Vector", "up_vector_"); diff --git a/scene/resources/curve.h b/scene/resources/curve.h index b02466534c..7dcbf1ceff 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -168,7 +168,7 @@ class Curve2D : public Resource { }; mutable bool baked_cache_dirty; - mutable PoolVector2Array baked_point_cache; + mutable PackedVector2Array baked_point_cache; mutable float baked_max_ofs; void _bake() const; @@ -202,11 +202,11 @@ public: float get_baked_length() const; Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const; - PoolVector2Array get_baked_points() const; //useful for going through + PackedVector2Array get_baked_points() const; //useful for going through Vector2 get_closest_point(const Vector2 &p_to_point) const; float get_closest_offset(const Vector2 &p_to_point) const; - PoolVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display + PackedVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display Curve2D(); }; @@ -234,9 +234,9 @@ class Curve3D : public Resource { }; mutable bool baked_cache_dirty; - mutable PoolVector3Array baked_point_cache; - mutable PoolRealArray baked_tilt_cache; - mutable PoolVector3Array baked_up_vector_cache; + mutable PackedVector3Array baked_point_cache; + mutable PackedFloat32Array baked_tilt_cache; + mutable PackedVector3Array baked_up_vector_cache; mutable float baked_max_ofs; void _bake() const; @@ -277,13 +277,13 @@ public: Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const; float interpolate_baked_tilt(float p_offset) const; Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const; - PoolVector3Array get_baked_points() const; //useful for going through - PoolRealArray get_baked_tilts() const; //useful for going through - PoolVector3Array get_baked_up_vectors() const; + PackedVector3Array get_baked_points() const; //useful for going through + PackedFloat32Array get_baked_tilts() const; //useful for going through + PackedVector3Array get_baked_up_vectors() const; Vector3 get_closest_point(const Vector3 &p_to_point) const; float get_closest_offset(const Vector3 &p_to_point) const; - PoolVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display + PackedVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display Curve3D(); }; diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape.cpp index d9f6e4f054..53d368d32a 100644 --- a/scene/resources/cylinder_shape.cpp +++ b/scene/resources/cylinder_shape.cpp @@ -62,6 +62,10 @@ Vector<Vector3> CylinderShape::get_debug_mesh_lines() { return points; } +real_t CylinderShape::get_enclosing_radius() const { + return Vector2(radius, height * 0.5).length(); +} + void CylinderShape::_update_shape() { Dictionary d; @@ -104,8 +108,8 @@ void CylinderShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderShape::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CylinderShape::get_height); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height"); } CylinderShape::CylinderShape() : diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape.h index ebddd4d92f..a26fda10cd 100644 --- a/scene/resources/cylinder_shape.h +++ b/scene/resources/cylinder_shape.h @@ -50,6 +50,7 @@ public: float get_height() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; CylinderShape(); }; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 00c56e5eb2..04bc95ade6 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -69,7 +69,7 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl img->resize(orig_size.x * scale, orig_size.y * scale); } - texture->create_from_image(img, ImageTexture::FLAG_FILTER); + texture->create_from_image(img); (*tex_cache)[p_src] = texture; } @@ -98,7 +98,7 @@ static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, } template <class T> -static Ref<Texture> make_icon(T p_src) { +static Ref<Texture2D> make_icon(T p_src) { Ref<ImageTexture> texture(memnew(ImageTexture)); Ref<Image> img = memnew(Image(p_src)); @@ -115,7 +115,7 @@ static Ref<Texture> make_icon(T p_src) { img->convert(Image::FORMAT_RGBA8); img->resize(orig_size.x * scale, orig_size.y * scale); } - texture->create_from_image(img, ImageTexture::FLAG_FILTER); + texture->create_from_image(img); return texture; } @@ -169,7 +169,7 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi return style; } -void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale) { +void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) { scale = p_scale; @@ -464,7 +464,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("completion_scroll_width", "TextEdit", 3); theme->set_constant("line_spacing", "TextEdit", 4 * scale); - Ref<Texture> empty_icon = memnew(ImageTexture); + Ref<Texture2D> empty_icon = memnew(ImageTexture); // HScrollBar @@ -706,9 +706,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color_disabled", "TabContainer", control_font_color_disabled); theme->set_constant("side_margin", "TabContainer", 8 * scale); - theme->set_constant("top_margin", "TabContainer", 24 * scale); - theme->set_constant("label_valign_fg", "TabContainer", 0 * scale); - theme->set_constant("label_valign_bg", "TabContainer", 2 * scale); theme->set_constant("hseparation", "TabContainer", 4 * scale); // Tabs @@ -732,9 +729,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color_bg", "Tabs", control_font_color_low); theme->set_color("font_color_disabled", "Tabs", control_font_color_disabled); - theme->set_constant("top_margin", "Tabs", 24 * scale); - theme->set_constant("label_valign_fg", "Tabs", 0 * scale); - theme->set_constant("label_valign_bg", "Tabs", 2 * scale); theme->set_constant("hseparation", "Tabs", 4 * scale); // Separators @@ -873,7 +867,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { t.instance(); Ref<StyleBox> default_style; - Ref<Texture> default_icon; + Ref<Texture2D> default_icon; Ref<Font> default_font; if (p_font.is_valid()) { default_font = p_font; diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 1807770ff4..46f89a9b50 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -33,7 +33,7 @@ #include "scene/resources/theme.h" -void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale); +void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale); void make_default_theme(bool p_hidpi, Ref<Font> p_font); void clear_default_theme(); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 451029e93b..ebd5b02dbc 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -222,11 +222,6 @@ Error DynamicFontAtSize::_load() { ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font; descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font; linegap = 0; - texture_flags = 0; - if (id.mipmaps) - texture_flags |= Texture::FLAG_MIPMAPS; - if (id.filter) - texture_flags |= Texture::FLAG_FILTER; valid = true; return OK; @@ -299,16 +294,6 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V return ret; } -void DynamicFontAtSize::set_texture_flags(uint32_t p_flags) { - - texture_flags = p_flags; - for (int i = 0; i < textures.size(); i++) { - Ref<ImageTexture> &tex = textures.write[i].texture; - if (!tex.is_null()) - tex->set_flags(p_flags); - } -} - float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize> > &p_fallbacks, bool p_advance_only, bool p_outline) const { if (!valid) @@ -351,7 +336,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT modulate.r = modulate.g = modulate.b = 1.0; } RID texture = font->textures[ch->texture_idx].texture->get_rid(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), false); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, ch->rect.size), texture, ch->rect_uv, modulate, false, RID(), RID(), Color(1, 1, 1, 1), false); } advance = ch->advance; @@ -457,7 +442,7 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp { //zero texture - PoolVector<uint8_t>::Write w = tex.imgdata.write(); + uint8_t *w = tex.imgdata.ptrw(); ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.imgdata.size(), ret); for (int i = 0; i < texsize * texsize * p_color_size; i++) { w[i] = 0; @@ -495,7 +480,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b CharTexture &tex = textures.write[tex_pos.index]; { - PoolVector<uint8_t>::Write wr = tex.imgdata.write(); + uint8_t *wr = tex.imgdata.ptrw(); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { @@ -536,9 +521,9 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b if (tex.texture.is_null()) { tex.texture.instance(); - tex.texture->create_from_image(img, Texture::FLAG_VIDEO_SURFACE | texture_flags); + tex.texture->create_from_image(img); } else { - tex.texture->set_data(img); //update + tex.texture->update(img); //update } } @@ -659,7 +644,6 @@ DynamicFontAtSize::DynamicFontAtSize() { ascent = 1; descent = 1; linegap = 1; - texture_flags = 0; oversampling = font_oversampling; scale_color_font = 1; } @@ -758,34 +742,6 @@ Color DynamicFont::get_outline_color() const { return outline_color; } -bool DynamicFont::get_use_mipmaps() const { - - return cache_id.mipmaps; -} - -void DynamicFont::set_use_mipmaps(bool p_enable) { - - if (cache_id.mipmaps == p_enable) - return; - cache_id.mipmaps = p_enable; - outline_cache_id.mipmaps = p_enable; - _reload_cache(); -} - -bool DynamicFont::get_use_filter() const { - - return cache_id.filter; -} - -void DynamicFont::set_use_filter(bool p_enable) { - - if (cache_id.filter == p_enable) - return; - cache_id.filter = p_enable; - outline_cache_id.filter = p_enable; - _reload_cache(); -} - bool DynamicFontData::is_antialiased() const { return antialiased; @@ -1007,10 +963,6 @@ void DynamicFont::_bind_methods() { ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &DynamicFont::set_outline_color); ClassDB::bind_method(D_METHOD("get_outline_color"), &DynamicFont::get_outline_color); - ClassDB::bind_method(D_METHOD("set_use_mipmaps", "enable"), &DynamicFont::set_use_mipmaps); - ClassDB::bind_method(D_METHOD("get_use_mipmaps"), &DynamicFont::get_use_mipmaps); - ClassDB::bind_method(D_METHOD("set_use_filter", "enable"), &DynamicFont::set_use_filter); - ClassDB::bind_method(D_METHOD("get_use_filter"), &DynamicFont::get_use_filter); ClassDB::bind_method(D_METHOD("set_spacing", "type", "value"), &DynamicFont::set_spacing); ClassDB::bind_method(D_METHOD("get_spacing", "type"), &DynamicFont::get_spacing); @@ -1024,8 +976,6 @@ void DynamicFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,1024,1"), "set_outline_size", "get_outline_size"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter"); ADD_GROUP("Extra Spacing", "extra_spacing"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_top"), "set_spacing", "get_spacing", SPACING_TOP); ADD_PROPERTYI(PropertyInfo(Variant::INT, "extra_spacing_bottom"), "set_spacing", "get_spacing", SPACING_BOTTOM); @@ -1040,7 +990,7 @@ void DynamicFont::_bind_methods() { BIND_ENUM_CONSTANT(SPACING_SPACE); } -Mutex *DynamicFont::dynamic_font_mutex = NULL; +Mutex DynamicFont::dynamic_font_mutex; SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL; @@ -1054,29 +1004,21 @@ DynamicFont::DynamicFont() : spacing_char = 0; spacing_space = 0; outline_color = Color(1, 1, 1); - if (dynamic_font_mutex) { - dynamic_font_mutex->lock(); - dynamic_fonts->add(&font_list); - dynamic_font_mutex->unlock(); - } + + MutexLock lock(dynamic_font_mutex); + dynamic_fonts->add(&font_list); } DynamicFont::~DynamicFont() { - if (dynamic_font_mutex) { - dynamic_font_mutex->lock(); - dynamic_fonts->remove(&font_list); - dynamic_font_mutex->unlock(); - } + MutexLock lock(dynamic_font_mutex); + dynamic_fonts->remove(&font_list); } void DynamicFont::initialize_dynamic_fonts() { dynamic_fonts = memnew(SelfList<DynamicFont>::List()); - dynamic_font_mutex = Mutex::create(); } void DynamicFont::finish_dynamic_fonts() { - memdelete(dynamic_font_mutex); - dynamic_font_mutex = NULL; memdelete(dynamic_fonts); dynamic_fonts = NULL; } @@ -1084,39 +1026,36 @@ void DynamicFont::finish_dynamic_fonts() { void DynamicFont::update_oversampling() { Vector<Ref<DynamicFont> > changed; + { + MutexLock lock(dynamic_font_mutex); - if (dynamic_font_mutex) - dynamic_font_mutex->lock(); - - SelfList<DynamicFont> *E = dynamic_fonts->first(); - while (E) { + SelfList<DynamicFont> *E = dynamic_fonts->first(); + while (E) { - if (E->self()->data_at_size.is_valid()) { - E->self()->data_at_size->update_oversampling(); + if (E->self()->data_at_size.is_valid()) { + E->self()->data_at_size->update_oversampling(); - if (E->self()->outline_data_at_size.is_valid()) { - E->self()->outline_data_at_size->update_oversampling(); - } + if (E->self()->outline_data_at_size.is_valid()) { + E->self()->outline_data_at_size->update_oversampling(); + } - for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) { - if (E->self()->fallback_data_at_size[i].is_valid()) { - E->self()->fallback_data_at_size.write[i]->update_oversampling(); + for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) { + if (E->self()->fallback_data_at_size[i].is_valid()) { + E->self()->fallback_data_at_size.write[i]->update_oversampling(); - if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) { - E->self()->fallback_outline_data_at_size.write[i]->update_oversampling(); + if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) { + E->self()->fallback_outline_data_at_size.write[i]->update_oversampling(); + } } } + + changed.push_back(Ref<DynamicFont>(E->self())); } - changed.push_back(Ref<DynamicFont>(E->self())); + E = E->next(); } - - E = E->next(); } - if (dynamic_font_mutex) - dynamic_font_mutex->unlock(); - for (int i = 0; i < changed.size(); i++) { changed.write[i]->emit_changed(); } @@ -1124,7 +1063,7 @@ void DynamicFont::update_oversampling() { ///////////////////////// -RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index 9170767512..c10f1e6681 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -56,9 +56,7 @@ public: struct { uint32_t size : 16; uint32_t outline_size : 8; - uint32_t mipmaps : 1; - uint32_t filter : 1; - uint32_t unused : 6; + uint32_t unused : 8; }; uint32_t key; }; @@ -127,13 +125,11 @@ class DynamicFontAtSize : public Reference { float oversampling; float scale_color_font; - uint32_t texture_flags; - bool valid; struct CharTexture { - PoolVector<uint8_t> imgdata; + Vector<uint8_t> imgdata; int texture_size; Vector<int> offsets; Ref<ImageTexture> texture; @@ -289,7 +285,7 @@ public: SelfList<DynamicFont> font_list; - static Mutex *dynamic_font_mutex; + static Mutex dynamic_font_mutex; static SelfList<DynamicFont>::List *dynamic_fonts; static void initialize_dynamic_fonts(); @@ -306,7 +302,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType); class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 7597cd636e..d407dd3722 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -61,25 +61,6 @@ void Environment::set_sky_custom_fov(float p_scale) { bg_sky_custom_fov = p_scale; VS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale); } -void Environment::set_sky_orientation(const Basis &p_orientation) { - - bg_sky_orientation = p_orientation; - _change_notify("background_sky_rotation"); - _change_notify("background_sky_rotation_degrees"); - VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation); -} -void Environment::set_sky_rotation(const Vector3 &p_euler_rad) { - - bg_sky_orientation.set_euler(p_euler_rad); - _change_notify("background_sky_orientation"); - _change_notify("background_sky_rotation_degrees"); - VS::get_singleton()->environment_set_sky_orientation(environment, bg_sky_orientation); -} -void Environment::set_sky_rotation_degrees(const Vector3 &p_euler_deg) { - - set_sky_rotation(p_euler_deg * Math_PI / 180.0); - _change_notify("background_sky_rotation"); -} void Environment::set_bg_color(const Color &p_color) { bg_color = p_color; @@ -98,24 +79,43 @@ void Environment::set_canvas_max_layer(int p_max_layer) { void Environment::set_ambient_light_color(const Color &p_color) { ambient_color = p_color; - VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution); + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); } void Environment::set_ambient_light_energy(float p_energy) { ambient_energy = p_energy; - VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution); + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); } void Environment::set_ambient_light_sky_contribution(float p_energy) { ambient_sky_contribution = p_energy; - VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution); + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); } void Environment::set_camera_feed_id(int p_camera_feed_id) { camera_feed_id = p_camera_feed_id; +// FIXME: Disabled during Vulkan refactoring, should be ported. +#if 0 VS::get_singleton()->environment_set_camera_feed_id(environment, camera_feed_id); +#endif }; +void Environment::set_ambient_source(AmbientSource p_source) { + ambient_source = p_source; + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); +} + +Environment::AmbientSource Environment::get_ambient_source() const { + return ambient_source; +} +void Environment::set_reflection_source(ReflectionSource p_source) { + reflection_source = p_source; + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); +} +Environment::ReflectionSource Environment::get_reflection_source() const { + return reflection_source; +} + Environment::BGMode Environment::get_background() const { return bg_mode; @@ -130,20 +130,14 @@ float Environment::get_sky_custom_fov() const { return bg_sky_custom_fov; } -Basis Environment::get_sky_orientation() const { - - return bg_sky_orientation; +void Environment::set_sky_rotation(const Vector3 &p_rotation) { + sky_rotation = p_rotation; + VS::get_singleton()->environment_set_sky_orientation(environment, Basis(p_rotation)); } Vector3 Environment::get_sky_rotation() const { - // should we cache this? maybe overkill - return bg_sky_orientation.get_euler(); -} - -Vector3 Environment::get_sky_rotation_degrees() const { - - return get_sky_rotation() * 180.0 / Math_PI; + return sky_rotation; } Color Environment::get_bg_color() const { @@ -300,26 +294,34 @@ float Environment::get_adjustment_saturation() const { return adjustment_saturation; } -void Environment::set_adjustment_color_correction(const Ref<Texture> &p_ramp) { +void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) { adjustment_color_correction = p_ramp; VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); } -Ref<Texture> Environment::get_adjustment_color_correction() const { +Ref<Texture2D> Environment::get_adjustment_color_correction() const { return adjustment_color_correction; } void Environment::_validate_property(PropertyInfo &property) const { - if (property.name == "background_sky" || property.name == "background_sky_custom_fov" || property.name == "background_sky_orientation" || property.name == "background_sky_rotation" || property.name == "background_sky_rotation_degrees" || property.name == "ambient_light/sky_contribution") { - if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) { + if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") { + if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) { property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } } + if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + + if (property.name == "glow_mix" && glow_blend_mode != GLOW_BLEND_MODE_MIX) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + if (property.name == "background_color") { - if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) { + if (bg_mode != BG_COLOR && ambient_source != AMBIENT_SOURCE_COLOR) { property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } } @@ -341,8 +343,6 @@ void Environment::_validate_property(PropertyInfo &property) const { "auto_exposure_", "ss_reflections_", "ssao_", - "dof_blur_far_", - "dof_blur_near_", "glow_", "adjustment_", NULL @@ -451,7 +451,7 @@ bool Environment::is_ssr_rough() const { void Environment::set_ssao_enabled(bool p_enable) { ssao_enabled = p_enable; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); _change_notify(); } @@ -463,7 +463,7 @@ bool Environment::is_ssao_enabled() const { void Environment::set_ssao_radius(float p_radius) { ssao_radius = p_radius; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_radius() const { @@ -473,7 +473,7 @@ float Environment::get_ssao_radius() const { void Environment::set_ssao_intensity(float p_intensity) { ssao_intensity = p_intensity; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_intensity() const { @@ -481,30 +481,10 @@ float Environment::get_ssao_intensity() const { return ssao_intensity; } -void Environment::set_ssao_radius2(float p_radius) { - - ssao_radius2 = p_radius; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); -} -float Environment::get_ssao_radius2() const { - - return ssao_radius2; -} - -void Environment::set_ssao_intensity2(float p_intensity) { - - ssao_intensity2 = p_intensity; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); -} -float Environment::get_ssao_intensity2() const { - - return ssao_intensity2; -} - void Environment::set_ssao_bias(float p_bias) { ssao_bias = p_bias; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_bias() const { @@ -514,7 +494,7 @@ float Environment::get_ssao_bias() const { void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) { ssao_direct_light_affect = p_direct_light_affect; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_direct_light_affect() const { @@ -524,49 +504,38 @@ float Environment::get_ssao_direct_light_affect() const { void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) { ssao_ao_channel_affect = p_ao_channel_affect; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_ao_channel_affect() const { return ssao_ao_channel_affect; } -void Environment::set_ssao_color(const Color &p_color) { +void Environment::set_ao_color(const Color &p_color) { - ssao_color = p_color; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + ao_color = p_color; + VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, VS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, VS::EnvironmentReflectionSource(reflection_source), ao_color); } -Color Environment::get_ssao_color() const { +Color Environment::get_ao_color() const { - return ssao_color; + return ao_color; } void Environment::set_ssao_blur(SSAOBlur p_blur) { ssao_blur = p_blur; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } Environment::SSAOBlur Environment::get_ssao_blur() const { return ssao_blur; } -void Environment::set_ssao_quality(SSAOQuality p_quality) { - - ssao_quality = p_quality; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); -} - -Environment::SSAOQuality Environment::get_ssao_quality() const { - - return ssao_quality; -} - void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) { ssao_edge_sharpness = p_edge_sharpness; - VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, ssao_color, VS::EnvironmentSSAOQuality(ssao_quality), VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); + VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, VS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness); } float Environment::get_ssao_edge_sharpness() const { @@ -577,7 +546,7 @@ float Environment::get_ssao_edge_sharpness() const { void Environment::set_glow_enabled(bool p_enabled) { glow_enabled = p_enabled; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); _change_notify(); } @@ -595,7 +564,7 @@ void Environment::set_glow_level(int p_level, bool p_enabled) { else glow_levels &= ~(1 << p_level); - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } bool Environment::is_glow_level_enabled(int p_level) const { @@ -608,7 +577,7 @@ void Environment::set_glow_intensity(float p_intensity) { glow_intensity = p_intensity; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_intensity() const { @@ -618,18 +587,28 @@ float Environment::get_glow_intensity() const { void Environment::set_glow_strength(float p_strength) { glow_strength = p_strength; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_strength() const { return glow_strength; } +void Environment::set_glow_mix(float p_mix) { + + glow_mix = p_mix; + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); +} +float Environment::get_glow_mix() const { + + return glow_mix; +} + void Environment::set_glow_bloom(float p_threshold) { glow_bloom = p_threshold; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_bloom() const { @@ -640,7 +619,8 @@ void Environment::set_glow_blend_mode(GlowBlendMode p_mode) { glow_blend_mode = p_mode; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + _change_notify(); } Environment::GlowBlendMode Environment::get_glow_blend_mode() const { @@ -651,7 +631,7 @@ void Environment::set_glow_hdr_bleed_threshold(float p_threshold) { glow_hdr_bleed_threshold = p_threshold; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_hdr_bleed_threshold() const { @@ -662,7 +642,7 @@ void Environment::set_glow_hdr_luminance_cap(float p_amount) { glow_hdr_luminance_cap = p_amount; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_hdr_luminance_cap() const { @@ -673,7 +653,7 @@ void Environment::set_glow_hdr_bleed_scale(float p_scale) { glow_hdr_bleed_scale = p_scale; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } float Environment::get_glow_hdr_bleed_scale() const { @@ -683,7 +663,7 @@ float Environment::get_glow_hdr_bleed_scale() const { void Environment::set_glow_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; - VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); + VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap, glow_bicubic_upscale); } bool Environment::is_glow_bicubic_upscale_enabled() const { @@ -691,115 +671,6 @@ bool Environment::is_glow_bicubic_upscale_enabled() const { return glow_bicubic_upscale; } -void Environment::set_dof_blur_far_enabled(bool p_enable) { - - dof_blur_far_enabled = p_enable; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); - _change_notify(); -} - -bool Environment::is_dof_blur_far_enabled() const { - - return dof_blur_far_enabled; -} - -void Environment::set_dof_blur_far_distance(float p_distance) { - - dof_blur_far_distance = p_distance; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_distance() const { - - return dof_blur_far_distance; -} - -void Environment::set_dof_blur_far_transition(float p_distance) { - - dof_blur_far_transition = p_distance; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_transition() const { - - return dof_blur_far_transition; -} - -void Environment::set_dof_blur_far_amount(float p_amount) { - - dof_blur_far_amount = p_amount; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} -float Environment::get_dof_blur_far_amount() const { - - return dof_blur_far_amount; -} - -void Environment::set_dof_blur_far_quality(DOFBlurQuality p_quality) { - - dof_blur_far_quality = p_quality; - VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality)); -} - -Environment::DOFBlurQuality Environment::get_dof_blur_far_quality() const { - - return dof_blur_far_quality; -} - -void Environment::set_dof_blur_near_enabled(bool p_enable) { - - dof_blur_near_enabled = p_enable; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); - _change_notify(); -} - -bool Environment::is_dof_blur_near_enabled() const { - - return dof_blur_near_enabled; -} - -void Environment::set_dof_blur_near_distance(float p_distance) { - - dof_blur_near_distance = p_distance; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_distance() const { - - return dof_blur_near_distance; -} - -void Environment::set_dof_blur_near_transition(float p_distance) { - - dof_blur_near_transition = p_distance; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_transition() const { - - return dof_blur_near_transition; -} - -void Environment::set_dof_blur_near_amount(float p_amount) { - - dof_blur_near_amount = p_amount; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -float Environment::get_dof_blur_near_amount() const { - - return dof_blur_near_amount; -} - -void Environment::set_dof_blur_near_quality(DOFBlurQuality p_quality) { - - dof_blur_near_quality = p_quality; - VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality)); -} - -Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const { - - return dof_blur_near_quality; -} - void Environment::set_fog_enabled(bool p_enabled) { fog_enabled = p_enabled; @@ -943,14 +814,31 @@ float Environment::get_fog_height_curve() const { return fog_height_curve; } +#ifndef DISABLE_DEPRECATED +// Kept for compatibility from 3.x to 4.0. +bool Environment::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "background_sky") { + set_sky(p_value); + return true; + } else if (p_name == "background_sky_custom_fov") { + set_sky_custom_fov(p_value); + return true; + } else if (p_name == "background_sky_orientation") { + Vector3 euler = p_value.operator Basis().get_euler(); + set_sky_rotation(euler); + return true; + } else { + return false; + } +} +#endif + void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background); ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky); ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov); - ClassDB::bind_method(D_METHOD("set_sky_orientation", "orientation"), &Environment::set_sky_orientation); ClassDB::bind_method(D_METHOD("set_sky_rotation", "euler_radians"), &Environment::set_sky_rotation); - ClassDB::bind_method(D_METHOD("set_sky_rotation_degrees", "euler_degrees"), &Environment::set_sky_rotation_degrees); ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color); ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy); ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer); @@ -958,13 +846,13 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy); ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution); ClassDB::bind_method(D_METHOD("set_camera_feed_id", "camera_feed_id"), &Environment::set_camera_feed_id); + ClassDB::bind_method(D_METHOD("set_ambient_source", "source"), &Environment::set_ambient_source); + ClassDB::bind_method(D_METHOD("set_reflection_source", "source"), &Environment::set_reflection_source); ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background); ClassDB::bind_method(D_METHOD("get_sky"), &Environment::get_sky); ClassDB::bind_method(D_METHOD("get_sky_custom_fov"), &Environment::get_sky_custom_fov); - ClassDB::bind_method(D_METHOD("get_sky_orientation"), &Environment::get_sky_orientation); ClassDB::bind_method(D_METHOD("get_sky_rotation"), &Environment::get_sky_rotation); - ClassDB::bind_method(D_METHOD("get_sky_rotation_degrees"), &Environment::get_sky_rotation_degrees); ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color); ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy); ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer); @@ -972,24 +860,29 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy); ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution); ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &Environment::get_camera_feed_id); + ClassDB::bind_method(D_METHOD("get_ambient_source"), &Environment::get_ambient_source); + ClassDB::bind_method(D_METHOD("get_reflection_source"), &Environment::get_reflection_source); + ClassDB::bind_method(D_METHOD("set_ao_color", "color"), &Environment::set_ao_color); + ClassDB::bind_method(D_METHOD("get_ao_color"), &Environment::get_ao_color); ADD_GROUP("Background", "background_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov"); - ADD_PROPERTY(PropertyInfo(Variant::BASIS, "background_sky_orientation"), "set_sky_orientation", "get_sky_orientation"); - // Only display rotation in degrees in the inspector (like in Spatial). - // This avoids displaying the same information twice. - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation", PROPERTY_HINT_NONE, "", 0), "set_sky_rotation", "get_sky_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "background_sky_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_sky_rotation_degrees", "get_sky_rotation_degrees"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep,Camera Feed"), "set_background", "get_background"); ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "background_camera_feed_id", PROPERTY_HINT_RANGE, "1,10,1"), "set_camera_feed_id", "get_camera_feed_id"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy"); + ADD_GROUP("Sky", "sky_"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_custom_fov", PROPERTY_HINT_RANGE, "0,180,0.1"), "set_sky_custom_fov", "get_sky_custom_fov"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "sky_rotation"), "set_sky_rotation", "get_sky_rotation"); ADD_GROUP("Ambient Light", "ambient_light_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Color,Sky"), "set_ambient_source", "get_ambient_source"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_occlusion_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ao_color", "get_ao_color"); + ADD_GROUP("Reflected Light", "reflected_light_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "reflected_light_source", PROPERTY_HINT_ENUM, "Background,Disabled,Sky"), "set_reflection_source", "get_reflection_source"); ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); @@ -1037,17 +930,17 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper); ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper); @@ -1075,14 +968,14 @@ void Environment::_bind_methods() { ADD_GROUP("Tonemap", "tonemap_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reinhard,Filmic,Aces"), "set_tonemapper", "get_tonemapper"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white"); ADD_GROUP("Auto Exposure", "auto_exposure_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed"); ClassDB::bind_method(D_METHOD("set_ssr_enabled", "enabled"), &Environment::set_ssr_enabled); ClassDB::bind_method(D_METHOD("is_ssr_enabled"), &Environment::is_ssr_enabled); @@ -1105,9 +998,9 @@ void Environment::_bind_methods() { ADD_GROUP("SS Reflections", "ss_reflections_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_roughness"), "set_ssr_rough", "is_ssr_rough"); ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled); @@ -1119,12 +1012,6 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ssao_intensity", "intensity"), &Environment::set_ssao_intensity); ClassDB::bind_method(D_METHOD("get_ssao_intensity"), &Environment::get_ssao_intensity); - ClassDB::bind_method(D_METHOD("set_ssao_radius2", "radius"), &Environment::set_ssao_radius2); - ClassDB::bind_method(D_METHOD("get_ssao_radius2"), &Environment::get_ssao_radius2); - - ClassDB::bind_method(D_METHOD("set_ssao_intensity2", "intensity"), &Environment::set_ssao_intensity2); - ClassDB::bind_method(D_METHOD("get_ssao_intensity2"), &Environment::get_ssao_intensity2); - ClassDB::bind_method(D_METHOD("set_ssao_bias", "bias"), &Environment::set_ssao_bias); ClassDB::bind_method(D_METHOD("get_ssao_bias"), &Environment::get_ssao_bias); @@ -1134,75 +1021,21 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ssao_ao_channel_affect", "amount"), &Environment::set_ssao_ao_channel_affect); ClassDB::bind_method(D_METHOD("get_ssao_ao_channel_affect"), &Environment::get_ssao_ao_channel_affect); - ClassDB::bind_method(D_METHOD("set_ssao_color", "color"), &Environment::set_ssao_color); - ClassDB::bind_method(D_METHOD("get_ssao_color"), &Environment::get_ssao_color); - ClassDB::bind_method(D_METHOD("set_ssao_blur", "mode"), &Environment::set_ssao_blur); ClassDB::bind_method(D_METHOD("get_ssao_blur"), &Environment::get_ssao_blur); - ClassDB::bind_method(D_METHOD("set_ssao_quality", "quality"), &Environment::set_ssao_quality); - ClassDB::bind_method(D_METHOD("get_ssao_quality"), &Environment::get_ssao_quality); - ClassDB::bind_method(D_METHOD("set_ssao_edge_sharpness", "edge_sharpness"), &Environment::set_ssao_edge_sharpness); ClassDB::bind_method(D_METHOD("get_ssao_edge_sharpness"), &Environment::get_ssao_edge_sharpness); ADD_GROUP("SSAO", "ssao_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_radius2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_radius2", "get_ssao_radius2"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_intensity2", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity2", "get_ssao_intensity2"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ssao_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ssao_color", "get_ssao_color"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_ssao_quality", "get_ssao_quality"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ssao_blur", PROPERTY_HINT_ENUM, "Disabled,1x1,2x2,3x3"), "set_ssao_blur", "get_ssao_blur"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness"); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &Environment::set_dof_blur_far_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &Environment::is_dof_blur_far_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &Environment::set_dof_blur_far_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &Environment::get_dof_blur_far_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &Environment::set_dof_blur_far_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &Environment::get_dof_blur_far_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_amount", "intensity"), &Environment::set_dof_blur_far_amount); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_amount"), &Environment::get_dof_blur_far_amount); - - ClassDB::bind_method(D_METHOD("set_dof_blur_far_quality", "intensity"), &Environment::set_dof_blur_far_quality); - ClassDB::bind_method(D_METHOD("get_dof_blur_far_quality"), &Environment::get_dof_blur_far_quality); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &Environment::set_dof_blur_near_enabled); - ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &Environment::is_dof_blur_near_enabled); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &Environment::set_dof_blur_near_distance); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &Environment::get_dof_blur_near_distance); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &Environment::set_dof_blur_near_transition); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &Environment::get_dof_blur_near_transition); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_amount", "intensity"), &Environment::set_dof_blur_near_amount); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_amount"), &Environment::get_dof_blur_near_amount); - - ClassDB::bind_method(D_METHOD("set_dof_blur_near_quality", "level"), &Environment::set_dof_blur_near_quality); - ClassDB::bind_method(D_METHOD("get_dof_blur_near_quality"), &Environment::get_dof_blur_near_quality); - - ADD_GROUP("DOF Far Blur", "dof_blur_far_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_far_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_far_amount", "get_dof_blur_far_amount"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_far_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_far_quality", "get_dof_blur_far_quality"); - - ADD_GROUP("DOF Near Blur", "dof_blur_near_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "dof_blur_near_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_near_amount", "get_dof_blur_near_amount"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dof_blur_near_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_dof_blur_near_quality", "get_dof_blur_near_quality"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_edge_sharpness", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_ssao_edge_sharpness", "get_ssao_edge_sharpness"); ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled); ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled); @@ -1216,6 +1049,9 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength); ClassDB::bind_method(D_METHOD("get_glow_strength"), &Environment::get_glow_strength); + ClassDB::bind_method(D_METHOD("set_glow_mix", "mix"), &Environment::set_glow_mix); + ClassDB::bind_method(D_METHOD("get_glow_mix"), &Environment::get_glow_mix); + ClassDB::bind_method(D_METHOD("set_glow_bloom", "amount"), &Environment::set_glow_bloom); ClassDB::bind_method(D_METHOD("get_glow_bloom"), &Environment::get_glow_bloom); @@ -1244,13 +1080,14 @@ void Environment::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level", "is_glow_level_enabled", 5); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level", "is_glow_level_enabled", 6); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace"), "set_glow_blend_mode", "get_glow_blend_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_bloom", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_bloom", "get_glow_bloom"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "glow_blend_mode", PROPERTY_HINT_ENUM, "Additive,Screen,Softlight,Replace,Mix"), "set_glow_blend_mode", "get_glow_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_bicubic_upscale"), "set_glow_bicubic_upscale", "is_glow_bicubic_upscale_enabled"); ClassDB::bind_method(D_METHOD("set_adjustment_enable", "enabled"), &Environment::set_adjustment_enable); @@ -1270,62 +1107,61 @@ void Environment::_bind_methods() { ADD_GROUP("Adjustments", "adjustment_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "adjustment_enabled"), "set_adjustment_enable", "is_adjustment_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_adjustment_color_correction", "get_adjustment_color_correction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_adjustment_color_correction", "get_adjustment_color_correction"); - BIND_ENUM_CONSTANT(BG_KEEP); BIND_ENUM_CONSTANT(BG_CLEAR_COLOR); BIND_ENUM_CONSTANT(BG_COLOR); BIND_ENUM_CONSTANT(BG_SKY); - BIND_ENUM_CONSTANT(BG_COLOR_SKY); BIND_ENUM_CONSTANT(BG_CANVAS); + BIND_ENUM_CONSTANT(BG_KEEP); BIND_ENUM_CONSTANT(BG_CAMERA_FEED); BIND_ENUM_CONSTANT(BG_MAX); + BIND_ENUM_CONSTANT(AMBIENT_SOURCE_BG); + BIND_ENUM_CONSTANT(AMBIENT_SOURCE_DISABLED); + BIND_ENUM_CONSTANT(AMBIENT_SOURCE_COLOR); + BIND_ENUM_CONSTANT(AMBIENT_SOURCE_SKY); + + BIND_ENUM_CONSTANT(REFLECTION_SOURCE_BG); + BIND_ENUM_CONSTANT(REFLECTION_SOURCE_DISABLED); + BIND_ENUM_CONSTANT(REFLECTION_SOURCE_SKY); + BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_ADDITIVE); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SCREEN); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_SOFTLIGHT); BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE); + BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_MIX); BIND_ENUM_CONSTANT(TONE_MAPPER_LINEAR); BIND_ENUM_CONSTANT(TONE_MAPPER_REINHARDT); BIND_ENUM_CONSTANT(TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(TONE_MAPPER_ACES); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_HIGH); - BIND_ENUM_CONSTANT(SSAO_BLUR_DISABLED); BIND_ENUM_CONSTANT(SSAO_BLUR_1x1); BIND_ENUM_CONSTANT(SSAO_BLUR_2x2); BIND_ENUM_CONSTANT(SSAO_BLUR_3x3); - - BIND_ENUM_CONSTANT(SSAO_QUALITY_LOW); - BIND_ENUM_CONSTANT(SSAO_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH); } Environment::Environment() : bg_mode(BG_CLEAR_COLOR), tone_mapper(TONE_MAPPER_LINEAR), ssao_blur(SSAO_BLUR_3x3), - ssao_quality(SSAO_QUALITY_MEDIUM), - glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE), - dof_blur_far_quality(DOF_BLUR_QUALITY_LOW), - dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) { + glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE) { environment = VS::get_singleton()->environment_create(); bg_mode = BG_CLEAR_COLOR; bg_sky_custom_fov = 0; - bg_sky_orientation = Basis(); bg_energy = 1.0; bg_canvas_max_layer = 0; ambient_energy = 1.0; //ambient_sky_contribution = 1.0; + ambient_source = AMBIENT_SOURCE_BG; + reflection_source = REFLECTION_SOURCE_BG; set_ambient_light_sky_contribution(1.0); set_camera_feed_id(1); @@ -1357,19 +1193,17 @@ Environment::Environment() : ssao_enabled = false; ssao_radius = 1; ssao_intensity = 1; - ssao_radius2 = 0; - ssao_intensity2 = 1; ssao_bias = 0.01; ssao_direct_light_affect = 0.0; ssao_ao_channel_affect = 0.0; ssao_blur = SSAO_BLUR_3x3; set_ssao_edge_sharpness(4); - set_ssao_quality(SSAO_QUALITY_MEDIUM); glow_enabled = false; glow_levels = (1 << 2) | (1 << 4); glow_intensity = 0.8; glow_strength = 1.0; + glow_mix = 0.05; glow_bloom = 0.0; glow_blend_mode = GLOW_BLEND_MODE_SOFTLIGHT; glow_hdr_bleed_threshold = 1.0; @@ -1377,18 +1211,6 @@ Environment::Environment() : glow_hdr_bleed_scale = 2.0; glow_bicubic_upscale = false; - dof_blur_far_enabled = false; - dof_blur_far_distance = 10; - dof_blur_far_transition = 5; - dof_blur_far_amount = 0.1; - dof_blur_far_quality = DOF_BLUR_QUALITY_MEDIUM; - - dof_blur_near_enabled = false; - dof_blur_near_distance = 2; - dof_blur_near_transition = 1; - dof_blur_near_amount = 0.1; - dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM; - fog_enabled = false; fog_color = Color(0.5, 0.5, 0.5); fog_sun_color = Color(0.8, 0.8, 0.0); @@ -1416,3 +1238,167 @@ Environment::~Environment() { VS::get_singleton()->free(environment); } + +////////////////////// + +void CameraEffects::set_dof_blur_far_enabled(bool p_enable) { + + dof_blur_far_enabled = p_enable; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} + +bool CameraEffects::is_dof_blur_far_enabled() const { + + return dof_blur_far_enabled; +} + +void CameraEffects::set_dof_blur_far_distance(float p_distance) { + + dof_blur_far_distance = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} +float CameraEffects::get_dof_blur_far_distance() const { + + return dof_blur_far_distance; +} + +void CameraEffects::set_dof_blur_far_transition(float p_distance) { + + dof_blur_far_transition = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} +float CameraEffects::get_dof_blur_far_transition() const { + + return dof_blur_far_transition; +} + +void CameraEffects::set_dof_blur_near_enabled(bool p_enable) { + + dof_blur_near_enabled = p_enable; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); + _change_notify(); +} + +bool CameraEffects::is_dof_blur_near_enabled() const { + + return dof_blur_near_enabled; +} + +void CameraEffects::set_dof_blur_near_distance(float p_distance) { + + dof_blur_near_distance = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} + +float CameraEffects::get_dof_blur_near_distance() const { + + return dof_blur_near_distance; +} + +void CameraEffects::set_dof_blur_near_transition(float p_distance) { + + dof_blur_near_transition = p_distance; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} + +float CameraEffects::get_dof_blur_near_transition() const { + + return dof_blur_near_transition; +} + +void CameraEffects::set_dof_blur_amount(float p_amount) { + + dof_blur_amount = p_amount; + VS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount); +} +float CameraEffects::get_dof_blur_amount() const { + + return dof_blur_amount; +} + +void CameraEffects::set_override_exposure_enabled(bool p_enabled) { + override_exposure_enabled = p_enabled; + VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); +} + +bool CameraEffects::is_override_exposure_enabled() const { + return override_exposure_enabled; +} + +void CameraEffects::set_override_exposure(float p_exposure) { + override_exposure = p_exposure; + VS::get_singleton()->camera_effects_set_custom_exposure(camera_effects, override_exposure_enabled, override_exposure); +} + +float CameraEffects::get_override_exposure() const { + return override_exposure; +} + +RID CameraEffects::get_rid() const { + return camera_effects; +} + +void CameraEffects::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled); + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_distance", "intensity"), &CameraEffects::set_dof_blur_far_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_distance"), &CameraEffects::get_dof_blur_far_distance); + + ClassDB::bind_method(D_METHOD("set_dof_blur_far_transition", "intensity"), &CameraEffects::set_dof_blur_far_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_far_transition"), &CameraEffects::get_dof_blur_far_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_enabled", "enabled"), &CameraEffects::set_dof_blur_near_enabled); + ClassDB::bind_method(D_METHOD("is_dof_blur_near_enabled"), &CameraEffects::is_dof_blur_near_enabled); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_distance", "intensity"), &CameraEffects::set_dof_blur_near_distance); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_distance"), &CameraEffects::get_dof_blur_near_distance); + + ClassDB::bind_method(D_METHOD("set_dof_blur_near_transition", "intensity"), &CameraEffects::set_dof_blur_near_transition); + ClassDB::bind_method(D_METHOD("get_dof_blur_near_transition"), &CameraEffects::get_dof_blur_near_transition); + + ClassDB::bind_method(D_METHOD("set_dof_blur_amount", "intensity"), &CameraEffects::set_dof_blur_amount); + ClassDB::bind_method(D_METHOD("get_dof_blur_amount"), &CameraEffects::get_dof_blur_amount); + + ClassDB::bind_method(D_METHOD("set_override_exposure_enabled", "enable"), &CameraEffects::set_override_exposure_enabled); + ClassDB::bind_method(D_METHOD("is_override_exposure_enabled"), &CameraEffects::is_override_exposure_enabled); + + ClassDB::bind_method(D_METHOD("set_override_exposure", "exposure"), &CameraEffects::set_override_exposure); + ClassDB::bind_method(D_METHOD("get_override_exposure"), &CameraEffects::get_override_exposure); + + ADD_GROUP("DOF Blur", "dof_blur_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_far_enabled"), "set_dof_blur_far_enabled", "is_dof_blur_far_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_distance", "get_dof_blur_far_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_far_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_far_transition", "get_dof_blur_far_transition"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dof_blur_near_enabled"), "set_dof_blur_near_enabled", "is_dof_blur_near_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_distance", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_distance", "get_dof_blur_near_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_near_transition", PROPERTY_HINT_EXP_RANGE, "0.01,8192,0.01"), "set_dof_blur_near_transition", "get_dof_blur_near_transition"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dof_blur_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dof_blur_amount", "get_dof_blur_amount"); + ADD_GROUP("Override Exposure", "override_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_exposure_enable"), "set_override_exposure_enabled", "is_override_exposure_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "override_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_override_exposure", "get_override_exposure"); +} + +CameraEffects::CameraEffects() { + + camera_effects = VS::get_singleton()->camera_effects_create(); + + dof_blur_far_enabled = false; + dof_blur_far_distance = 10; + dof_blur_far_transition = 5; + + dof_blur_near_enabled = false; + dof_blur_near_distance = 2; + dof_blur_near_transition = 1; + + set_dof_blur_amount(0.1); + + override_exposure_enabled = false; + set_override_exposure(1.0); +} + +CameraEffects::~CameraEffects() { + + VS::get_singleton()->free(camera_effects); +} diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 62c6c5b4cd..f9fe26f792 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -46,13 +46,25 @@ public: BG_CLEAR_COLOR, BG_COLOR, BG_SKY, - BG_COLOR_SKY, BG_CANVAS, BG_KEEP, BG_CAMERA_FEED, BG_MAX }; + enum AmbientSource { + AMBIENT_SOURCE_BG, + AMBIENT_SOURCE_DISABLED, + AMBIENT_SOURCE_COLOR, + AMBIENT_SOURCE_SKY, + }; + + enum ReflectionSource { + REFLECTION_SOURCE_BG, + REFLECTION_SOURCE_DISABLED, + REFLECTION_SOURCE_SKY, + }; + enum ToneMapper { TONE_MAPPER_LINEAR, TONE_MAPPER_REINHARDT, @@ -65,12 +77,7 @@ public: GLOW_BLEND_MODE_SCREEN, GLOW_BLEND_MODE_SOFTLIGHT, GLOW_BLEND_MODE_REPLACE, - }; - - enum DOFBlurQuality { - DOF_BLUR_QUALITY_LOW, - DOF_BLUR_QUALITY_MEDIUM, - DOF_BLUR_QUALITY_HIGH, + GLOW_BLEND_MODE_MIX, }; enum SSAOBlur { @@ -80,26 +87,23 @@ public: SSAO_BLUR_3x3 }; - enum SSAOQuality { - SSAO_QUALITY_LOW, - SSAO_QUALITY_MEDIUM, - SSAO_QUALITY_HIGH - }; - private: RID environment; BGMode bg_mode; Ref<Sky> bg_sky; float bg_sky_custom_fov; - Basis bg_sky_orientation; + Vector3 sky_rotation; Color bg_color; float bg_energy; int bg_canvas_max_layer; Color ambient_color; float ambient_energy; + Color ao_color; float ambient_sky_contribution; int camera_feed_id; + AmbientSource ambient_source; + ReflectionSource reflection_source; ToneMapper tone_mapper; float tonemap_exposure; @@ -114,7 +118,7 @@ private: float adjustment_contrast; float adjustment_saturation; float adjustment_brightness; - Ref<Texture> adjustment_color_correction; + Ref<Texture2D> adjustment_color_correction; bool ssr_enabled; int ssr_max_steps; @@ -126,20 +130,17 @@ private: bool ssao_enabled; float ssao_radius; float ssao_intensity; - float ssao_radius2; - float ssao_intensity2; float ssao_bias; float ssao_direct_light_affect; float ssao_ao_channel_affect; - Color ssao_color; SSAOBlur ssao_blur; float ssao_edge_sharpness; - SSAOQuality ssao_quality; bool glow_enabled; int glow_levels; float glow_intensity; float glow_strength; + float glow_mix; float glow_bloom; GlowBlendMode glow_blend_mode; float glow_hdr_bleed_threshold; @@ -147,18 +148,6 @@ private: float glow_hdr_luminance_cap; bool glow_bicubic_upscale; - bool dof_blur_far_enabled; - float dof_blur_far_distance; - float dof_blur_far_transition; - float dof_blur_far_amount; - DOFBlurQuality dof_blur_far_quality; - - bool dof_blur_near_enabled; - float dof_blur_near_distance; - float dof_blur_near_transition; - float dof_blur_near_amount; - DOFBlurQuality dof_blur_near_quality; - bool fog_enabled; Color fog_color; Color fog_sun_color; @@ -180,14 +169,17 @@ private: protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const; +#ifndef DISABLE_DEPRECATED + // Kept for compatibility from 3.x to 4.0. + bool _set(const StringName &p_name, const Variant &p_value); +#endif public: void set_background(BGMode p_bg); + void set_sky(const Ref<Sky> &p_sky); void set_sky_custom_fov(float p_scale); - void set_sky_orientation(const Basis &p_orientation); - void set_sky_rotation(const Vector3 &p_euler_rad); - void set_sky_rotation_degrees(const Vector3 &p_euler_deg); + void set_sky_rotation(const Vector3 &p_rotation); void set_bg_color(const Color &p_color); void set_bg_energy(float p_energy); void set_canvas_max_layer(int p_max_layer); @@ -195,13 +187,15 @@ public: void set_ambient_light_energy(float p_energy); void set_ambient_light_sky_contribution(float p_energy); void set_camera_feed_id(int p_camera_feed_id); + void set_ambient_source(AmbientSource p_source); + AmbientSource get_ambient_source() const; + void set_reflection_source(ReflectionSource p_source); + ReflectionSource get_reflection_source() const; BGMode get_background() const; Ref<Sky> get_sky() const; float get_sky_custom_fov() const; - Basis get_sky_orientation() const; Vector3 get_sky_rotation() const; - Vector3 get_sky_rotation_degrees() const; Color get_bg_color() const; float get_bg_energy() const; int get_canvas_max_layer() const; @@ -246,8 +240,8 @@ public: void set_adjustment_saturation(float p_saturation); float get_adjustment_saturation() const; - void set_adjustment_color_correction(const Ref<Texture> &p_ramp); - Ref<Texture> get_adjustment_color_correction() const; + void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp); + Ref<Texture2D> get_adjustment_color_correction() const; void set_ssr_enabled(bool p_enable); bool is_ssr_enabled() const; @@ -276,12 +270,6 @@ public: void set_ssao_intensity(float p_intensity); float get_ssao_intensity() const; - void set_ssao_radius2(float p_radius); - float get_ssao_radius2() const; - - void set_ssao_intensity2(float p_intensity); - float get_ssao_intensity2() const; - void set_ssao_bias(float p_bias); float get_ssao_bias() const; @@ -291,15 +279,12 @@ public: void set_ssao_ao_channel_affect(float p_ao_channel_affect); float get_ssao_ao_channel_affect() const; - void set_ssao_color(const Color &p_color); - Color get_ssao_color() const; + void set_ao_color(const Color &p_color); + Color get_ao_color() const; void set_ssao_blur(SSAOBlur p_blur); SSAOBlur get_ssao_blur() const; - void set_ssao_quality(SSAOQuality p_quality); - SSAOQuality get_ssao_quality() const; - void set_ssao_edge_sharpness(float p_edge_sharpness); float get_ssao_edge_sharpness() const; @@ -315,6 +300,9 @@ public: void set_glow_strength(float p_strength); float get_glow_strength() const; + void set_glow_mix(float p_mix); + float get_glow_mix() const; + void set_glow_bloom(float p_threshold); float get_glow_bloom() const; @@ -333,36 +321,6 @@ public: void set_glow_bicubic_upscale(bool p_enable); bool is_glow_bicubic_upscale_enabled() const; - void set_dof_blur_far_enabled(bool p_enable); - bool is_dof_blur_far_enabled() const; - - void set_dof_blur_far_distance(float p_distance); - float get_dof_blur_far_distance() const; - - void set_dof_blur_far_transition(float p_distance); - float get_dof_blur_far_transition() const; - - void set_dof_blur_far_amount(float p_amount); - float get_dof_blur_far_amount() const; - - void set_dof_blur_far_quality(DOFBlurQuality p_quality); - DOFBlurQuality get_dof_blur_far_quality() const; - - void set_dof_blur_near_enabled(bool p_enable); - bool is_dof_blur_near_enabled() const; - - void set_dof_blur_near_distance(float p_distance); - float get_dof_blur_near_distance() const; - - void set_dof_blur_near_transition(float p_distance); - float get_dof_blur_near_transition() const; - - void set_dof_blur_near_amount(float p_amount); - float get_dof_blur_near_amount() const; - - void set_dof_blur_near_quality(DOFBlurQuality p_quality); - DOFBlurQuality get_dof_blur_near_quality() const; - void set_fog_enabled(bool p_enabled); bool is_fog_enabled() const; @@ -412,10 +370,67 @@ public: }; VARIANT_ENUM_CAST(Environment::BGMode) +VARIANT_ENUM_CAST(Environment::AmbientSource) +VARIANT_ENUM_CAST(Environment::ReflectionSource) VARIANT_ENUM_CAST(Environment::ToneMapper) VARIANT_ENUM_CAST(Environment::GlowBlendMode) -VARIANT_ENUM_CAST(Environment::DOFBlurQuality) -VARIANT_ENUM_CAST(Environment::SSAOQuality) VARIANT_ENUM_CAST(Environment::SSAOBlur) +class CameraEffects : public Resource { + + GDCLASS(CameraEffects, Resource); + +private: + RID camera_effects; + + bool dof_blur_far_enabled; + float dof_blur_far_distance; + float dof_blur_far_transition; + + bool dof_blur_near_enabled; + float dof_blur_near_distance; + float dof_blur_near_transition; + + float dof_blur_amount; + + bool override_exposure_enabled; + float override_exposure; + +protected: + static void _bind_methods(); + +public: + void set_dof_blur_far_enabled(bool p_enable); + bool is_dof_blur_far_enabled() const; + + void set_dof_blur_far_distance(float p_distance); + float get_dof_blur_far_distance() const; + + void set_dof_blur_far_transition(float p_distance); + float get_dof_blur_far_transition() const; + + void set_dof_blur_near_enabled(bool p_enable); + bool is_dof_blur_near_enabled() const; + + void set_dof_blur_near_distance(float p_distance); + float get_dof_blur_near_distance() const; + + void set_dof_blur_near_transition(float p_distance); + float get_dof_blur_near_transition() const; + + void set_dof_blur_amount(float p_amount); + float get_dof_blur_amount() const; + + void set_override_exposure_enabled(bool p_enabled); + bool is_override_exposure_enabled() const; + + void set_override_exposure(float p_exposure); + float get_override_exposure() const; + + virtual RID get_rid() const; + + CameraEffects(); + ~CameraEffects(); +}; + #endif // ENVIRONMENT_H diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 19c59b3817..1f5e4b647a 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -107,7 +107,7 @@ Font::Font() { ///////////////////////////////////////////////////////////////// -void BitmapFont::_set_chars(const PoolVector<int> &p_chars) { +void BitmapFont::_set_chars(const Vector<int> &p_chars) { int len = p_chars.size(); //char 1 charsize 1 texture, 4 rect, 2 align, advance 1 @@ -116,7 +116,7 @@ void BitmapFont::_set_chars(const PoolVector<int> &p_chars) { return; //none to do int chars = len / 9; - PoolVector<int>::Read r = p_chars.read(); + const int *r = p_chars.ptr(); for (int i = 0; i < chars; i++) { const int *data = &r[i * 9]; @@ -124,16 +124,16 @@ void BitmapFont::_set_chars(const PoolVector<int> &p_chars) { } } -PoolVector<int> BitmapFont::_get_chars() const { +Vector<int> BitmapFont::_get_chars() const { - PoolVector<int> chars; + Vector<int> chars; const CharType *key = NULL; while ((key = char_map.next(key))) { const Character *c = char_map.getptr(*key); - ERR_FAIL_COND_V(!c, PoolVector<int>()); + ERR_FAIL_COND_V(!c, Vector<int>()); chars.push_back(*key); chars.push_back(c->texture_idx); chars.push_back(c->rect.position.x); @@ -149,13 +149,13 @@ PoolVector<int> BitmapFont::_get_chars() const { return chars; } -void BitmapFont::_set_kernings(const PoolVector<int> &p_kernings) { +void BitmapFont::_set_kernings(const Vector<int> &p_kernings) { int len = p_kernings.size(); ERR_FAIL_COND(len % 3); if (!len) return; - PoolVector<int>::Read r = p_kernings.read(); + const int *r = p_kernings.ptr(); for (int i = 0; i < len / 3; i++) { @@ -164,9 +164,9 @@ void BitmapFont::_set_kernings(const PoolVector<int> &p_kernings) { } } -PoolVector<int> BitmapFont::_get_kernings() const { +Vector<int> BitmapFont::_get_kernings() const { - PoolVector<int> kernings; + Vector<int> kernings; for (Map<KerningPairKey, int>::Element *E = kerning_map.front(); E; E = E->next()) { @@ -182,7 +182,7 @@ void BitmapFont::_set_textures(const Vector<Variant> &p_textures) { textures.clear(); for (int i = 0; i < p_textures.size(); i++) { - Ref<Texture> tex = p_textures[i]; + Ref<Texture2D> tex = p_textures[i]; ERR_CONTINUE(!tex.is_valid()); add_texture(tex); } @@ -192,7 +192,7 @@ Vector<Variant> BitmapFont::_get_textures() const { Vector<Variant> rtextures; for (int i = 0; i < textures.size(); i++) - rtextures.push_back(textures[i].get_ref_ptr()); + rtextures.push_back(textures[i]); return rtextures; } @@ -270,7 +270,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) { String base_dir = p_file.get_base_dir(); String file = base_dir.plus_file(keys["file"]); - Ref<Texture> tex = ResourceLoader::load(file); + Ref<Texture2D> tex = ResourceLoader::load(file); if (tex.is_null()) { ERR_PRINT("Can't load font texture!"); } else { @@ -356,7 +356,7 @@ float BitmapFont::get_descent() const { return height - ascent; } -void BitmapFont::add_texture(const Ref<Texture> &p_texture) { +void BitmapFont::add_texture(const Ref<Texture2D> &p_texture) { ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object."); textures.push_back(p_texture); @@ -367,9 +367,9 @@ int BitmapFont::get_texture_count() const { return textures.size(); }; -Ref<Texture> BitmapFont::get_texture(int p_idx) const { +Ref<Texture2D> BitmapFont::get_texture(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture2D>()); return textures[p_idx]; }; @@ -556,7 +556,7 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c cpos.x += c->h_align; cpos.y -= ascent; cpos.y += c->v_align; - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), false); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(cpos, c->rect.size), textures[c->texture_idx]->get_rid(), c->rect, p_modulate, false, RID(), RID(), Color(1, 1, 1, 1), false); } return get_char_size(p_char, p_next).width; @@ -625,11 +625,11 @@ void BitmapFont::_bind_methods() { ClassDB::bind_method(D_METHOD("get_fallback"), &BitmapFont::get_fallback); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_textures", "_get_textures"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_INT32_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "1,1024,1"), "set_height", "get_height"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ascent", PROPERTY_HINT_RANGE, "0,1024,1"), "set_ascent", "get_ascent"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "1,1024,1"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ascent", PROPERTY_HINT_RANGE, "0,1024,1"), "set_ascent", "get_ascent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_field"), "set_distance_field_hint", "is_distance_field_hint"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback", PROPERTY_HINT_RESOURCE_TYPE, "BitmapFont"), "set_fallback", "get_fallback"); } @@ -646,7 +646,7 @@ BitmapFont::~BitmapFont() { //////////// -RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/font.h b/scene/resources/font.h index 411145c153..85b295b5f8 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -108,7 +108,7 @@ class BitmapFont : public Font { GDCLASS(BitmapFont, Font); RES_BASE_EXTENSION("font"); - Vector<Ref<Texture> > textures; + Vector<Ref<Texture2D> > textures; public: struct Character { @@ -146,10 +146,10 @@ private: float ascent; bool distance_field_hint; - void _set_chars(const PoolVector<int> &p_chars); - PoolVector<int> _get_chars() const; - void _set_kernings(const PoolVector<int> &p_kernings); - PoolVector<int> _get_kernings() const; + void _set_chars(const Vector<int> &p_chars); + Vector<int> _get_chars() const; + void _set_kernings(const Vector<int> &p_kernings); + Vector<int> _get_kernings() const; void _set_textures(const Vector<Variant> &p_textures); Vector<Variant> _get_textures() const; @@ -168,7 +168,7 @@ public: float get_ascent() const; float get_descent() const; - void add_texture(const Ref<Texture> &p_texture); + void add_texture(const Ref<Texture2D> &p_texture); void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1); int get_character_count() const; @@ -176,7 +176,7 @@ public: Character get_character(CharType p_char) const; int get_texture_count() const; - Ref<Texture> get_texture(int p_idx) const; + Ref<Texture2D> get_texture(int p_idx) const; void add_kerning_pair(CharType p_A, CharType p_B, int p_kerning); int get_kerning_pair(CharType p_A, CharType p_B) const; @@ -200,7 +200,7 @@ public: class ResourceFormatLoaderBMFont : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp index fe5a01886d..7bce04beaf 100644 --- a/scene/resources/gradient.cpp +++ b/scene/resources/gradient.cpp @@ -72,8 +72,8 @@ void Gradient::_bind_methods() { ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors); ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors); - ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS); } Vector<float> Gradient::get_offsets() const { diff --git a/scene/resources/height_map_shape.cpp b/scene/resources/height_map_shape.cpp index 2b86d658d8..fa45ddcabb 100644 --- a/scene/resources/height_map_shape.cpp +++ b/scene/resources/height_map_shape.cpp @@ -42,7 +42,7 @@ Vector<Vector3> HeightMapShape::get_debug_mesh_lines() { Vector2 size(map_width - 1, map_depth - 1); Vector2 start = size * -0.5; - PoolRealArray::Read r = map_data.read(); + const real_t *r = map_data.ptr(); // reserve some memory for our points.. points.resize(((map_width - 1) * map_depth * 2) + (map_width * (map_depth - 1) * 2)); @@ -76,6 +76,10 @@ Vector<Vector3> HeightMapShape::get_debug_mesh_lines() { return points; } +real_t HeightMapShape::get_enclosing_radius() const { + return Vector3(real_t(map_width), max_height - min_height, real_t(map_depth)).length(); +} + void HeightMapShape::_update_shape() { Dictionary d; @@ -98,7 +102,7 @@ void HeightMapShape::set_map_width(int p_new) { int new_size = map_width * map_depth; map_data.resize(map_width * map_depth); - PoolRealArray::Write w = map_data.write(); + real_t *w = map_data.ptrw(); while (was_size < new_size) { w[was_size++] = 0.0; } @@ -124,7 +128,7 @@ void HeightMapShape::set_map_depth(int p_new) { int new_size = map_width * map_depth; map_data.resize(new_size); - PoolRealArray::Write w = map_data.write(); + real_t *w = map_data.ptrw(); while (was_size < new_size) { w[was_size++] = 0.0; } @@ -140,7 +144,7 @@ int HeightMapShape::get_map_depth() const { return map_depth; } -void HeightMapShape::set_map_data(PoolRealArray p_new) { +void HeightMapShape::set_map_data(PackedFloat32Array p_new) { int size = (map_width * map_depth); if (p_new.size() != size) { // fail @@ -148,8 +152,8 @@ void HeightMapShape::set_map_data(PoolRealArray p_new) { } // copy - PoolRealArray::Write w = map_data.write(); - PoolRealArray::Read r = p_new.read(); + real_t *w = map_data.ptrw(); + const real_t *r = p_new.ptr(); for (int i = 0; i < size; i++) { float val = r[i]; w[i] = val; @@ -170,7 +174,7 @@ void HeightMapShape::set_map_data(PoolRealArray p_new) { _change_notify("map_data"); } -PoolRealArray HeightMapShape::get_map_data() const { +PackedFloat32Array HeightMapShape::get_map_data() const { return map_data; } @@ -184,7 +188,7 @@ void HeightMapShape::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "map_width", PROPERTY_HINT_RANGE, "1,4096,1"), "set_map_width", "get_map_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "map_depth", PROPERTY_HINT_RANGE, "1,4096,1"), "set_map_depth", "get_map_depth"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_REAL_ARRAY, "map_data"), "set_map_data", "get_map_data"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "map_data"), "set_map_data", "get_map_data"); } HeightMapShape::HeightMapShape() : @@ -193,7 +197,7 @@ HeightMapShape::HeightMapShape() : map_width = 2; map_depth = 2; map_data.resize(map_width * map_depth); - PoolRealArray::Write w = map_data.write(); + real_t *w = map_data.ptrw(); w[0] = 0.0; w[1] = 0.0; w[2] = 0.0; diff --git a/scene/resources/height_map_shape.h b/scene/resources/height_map_shape.h index 3a976e3add..b8204f6c98 100644 --- a/scene/resources/height_map_shape.h +++ b/scene/resources/height_map_shape.h @@ -38,7 +38,7 @@ class HeightMapShape : public Shape { int map_width; int map_depth; - PoolRealArray map_data; + PackedFloat32Array map_data; float min_height; float max_height; @@ -51,10 +51,11 @@ public: int get_map_width() const; void set_map_depth(int p_new); int get_map_depth() const; - void set_map_data(PoolRealArray p_new); - PoolRealArray get_map_data() const; + void set_map_data(PackedFloat32Array p_new); + PackedFloat32Array get_map_data() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; HeightMapShape(); }; diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp index 7f39467403..3b30b4528a 100644 --- a/scene/resources/line_shape_2d.cpp +++ b/scene/resources/line_shape_2d.cpp @@ -100,6 +100,10 @@ Rect2 LineShape2D::get_rect() const { return rect; } +real_t LineShape2D::get_enclosing_radius() const { + return d; +} + void LineShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_normal", "normal"), &LineShape2D::set_normal); @@ -109,13 +113,13 @@ void LineShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_d"), &LineShape2D::get_d); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "d"), "set_d", "get_d"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "d"), "set_d", "get_d"); } LineShape2D::LineShape2D() : Shape2D(Physics2DServer::get_singleton()->line_shape_create()) { - normal = Vector2(0, -1); + normal = Vector2(0, 1); d = 0; _update_shape(); } diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h index 7babfe12f6..5bf9e85bb9 100644 --- a/scene/resources/line_shape_2d.h +++ b/scene/resources/line_shape_2d.h @@ -55,6 +55,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; LineShape2D(); }; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index ab4dbb758a..d387a39dbe 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -171,7 +171,7 @@ bool ShaderMaterial::property_can_revert(const String &p_name) { StringName pr = shader->remap_param(p_name); if (pr) { - Variant default_value = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr); + Variant default_value = VisualServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); Variant current_value; _get(p_name, current_value); return default_value.get_type() != Variant::NIL && default_value != current_value; @@ -185,7 +185,7 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) { if (shader.is_valid()) { StringName pr = shader->remap_param(p_name); if (pr) { - r_ret = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr); + r_ret = VisualServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr); } } return r_ret; @@ -197,7 +197,7 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { // This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`) // does nothing in non-editor builds anyway. See GH-34741 for details. if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) { - shader->disconnect("changed", this, "_shader_changed"); + shader->disconnect("changed", callable_mp(this, &ShaderMaterial::_shader_changed)); } shader = p_shader; @@ -207,7 +207,7 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { rid = shader->get_rid(); if (Engine::get_singleton()->is_editor_hint()) { - shader->connect("changed", this, "_shader_changed"); + shader->connect("changed", callable_mp(this, &ShaderMaterial::_shader_changed)); } } @@ -241,7 +241,6 @@ void ShaderMaterial::_bind_methods() { 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("_shader_changed"), &ShaderMaterial::_shader_changed); 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); @@ -290,18 +289,14 @@ ShaderMaterial::~ShaderMaterial() { ///////////////////////////////// -Mutex *SpatialMaterial::material_mutex = NULL; -SelfList<SpatialMaterial>::List *SpatialMaterial::dirty_materials = NULL; -Map<SpatialMaterial::MaterialKey, SpatialMaterial::ShaderData> SpatialMaterial::shader_map; -SpatialMaterial::ShaderNames *SpatialMaterial::shader_names = NULL; +Mutex BaseMaterial3D::material_mutex; +SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = NULL; +Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map; +BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = NULL; -void SpatialMaterial::init_shaders() { +void BaseMaterial3D::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - - dirty_materials = memnew(SelfList<SpatialMaterial>::List); + dirty_materials = memnew(SelfList<BaseMaterial3D>::List); shader_names = memnew(ShaderNames); @@ -317,7 +312,7 @@ void SpatialMaterial::init_shaders() { shader_names->clearcoat = "clearcoat"; shader_names->clearcoat_gloss = "clearcoat_gloss"; shader_names->anisotropy = "anisotropy_ratio"; - shader_names->depth_scale = "depth_scale"; + shader_names->heightmap_scale = "heightmap_scale"; shader_names->subsurface_scattering_strength = "subsurface_scattering_strength"; shader_names->transmission = "transmission"; shader_names->refraction = "refraction"; @@ -332,9 +327,9 @@ void SpatialMaterial::init_shaders() { shader_names->particles_anim_h_frames = "particles_anim_h_frames"; shader_names->particles_anim_v_frames = "particles_anim_v_frames"; shader_names->particles_anim_loop = "particles_anim_loop"; - shader_names->depth_min_layers = "depth_min_layers"; - shader_names->depth_max_layers = "depth_max_layers"; - shader_names->depth_flip = "depth_flip"; + shader_names->heightmap_min_layers = "heightmap_min_layers"; + shader_names->heightmap_max_layers = "heightmap_max_layers"; + shader_names->heightmap_flip = "heightmap_flip"; shader_names->grow = "grow"; @@ -345,11 +340,10 @@ void SpatialMaterial::init_shaders() { shader_names->distance_fade_max = "distance_fade_max"; shader_names->metallic_texture_channel = "metallic_texture_channel"; - shader_names->roughness_texture_channel = "roughness_texture_channel"; shader_names->ao_texture_channel = "ao_texture_channel"; shader_names->clearcoat_texture_channel = "clearcoat_texture_channel"; shader_names->rim_texture_channel = "rim_texture_channel"; - shader_names->depth_texture_channel = "depth_texture_channel"; + shader_names->heightmap_texture_channel = "heightmap_texture_channel"; shader_names->refraction_texture_channel = "refraction_texture_channel"; shader_names->alpha_scissor_threshold = "alpha_scissor_threshold"; @@ -362,34 +356,31 @@ void SpatialMaterial::init_shaders() { shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat"; shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap"; shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion"; - shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth"; + shader_names->texture_names[TEXTURE_HEIGHTMAP] = "texture_heightmap"; shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering"; shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission"; shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction"; shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask"; shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo"; shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal"; + shader_names->texture_names[TEXTURE_ORM] = "texture_orm"; } -Ref<SpatialMaterial> SpatialMaterial::materials_for_2d[SpatialMaterial::MAX_MATERIALS_FOR_2D]; +Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D]; -void SpatialMaterial::finish_shaders() { +void BaseMaterial3D::finish_shaders() { for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) { materials_for_2d[i].unref(); } -#ifndef NO_THREADS - memdelete(material_mutex); -#endif - memdelete(dirty_materials); dirty_materials = NULL; memdelete(shader_names); } -void SpatialMaterial::_update_shader() { +void BaseMaterial3D::_update_shader() { dirty_materials->remove(&element); @@ -415,6 +406,23 @@ void SpatialMaterial::_update_shader() { return; } + String texfilter_str; + switch (texture_filter) { + case TEXTURE_FILTER_NEAREST: texfilter_str = "filter_nearest"; break; + case TEXTURE_FILTER_LINEAR: texfilter_str = "filter_linear"; break; + case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: texfilter_str = "filter_nearest_mipmap"; break; + case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texfilter_str = "filter_linear_mipmap"; break; + case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_nearest_mipmap_aniso"; break; + case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_linear_mipmap_aniso"; break; + case TEXTURE_FILTER_MAX: break; // Internal value, skip. + } + + if (flags[FLAG_USE_TEXTURE_REPEAT]) { + texfilter_str += ",repeat_enable"; + } else { + texfilter_str += ",repeat_disable"; + } + //must create a shader! String code = "shader_type spatial;\nrender_mode "; @@ -434,7 +442,10 @@ void SpatialMaterial::_update_shader() { case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break; case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break; case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break; - case DEPTH_DRAW_ALPHA_OPAQUE_PREPASS: code += ",depth_draw_alpha_prepass"; break; + } + + if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) { + code += ",depth_prepass_alpha"; } switch (cull_mode) { @@ -457,36 +468,28 @@ void SpatialMaterial::_update_shader() { case SPECULAR_DISABLED: code += ",specular_disabled"; break; } - if (flags[FLAG_UNSHADED]) { + if (shading_mode == SHADING_MODE_UNSHADED) { code += ",unshaded"; } if (flags[FLAG_DISABLE_DEPTH_TEST]) { - code += ",depth_test_disable"; + code += ",depth_test_disabled"; } - if (flags[FLAG_USE_VERTEX_LIGHTING]) { + if (shading_mode == SHADING_MODE_PER_VERTEX) { code += ",vertex_lighting"; } - if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) { - code += ",world_vertex_coords"; - } if (flags[FLAG_DONT_RECEIVE_SHADOWS]) { code += ",shadows_disabled"; } if (flags[FLAG_DISABLE_AMBIENT_LIGHT]) { code += ",ambient_light_disabled"; } - if (flags[FLAG_ENSURE_CORRECT_NORMALS]) { - code += ",ensure_correct_normals"; - } if (flags[FLAG_USE_SHADOW_TO_OPACITY]) { code += ",shadow_to_opacity"; } code += ";\n"; code += "uniform vec4 albedo : hint_color;\n"; - code += "uniform sampler2D texture_albedo : hint_albedo;\n"; - code += "uniform float specular;\n"; - code += "uniform float metallic;\n"; + code += "uniform sampler2D texture_albedo : hint_albedo," + texfilter_str + ";\n"; if (grow_enabled) { code += "uniform float grow;\n"; } @@ -499,21 +502,41 @@ void SpatialMaterial::_update_shader() { code += "uniform float distance_fade_max;\n"; } - if (flags[FLAG_USE_ALPHA_SCISSOR]) { + if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { code += "uniform float alpha_scissor_threshold;\n"; } - code += "uniform float roughness : hint_range(0,1);\n"; + code += "uniform float point_size : hint_range(0,128);\n"; - if (textures[TEXTURE_METALLIC] != NULL) { - code += "uniform sampler2D texture_metallic : hint_white;\n"; + //TODO ALL HINTS + if (!orm) { + code += "uniform float roughness : hint_range(0,1);\n"; + code += "uniform sampler2D texture_metallic : hint_white," + texfilter_str + ";\n"; code += "uniform vec4 metallic_texture_channel;\n"; - } + switch (roughness_texture_channel) { + case TEXTURE_CHANNEL_RED: { + code += "uniform sampler2D texture_roughness : hint_roughness_r," + texfilter_str + ";\n"; + } break; + case TEXTURE_CHANNEL_GREEN: { + code += "uniform sampler2D texture_roughness : hint_roughness_g," + texfilter_str + ";\n"; + } break; + case TEXTURE_CHANNEL_BLUE: { + code += "uniform sampler2D texture_roughness : hint_roughness_b," + texfilter_str + ";\n"; + } break; + case TEXTURE_CHANNEL_ALPHA: { + code += "uniform sampler2D texture_roughness : hint_roughness_a," + texfilter_str + ";\n"; + } break; + case TEXTURE_CHANNEL_GRAYSCALE: { + code += "uniform sampler2D texture_roughness : hint_roughness_gray," + texfilter_str + ";\n"; + } break; + } - if (textures[TEXTURE_ROUGHNESS] != NULL) { - code += "uniform sampler2D texture_roughness : hint_white;\n"; - code += "uniform vec4 roughness_texture_channel;\n"; + code += "uniform float specular;\n"; + code += "uniform float metallic;\n"; + } else { + code += "uniform sampler2D texture_orm : hint_roughness_g," + texfilter_str + ";\n"; } + if (billboard_mode == BILLBOARD_PARTICLES) { code += "uniform int particles_anim_h_frames;\n"; code += "uniform int particles_anim_v_frames;\n"; @@ -522,34 +545,34 @@ void SpatialMaterial::_update_shader() { if (features[FEATURE_EMISSION]) { - code += "uniform sampler2D texture_emission : hint_black_albedo;\n"; + code += "uniform sampler2D texture_emission : hint_black_albedo," + texfilter_str + ";\n"; code += "uniform vec4 emission : hint_color;\n"; code += "uniform float emission_energy;\n"; } if (features[FEATURE_REFRACTION]) { - code += "uniform sampler2D texture_refraction;\n"; + code += "uniform sampler2D texture_refraction : " + texfilter_str + ";\n"; code += "uniform float refraction : hint_range(-16,16);\n"; code += "uniform vec4 refraction_texture_channel;\n"; } if (features[FEATURE_NORMAL_MAPPING]) { - code += "uniform sampler2D texture_normal : hint_normal;\n"; + code += "uniform sampler2D texture_normal : hint_roughness_normal," + texfilter_str + ";\n"; code += "uniform float normal_scale : hint_range(-16,16);\n"; } if (features[FEATURE_RIM]) { code += "uniform float rim : hint_range(0,1);\n"; code += "uniform float rim_tint : hint_range(0,1);\n"; - code += "uniform sampler2D texture_rim : hint_white;\n"; + code += "uniform sampler2D texture_rim : hint_white," + texfilter_str + ";\n"; } if (features[FEATURE_CLEARCOAT]) { code += "uniform float clearcoat : hint_range(0,1);\n"; code += "uniform float clearcoat_gloss : hint_range(0,1);\n"; - code += "uniform sampler2D texture_clearcoat : hint_white;\n"; + code += "uniform sampler2D texture_clearcoat : hint_white," + texfilter_str + ";\n"; } if (features[FEATURE_ANISOTROPY]) { code += "uniform float anisotropy_ratio : hint_range(0,256);\n"; - code += "uniform sampler2D texture_flowmap : hint_aniso;\n"; + code += "uniform sampler2D texture_flowmap : hint_aniso," + texfilter_str + ";\n"; } if (features[FEATURE_AMBIENT_OCCLUSION]) { code += "uniform sampler2D texture_ambient_occlusion : hint_white;\n"; @@ -558,29 +581,29 @@ void SpatialMaterial::_update_shader() { } if (features[FEATURE_DETAIL]) { - code += "uniform sampler2D texture_detail_albedo : hint_albedo;\n"; - code += "uniform sampler2D texture_detail_normal : hint_normal;\n"; - code += "uniform sampler2D texture_detail_mask : hint_white;\n"; + code += "uniform sampler2D texture_detail_albedo : hint_albedo," + texfilter_str + ";\n"; + code += "uniform sampler2D texture_detail_normal : hint_normal," + texfilter_str + ";\n"; + code += "uniform sampler2D texture_detail_mask : hint_white," + texfilter_str + ";\n"; } if (features[FEATURE_SUBSURACE_SCATTERING]) { code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n"; - code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n"; + code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n"; } if (features[FEATURE_TRANSMISSION]) { code += "uniform vec4 transmission : hint_color;\n"; - code += "uniform sampler2D texture_transmission : hint_black;\n"; + code += "uniform sampler2D texture_transmission : hint_black," + texfilter_str + ";\n"; } - if (features[FEATURE_DEPTH_MAPPING]) { - code += "uniform sampler2D texture_depth : hint_black;\n"; - code += "uniform float depth_scale;\n"; - code += "uniform int depth_min_layers;\n"; - code += "uniform int depth_max_layers;\n"; - code += "uniform vec2 depth_flip;\n"; + if (features[FEATURE_HEIGHT_MAPPING]) { + code += "uniform sampler2D texture_heightmap : hint_black," + texfilter_str + ";\n"; + code += "uniform float heightmap_scale;\n"; + code += "uniform int heightmap_min_layers;\n"; + code += "uniform int heightmap_max_layers;\n"; + code += "uniform vec2 heightmap_flip;\n"; } if (flags[FLAG_UV1_USE_TRIPLANAR]) { code += "varying vec3 uv1_triplanar_pos;\n"; @@ -618,7 +641,7 @@ void SpatialMaterial::_update_shader() { code += "\tPOINT_SIZE=point_size;\n"; } - if (flags[FLAG_USE_VERTEX_LIGHTING]) { + if (shading_mode == SHADING_MODE_PER_VERTEX) { code += "\tROUGHNESS=roughness;\n"; } @@ -750,33 +773,49 @@ void SpatialMaterial::_update_shader() { code += "\tvec2 base_uv2 = UV2;\n"; } - if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_DEPTH_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //depthmap not supported with triplanar + if (!VisualServer::get_singleton()->is_low_end() && features[FEATURE_HEIGHT_MAPPING] && !flags[FLAG_UV1_USE_TRIPLANAR]) { //heightmap not supported with triplanar code += "\t{\n"; - code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-) + code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*heightmap_flip.x,-BINORMAL*heightmap_flip.y,NORMAL));\n"; // binormal is negative due to mikktspace, flip 'unflips' it ;-) if (deep_parallax) { - code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; + code += "\t\tfloat num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n"; code += "\t\tfloat layer_depth = 1.0 / num_layers;\n"; code += "\t\tfloat current_layer_depth = 0.0;\n"; - code += "\t\tvec2 P = view_dir.xy * depth_scale;\n"; + code += "\t\tvec2 P = view_dir.xy * heightmap_scale;\n"; code += "\t\tvec2 delta = P / num_layers;\n"; code += "\t\tvec2 ofs = base_uv;\n"; - code += "\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n"; + if (flags[FLAG_INVERT_HEIGHTMAP]) { + code += "\t\tfloat depth = texture(texture_heightmap, ofs).r;\n"; + } else { + code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, ofs).r;\n"; + } code += "\t\tfloat current_depth = 0.0;\n"; code += "\t\twhile(current_depth < depth) {\n"; code += "\t\t\tofs -= delta;\n"; - code += "\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n"; + if (flags[FLAG_INVERT_HEIGHTMAP]) { + code += "\t\t\tdepth = texture(texture_heightmap, ofs).r;\n"; + } else { + code += "\t\t\tdepth = 1.0 - texture(texture_heightmap, ofs).r;\n"; + } code += "\t\t\tcurrent_depth += layer_depth;\n"; code += "\t\t}\n"; code += "\t\tvec2 prev_ofs = ofs + delta;\n"; code += "\t\tfloat after_depth = depth - current_depth;\n"; - code += "\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n"; + if (flags[FLAG_INVERT_HEIGHTMAP]) { + code += "\t\tfloat before_depth = texture(texture_heightmap, prev_ofs).r - current_depth + layer_depth;\n"; + } else { + code += "\t\tfloat before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;\n"; + } code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n"; code += "\t\tofs = mix(ofs,prev_ofs,weight);\n"; } else { - code += "\t\tfloat depth = texture(texture_depth, base_uv).r;\n"; - code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * depth_scale);\n"; + if (flags[FLAG_INVERT_HEIGHTMAP]) { + code += "\t\tfloat depth = texture(texture_heightmap, base_uv).r;\n"; + } else { + code += "\t\tfloat depth = 1.0 - texture(texture_heightmap, base_uv).r;\n"; + } + code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n"; } code += "\t\tbase_uv=ofs;\n"; @@ -806,29 +845,49 @@ void SpatialMaterial::_update_shader() { } code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n"; - if (textures[TEXTURE_METALLIC] != NULL) { + if (!orm) { if (flags[FLAG_UV1_USE_TRIPLANAR]) { code += "\tfloat metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);\n"; } else { code += "\tfloat metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);\n"; } code += "\tMETALLIC = metallic_tex * metallic;\n"; - } else { - code += "\tMETALLIC = metallic;\n"; - } - if (textures[TEXTURE_ROUGHNESS] != NULL) { + switch (roughness_texture_channel) { + case TEXTURE_CHANNEL_RED: { + code += "\tvec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);\n"; + } break; + case TEXTURE_CHANNEL_GREEN: { + code += "\tvec4 roughness_texture_channel = vec4(0.0,1.0,0.0,0.0);\n"; + } break; + case TEXTURE_CHANNEL_BLUE: { + code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,1.0,0.0);\n"; + } break; + case TEXTURE_CHANNEL_ALPHA: { + code += "\tvec4 roughness_texture_channel = vec4(0.0,0.0,0.0,1.0);\n"; + } break; + case TEXTURE_CHANNEL_GRAYSCALE: { + code += "\tvec4 roughness_texture_channel = vec4(0.333333,0.333333,0.333333,0.0);\n"; + } break; + } + if (flags[FLAG_UV1_USE_TRIPLANAR]) { code += "\tfloat roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);\n"; } else { code += "\tfloat roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);\n"; } code += "\tROUGHNESS = roughness_tex * roughness;\n"; + code += "\tSPECULAR = specular;\n"; } else { - code += "\tROUGHNESS = roughness;\n"; - } + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n"; + } else { + code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n"; + } - code += "\tSPECULAR = specular;\n"; + code += "\tROUGHNESS = orm_tex.g;\n"; + code += "\tMETALLIC = orm_tex.b;\n"; + } if (features[FEATURE_NORMAL_MAPPING]) { if (flags[FLAG_UV1_USE_TRIPLANAR]) { @@ -878,8 +937,10 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO *= 1.0 - ref_amount;\n"; code += "\tALPHA = 1.0;\n"; - } else if (features[FEATURE_TRANSPARENT] || flags[FLAG_USE_ALPHA_SCISSOR] || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { + } else if (transparency == TRANSPARENCY_ALPHA || transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS || flags[FLAG_USE_SHADOW_TO_OPACITY] || (distance_fade == DISTANCE_FADE_PIXEL_ALPHA) || proximity_fade_enabled) { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; + } else if (transparency == TRANSPARENCY_ALPHA_SCISSOR) { + code += "\tif (albedo.a * albedo_tex.a < alpha_scissor_threshold) discard;\n"; } if (proximity_fade_enabled) { @@ -965,18 +1026,23 @@ void SpatialMaterial::_update_shader() { } if (features[FEATURE_AMBIENT_OCCLUSION]) { - if (flags[FLAG_AO_ON_UV2]) { - if (flags[FLAG_UV2_USE_TRIPLANAR]) { - code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n"; + + if (!orm) { + if (flags[FLAG_AO_ON_UV2]) { + if (flags[FLAG_UV2_USE_TRIPLANAR]) { + code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv2_power_normal,uv2_triplanar_pos),ao_texture_channel);\n"; + } else { + code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n"; + } } else { - code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv2),ao_texture_channel);\n"; + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n"; + } else { + code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n"; + } } } else { - if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tAO = dot(triplanar_texture(texture_ambient_occlusion,uv1_power_normal,uv1_triplanar_pos),ao_texture_channel);\n"; - } else { - code += "\tAO = dot(texture(texture_ambient_occlusion,base_uv),ao_texture_channel);\n"; - } + code += "\tAO = orm_tex.r;\n"; } code += "\tAO_LIGHT_AFFECT = ao_light_affect;\n"; @@ -1043,10 +1109,6 @@ void SpatialMaterial::_update_shader() { code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n"; } - if (flags[FLAG_USE_ALPHA_SCISSOR]) { - code += "\tALPHA_SCISSOR=alpha_scissor_threshold;\n"; - } - code += "}\n"; ShaderData shader_data; @@ -1060,229 +1122,213 @@ void SpatialMaterial::_update_shader() { VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); } -void SpatialMaterial::flush_changes() { +void BaseMaterial3D::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } -void SpatialMaterial::_queue_shader_change() { +void BaseMaterial3D::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } -bool SpatialMaterial::_is_shader_dirty() const { - - bool dirty = false; +bool BaseMaterial3D::_is_shader_dirty() const { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); - dirty = element.in_list(); - - if (material_mutex) - material_mutex->unlock(); - - return dirty; + return element.in_list(); } -void SpatialMaterial::set_albedo(const Color &p_albedo) { +void BaseMaterial3D::set_albedo(const Color &p_albedo) { albedo = p_albedo; VS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo); } -Color SpatialMaterial::get_albedo() const { +Color BaseMaterial3D::get_albedo() const { return albedo; } -void SpatialMaterial::set_specular(float p_specular) { +void BaseMaterial3D::set_specular(float p_specular) { specular = p_specular; VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular); } -float SpatialMaterial::get_specular() const { +float BaseMaterial3D::get_specular() const { return specular; } -void SpatialMaterial::set_roughness(float p_roughness) { +void BaseMaterial3D::set_roughness(float p_roughness) { roughness = p_roughness; VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness); } -float SpatialMaterial::get_roughness() const { +float BaseMaterial3D::get_roughness() const { return roughness; } -void SpatialMaterial::set_metallic(float p_metallic) { +void BaseMaterial3D::set_metallic(float p_metallic) { metallic = p_metallic; VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic); } -float SpatialMaterial::get_metallic() const { +float BaseMaterial3D::get_metallic() const { return metallic; } -void SpatialMaterial::set_emission(const Color &p_emission) { +void BaseMaterial3D::set_emission(const Color &p_emission) { emission = p_emission; VS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission); } -Color SpatialMaterial::get_emission() const { +Color BaseMaterial3D::get_emission() const { return emission; } -void SpatialMaterial::set_emission_energy(float p_emission_energy) { +void BaseMaterial3D::set_emission_energy(float p_emission_energy) { emission_energy = p_emission_energy; VS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy); } -float SpatialMaterial::get_emission_energy() const { +float BaseMaterial3D::get_emission_energy() const { return emission_energy; } -void SpatialMaterial::set_normal_scale(float p_normal_scale) { +void BaseMaterial3D::set_normal_scale(float p_normal_scale) { normal_scale = p_normal_scale; VS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale); } -float SpatialMaterial::get_normal_scale() const { +float BaseMaterial3D::get_normal_scale() const { return normal_scale; } -void SpatialMaterial::set_rim(float p_rim) { +void BaseMaterial3D::set_rim(float p_rim) { rim = p_rim; VS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim); } -float SpatialMaterial::get_rim() const { +float BaseMaterial3D::get_rim() const { return rim; } -void SpatialMaterial::set_rim_tint(float p_rim_tint) { +void BaseMaterial3D::set_rim_tint(float p_rim_tint) { rim_tint = p_rim_tint; VS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint); } -float SpatialMaterial::get_rim_tint() const { +float BaseMaterial3D::get_rim_tint() const { return rim_tint; } -void SpatialMaterial::set_ao_light_affect(float p_ao_light_affect) { +void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) { ao_light_affect = p_ao_light_affect; VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect); } -float SpatialMaterial::get_ao_light_affect() const { +float BaseMaterial3D::get_ao_light_affect() const { return ao_light_affect; } -void SpatialMaterial::set_clearcoat(float p_clearcoat) { +void BaseMaterial3D::set_clearcoat(float p_clearcoat) { clearcoat = p_clearcoat; VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat); } -float SpatialMaterial::get_clearcoat() const { +float BaseMaterial3D::get_clearcoat() const { return clearcoat; } -void SpatialMaterial::set_clearcoat_gloss(float p_clearcoat_gloss) { +void BaseMaterial3D::set_clearcoat_gloss(float p_clearcoat_gloss) { clearcoat_gloss = p_clearcoat_gloss; VS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss); } -float SpatialMaterial::get_clearcoat_gloss() const { +float BaseMaterial3D::get_clearcoat_gloss() const { return clearcoat_gloss; } -void SpatialMaterial::set_anisotropy(float p_anisotropy) { +void BaseMaterial3D::set_anisotropy(float p_anisotropy) { anisotropy = p_anisotropy; VS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy); } -float SpatialMaterial::get_anisotropy() const { +float BaseMaterial3D::get_anisotropy() const { return anisotropy; } -void SpatialMaterial::set_depth_scale(float p_depth_scale) { +void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) { - depth_scale = p_depth_scale; - VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_scale, p_depth_scale); + heightmap_scale = p_heightmap_scale; + VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale); } -float SpatialMaterial::get_depth_scale() const { +float BaseMaterial3D::get_heightmap_scale() const { - return depth_scale; + return heightmap_scale; } -void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) { +void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) { subsurface_scattering_strength = p_subsurface_scattering_strength; VS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength); } -float SpatialMaterial::get_subsurface_scattering_strength() const { +float BaseMaterial3D::get_subsurface_scattering_strength() const { return subsurface_scattering_strength; } -void SpatialMaterial::set_transmission(const Color &p_transmission) { +void BaseMaterial3D::set_transmission(const Color &p_transmission) { transmission = p_transmission; VS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission); } -Color SpatialMaterial::get_transmission() const { +Color BaseMaterial3D::get_transmission() const { return transmission; } -void SpatialMaterial::set_refraction(float p_refraction) { +void BaseMaterial3D::set_refraction(float p_refraction) { refraction = p_refraction; VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction); } -float SpatialMaterial::get_refraction() const { +float BaseMaterial3D::get_refraction() const { return refraction; } -void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { +void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) { if (detail_uv == p_detail_uv) return; @@ -1290,12 +1336,12 @@ void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) { detail_uv = p_detail_uv; _queue_shader_change(); } -SpatialMaterial::DetailUV SpatialMaterial::get_detail_uv() const { +BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const { return detail_uv; } -void SpatialMaterial::set_blend_mode(BlendMode p_mode) { +void BaseMaterial3D::set_blend_mode(BlendMode p_mode) { if (blend_mode == p_mode) return; @@ -1303,22 +1349,52 @@ void SpatialMaterial::set_blend_mode(BlendMode p_mode) { blend_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::BlendMode SpatialMaterial::get_blend_mode() const { +BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const { return blend_mode; } -void SpatialMaterial::set_detail_blend_mode(BlendMode p_mode) { +void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) { detail_blend_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::BlendMode SpatialMaterial::get_detail_blend_mode() const { +BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const { return detail_blend_mode; } -void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) { +void BaseMaterial3D::set_transparency(Transparency p_transparency) { + + if (transparency == p_transparency) { + return; + } + + transparency = p_transparency; + _queue_shader_change(); + _change_notify(); +} + +BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const { + return transparency; +} + +void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) { + + if (shading_mode == p_shading_mode) { + return; + } + + shading_mode = p_shading_mode; + _queue_shader_change(); + _change_notify(); +} + +BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const { + return shading_mode; +} + +void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) { if (depth_draw_mode == p_mode) return; @@ -1326,12 +1402,12 @@ void SpatialMaterial::set_depth_draw_mode(DepthDrawMode p_mode) { depth_draw_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::DepthDrawMode SpatialMaterial::get_depth_draw_mode() const { +BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const { return depth_draw_mode; } -void SpatialMaterial::set_cull_mode(CullMode p_mode) { +void BaseMaterial3D::set_cull_mode(CullMode p_mode) { if (cull_mode == p_mode) return; @@ -1339,12 +1415,12 @@ void SpatialMaterial::set_cull_mode(CullMode p_mode) { cull_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::CullMode SpatialMaterial::get_cull_mode() const { +BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const { return cull_mode; } -void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) { +void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) { if (diffuse_mode == p_mode) return; @@ -1352,12 +1428,12 @@ void SpatialMaterial::set_diffuse_mode(DiffuseMode p_mode) { diffuse_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::DiffuseMode SpatialMaterial::get_diffuse_mode() const { +BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const { return diffuse_mode; } -void SpatialMaterial::set_specular_mode(SpecularMode p_mode) { +void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) { if (specular_mode == p_mode) return; @@ -1365,12 +1441,12 @@ void SpatialMaterial::set_specular_mode(SpecularMode p_mode) { specular_mode = p_mode; _queue_shader_change(); } -SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const { +BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const { return specular_mode; } -void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) { +void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { ERR_FAIL_INDEX(p_flag, FLAG_MAX); @@ -1378,19 +1454,19 @@ void SpatialMaterial::set_flag(Flags p_flag, bool p_enabled) { return; flags[p_flag] = p_enabled; - if ((p_flag == FLAG_USE_ALPHA_SCISSOR) || (p_flag == FLAG_UNSHADED) || (p_flag == FLAG_USE_SHADOW_TO_OPACITY)) { + if ((p_flag == FLAG_USE_SHADOW_TO_OPACITY) || (p_flag == FLAG_USE_TEXTURE_REPEAT)) { _change_notify(); } _queue_shader_change(); } -bool SpatialMaterial::get_flag(Flags p_flag) const { +bool BaseMaterial3D::get_flag(Flags p_flag) const { ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); return flags[p_flag]; } -void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) { +void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) { ERR_FAIL_INDEX(p_feature, FEATURE_MAX); if (features[p_feature] == p_enabled) @@ -1401,13 +1477,13 @@ void SpatialMaterial::set_feature(Feature p_feature, bool p_enabled) { _queue_shader_change(); } -bool SpatialMaterial::get_feature(Feature p_feature) const { +bool BaseMaterial3D::get_feature(Feature p_feature) const { ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false); return features[p_feature]; } -void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_texture) { +void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, TEXTURE_MAX); textures[p_param] = p_texture; @@ -1417,41 +1493,50 @@ void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_te _queue_shader_change(); } -Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const { +Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const { - ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture>()); + ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>()); return textures[p_param]; } -Ref<Texture> SpatialMaterial::get_texture_by_name(StringName p_name) const { - for (int i = 0; i < (int)SpatialMaterial::TEXTURE_MAX; i++) { +Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const { + for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) { TextureParam param = TextureParam(i); if (p_name == shader_names->texture_names[param]) return textures[param]; } - return Ref<Texture>(); + return Ref<Texture2D>(); +} + +void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) { + texture_filter = p_filter; + _queue_shader_change(); +} + +BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const { + return texture_filter; } -void SpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const { +void BaseMaterial3D::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const { if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) { property.usage = 0; } } -void SpatialMaterial::_validate_high_end(const String &text, PropertyInfo &property) const { +void BaseMaterial3D::_validate_high_end(const String &text, PropertyInfo &property) const { if (property.name.begins_with(text)) { property.usage |= PROPERTY_USAGE_HIGH_END_GFX; } } -void SpatialMaterial::_validate_property(PropertyInfo &property) const { +void BaseMaterial3D::_validate_property(PropertyInfo &property) const { _validate_feature("normal", FEATURE_NORMAL_MAPPING, property); _validate_feature("emission", FEATURE_EMISSION, property); _validate_feature("rim", FEATURE_RIM, property); _validate_feature("clearcoat", FEATURE_CLEARCOAT, property); _validate_feature("anisotropy", FEATURE_ANISOTROPY, property); _validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property); - _validate_feature("depth", FEATURE_DEPTH_MAPPING, property); + _validate_feature("heightmap", FEATURE_HEIGHT_MAPPING, property); _validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property); _validate_feature("transmission", FEATURE_TRANSMISSION, property); _validate_feature("refraction", FEATURE_REFRACTION, property); @@ -1461,7 +1546,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { _validate_high_end("subsurf_scatter", property); _validate_high_end("anisotropy", property); _validate_high_end("clearcoat", property); - _validate_high_end("depth", property); + _validate_high_end("heightmap", property); if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) { property.usage = 0; @@ -1479,48 +1564,67 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name == "params_alpha_scissor_threshold" && !flags[FLAG_USE_ALPHA_SCISSOR]) { + if (property.name == "alpha_scissor_threshold" && transparency != TRANSPARENCY_ALPHA_SCISSOR) { property.usage = 0; } - if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) { + if ((property.name == "heightmap_min_layers" || property.name == "heightmap_max_layers") && !deep_parallax) { property.usage = 0; } - if (flags[FLAG_UNSHADED]) { - if (property.name.begins_with("anisotropy")) { - property.usage = 0; - } + if (orm) { - if (property.name.begins_with("ao")) { - property.usage = 0; + if (property.name == "shading_mode") { + property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness. } - - if (property.name.begins_with("clearcoat")) { + if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) { property.usage = 0; } - if (property.name.begins_with("emission")) { + } else { + if (property.name == "orm_texture") { property.usage = 0; } + } - if (property.name.begins_with("metallic")) { - property.usage = 0; - } + if (shading_mode != SHADING_MODE_PER_PIXEL) { - if (property.name.begins_with("normal")) { - property.usage = 0; + if (shading_mode != SHADING_MODE_PER_VERTEX) { + + //these may still work per vertex + if (property.name.begins_with("ao")) { + property.usage = 0; + } + if (property.name.begins_with("emission")) { + property.usage = 0; + } + + if (property.name.begins_with("metallic")) { + property.usage = 0; + } + if (property.name.begins_with("rim")) { + property.usage = 0; + } + + if (property.name.begins_with("roughness")) { + property.usage = 0; + } + + if (property.name.begins_with("subsurf_scatter")) { + property.usage = 0; + } } - if (property.name.begins_with("rim")) { + //these definitely only need per pixel + if (property.name.begins_with("anisotropy")) { property.usage = 0; } - if (property.name.begins_with("roughness")) { + if (property.name.begins_with("clearcoat")) { property.usage = 0; } - if (property.name.begins_with("subsurf_scatter")) { + if (property.name.begins_with("normal")) { property.usage = 0; } @@ -1530,222 +1634,211 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { } } -void SpatialMaterial::set_line_width(float p_line_width) { - - line_width = p_line_width; - VS::get_singleton()->material_set_line_width(_get_material(), line_width); -} - -float SpatialMaterial::get_line_width() const { - - return line_width; -} - -void SpatialMaterial::set_point_size(float p_point_size) { +void BaseMaterial3D::set_point_size(float p_point_size) { point_size = p_point_size; VS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size); } -float SpatialMaterial::get_point_size() const { +float BaseMaterial3D::get_point_size() const { return point_size; } -void SpatialMaterial::set_uv1_scale(const Vector3 &p_scale) { +void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) { uv1_scale = p_scale; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale); } -Vector3 SpatialMaterial::get_uv1_scale() const { +Vector3 BaseMaterial3D::get_uv1_scale() const { return uv1_scale; } -void SpatialMaterial::set_uv1_offset(const Vector3 &p_offset) { +void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) { uv1_offset = p_offset; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset); } -Vector3 SpatialMaterial::get_uv1_offset() const { +Vector3 BaseMaterial3D::get_uv1_offset() const { return uv1_offset; } -void SpatialMaterial::set_uv1_triplanar_blend_sharpness(float p_sharpness) { +void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) { uv1_triplanar_sharpness = p_sharpness; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness); } -float SpatialMaterial::get_uv1_triplanar_blend_sharpness() const { +float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const { return uv1_triplanar_sharpness; } -void SpatialMaterial::set_uv2_scale(const Vector3 &p_scale) { +void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) { uv2_scale = p_scale; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale); } -Vector3 SpatialMaterial::get_uv2_scale() const { +Vector3 BaseMaterial3D::get_uv2_scale() const { return uv2_scale; } -void SpatialMaterial::set_uv2_offset(const Vector3 &p_offset) { +void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) { uv2_offset = p_offset; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset); } -Vector3 SpatialMaterial::get_uv2_offset() const { +Vector3 BaseMaterial3D::get_uv2_offset() const { return uv2_offset; } -void SpatialMaterial::set_uv2_triplanar_blend_sharpness(float p_sharpness) { +void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) { uv2_triplanar_sharpness = p_sharpness; VS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness); } -float SpatialMaterial::get_uv2_triplanar_blend_sharpness() const { +float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const { return uv2_triplanar_sharpness; } -void SpatialMaterial::set_billboard_mode(BillboardMode p_mode) { +void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) { billboard_mode = p_mode; _queue_shader_change(); _change_notify(); } -SpatialMaterial::BillboardMode SpatialMaterial::get_billboard_mode() const { +BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const { return billboard_mode; } -void SpatialMaterial::set_particles_anim_h_frames(int p_frames) { +void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) { particles_anim_h_frames = p_frames; VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames); } -int SpatialMaterial::get_particles_anim_h_frames() const { +int BaseMaterial3D::get_particles_anim_h_frames() const { return particles_anim_h_frames; } -void SpatialMaterial::set_particles_anim_v_frames(int p_frames) { +void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) { particles_anim_v_frames = p_frames; VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames); } -int SpatialMaterial::get_particles_anim_v_frames() const { +int BaseMaterial3D::get_particles_anim_v_frames() const { return particles_anim_v_frames; } -void SpatialMaterial::set_particles_anim_loop(bool p_loop) { +void BaseMaterial3D::set_particles_anim_loop(bool p_loop) { particles_anim_loop = p_loop; VS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop); } -bool SpatialMaterial::get_particles_anim_loop() const { +bool BaseMaterial3D::get_particles_anim_loop() const { return particles_anim_loop; } -void SpatialMaterial::set_depth_deep_parallax(bool p_enable) { +void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) { deep_parallax = p_enable; _queue_shader_change(); _change_notify(); } -bool SpatialMaterial::is_depth_deep_parallax_enabled() const { +bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const { return deep_parallax; } -void SpatialMaterial::set_depth_deep_parallax_min_layers(int p_layer) { +void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) { deep_parallax_min_layers = p_layer; - VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_min_layers, p_layer); + VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer); } -int SpatialMaterial::get_depth_deep_parallax_min_layers() const { +int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const { return deep_parallax_min_layers; } -void SpatialMaterial::set_depth_deep_parallax_max_layers(int p_layer) { +void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) { deep_parallax_max_layers = p_layer; - VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_max_layers, p_layer); + VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer); } -int SpatialMaterial::get_depth_deep_parallax_max_layers() const { +int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const { return deep_parallax_max_layers; } -void SpatialMaterial::set_depth_deep_parallax_flip_tangent(bool p_flip) { +void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) { - depth_parallax_flip_tangent = p_flip; - VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1)); + heightmap_parallax_flip_tangent = p_flip; + VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1)); } -bool SpatialMaterial::get_depth_deep_parallax_flip_tangent() const { +bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const { - return depth_parallax_flip_tangent; + return heightmap_parallax_flip_tangent; } -void SpatialMaterial::set_depth_deep_parallax_flip_binormal(bool p_flip) { +void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) { - depth_parallax_flip_binormal = p_flip; - VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_flip, Vector2(depth_parallax_flip_tangent ? -1 : 1, depth_parallax_flip_binormal ? -1 : 1)); + heightmap_parallax_flip_binormal = p_flip; + VS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1)); } -bool SpatialMaterial::get_depth_deep_parallax_flip_binormal() const { +bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const { - return depth_parallax_flip_binormal; + return heightmap_parallax_flip_binormal; } -void SpatialMaterial::set_grow_enabled(bool p_enable) { +void BaseMaterial3D::set_grow_enabled(bool p_enable) { grow_enabled = p_enable; _queue_shader_change(); _change_notify(); } -bool SpatialMaterial::is_grow_enabled() const { +bool BaseMaterial3D::is_grow_enabled() const { return grow_enabled; } -void SpatialMaterial::set_alpha_scissor_threshold(float p_threshold) { +void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) { alpha_scissor_threshold = p_threshold; VS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold); } -float SpatialMaterial::get_alpha_scissor_threshold() const { +float BaseMaterial3D::get_alpha_scissor_threshold() const { return alpha_scissor_threshold; } -void SpatialMaterial::set_grow(float p_grow) { +void BaseMaterial3D::set_grow(float p_grow) { grow = p_grow; VS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow); } -float SpatialMaterial::get_grow() const { +float BaseMaterial3D::get_grow() const { return grow; } -static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) { +static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) { static const Plane masks[5] = { Plane(1, 0, 0, 0), Plane(0, 1, 0, 0), @@ -1757,50 +1850,50 @@ static Plane _get_texture_mask(SpatialMaterial::TextureChannel p_channel) { return masks[p_channel]; } -void SpatialMaterial::set_metallic_texture_channel(TextureChannel p_channel) { +void BaseMaterial3D::set_metallic_texture_channel(TextureChannel p_channel) { ERR_FAIL_INDEX(p_channel, 5); metallic_texture_channel = p_channel; VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel)); } -SpatialMaterial::TextureChannel SpatialMaterial::get_metallic_texture_channel() const { +BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() const { return metallic_texture_channel; } -void SpatialMaterial::set_roughness_texture_channel(TextureChannel p_channel) { +void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) { ERR_FAIL_INDEX(p_channel, 5); roughness_texture_channel = p_channel; - VS::get_singleton()->material_set_param(_get_material(), shader_names->roughness_texture_channel, _get_texture_mask(p_channel)); + _queue_shader_change(); } -SpatialMaterial::TextureChannel SpatialMaterial::get_roughness_texture_channel() const { +BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const { return roughness_texture_channel; } -void SpatialMaterial::set_ao_texture_channel(TextureChannel p_channel) { +void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) { ERR_FAIL_INDEX(p_channel, 5); ao_texture_channel = p_channel; VS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel)); } -SpatialMaterial::TextureChannel SpatialMaterial::get_ao_texture_channel() const { +BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const { return ao_texture_channel; } -void SpatialMaterial::set_refraction_texture_channel(TextureChannel p_channel) { +void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) { ERR_FAIL_INDEX(p_channel, 5); refraction_texture_channel = p_channel; VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel)); } -SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel() const { +BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() const { return refraction_texture_channel; } -RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) { +RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) { int version = 0; if (p_shaded) @@ -1822,16 +1915,14 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, return materials_for_2d[version]->get_rid(); } - Ref<SpatialMaterial> material; + Ref<StandardMaterial3D> material; material.instance(); - material->set_flag(FLAG_UNSHADED, !p_shaded); - material->set_feature(FEATURE_TRANSPARENT, p_transparent); + material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED); + material->set_transparency(p_transparent ? (p_opaque_prepass ? TRANSPARENCY_ALPHA_DEPTH_PRE_PASS : (p_cut_alpha ? TRANSPARENCY_ALPHA_SCISSOR : TRANSPARENCY_ALPHA)) : TRANSPARENCY_DISABLED); material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK); - material->set_depth_draw_mode(p_opaque_prepass ? DEPTH_DRAW_ALPHA_OPAQUE_PREPASS : DEPTH_DRAW_OPAQUE_ONLY); material->set_flag(FLAG_SRGB_VERTEX_COLOR, true); material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha); if (p_billboard || p_billboard_y) { material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true); material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED); @@ -1842,67 +1933,67 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, return materials_for_2d[version]->get_rid(); } -void SpatialMaterial::set_on_top_of_alpha() { - set_feature(FEATURE_TRANSPARENT, true); +void BaseMaterial3D::set_on_top_of_alpha() { + set_transparency(TRANSPARENCY_DISABLED); set_render_priority(RENDER_PRIORITY_MAX); set_flag(FLAG_DISABLE_DEPTH_TEST, true); } -void SpatialMaterial::set_proximity_fade(bool p_enable) { +void BaseMaterial3D::set_proximity_fade(bool p_enable) { proximity_fade_enabled = p_enable; _queue_shader_change(); _change_notify(); } -bool SpatialMaterial::is_proximity_fade_enabled() const { +bool BaseMaterial3D::is_proximity_fade_enabled() const { return proximity_fade_enabled; } -void SpatialMaterial::set_proximity_fade_distance(float p_distance) { +void BaseMaterial3D::set_proximity_fade_distance(float p_distance) { proximity_fade_distance = p_distance; VS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance); } -float SpatialMaterial::get_proximity_fade_distance() const { +float BaseMaterial3D::get_proximity_fade_distance() const { return proximity_fade_distance; } -void SpatialMaterial::set_distance_fade(DistanceFadeMode p_mode) { +void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) { distance_fade = p_mode; _queue_shader_change(); _change_notify(); } -SpatialMaterial::DistanceFadeMode SpatialMaterial::get_distance_fade() const { +BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const { return distance_fade; } -void SpatialMaterial::set_distance_fade_max_distance(float p_distance) { +void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) { distance_fade_max_distance = p_distance; VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance); } -float SpatialMaterial::get_distance_fade_max_distance() const { +float BaseMaterial3D::get_distance_fade_max_distance() const { return distance_fade_max_distance; } -void SpatialMaterial::set_distance_fade_min_distance(float p_distance) { +void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) { distance_fade_min_distance = p_distance; VS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance); } -float SpatialMaterial::get_distance_fade_min_distance() const { +float BaseMaterial3D::get_distance_fade_min_distance() const { return distance_fade_min_distance; } -void SpatialMaterial::set_emission_operator(EmissionOperator p_op) { +void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) { if (emission_op == p_op) return; @@ -1910,336 +2001,355 @@ void SpatialMaterial::set_emission_operator(EmissionOperator p_op) { _queue_shader_change(); } -SpatialMaterial::EmissionOperator SpatialMaterial::get_emission_operator() const { +BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const { return emission_op; } -RID SpatialMaterial::get_shader_rid() const { +RID BaseMaterial3D::get_shader_rid() const { ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); return shader_map[current_key].shader; } -Shader::Mode SpatialMaterial::get_shader_mode() const { +Shader::Mode BaseMaterial3D::get_shader_mode() const { return Shader::MODE_SPATIAL; } -void SpatialMaterial::_bind_methods() { +void BaseMaterial3D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &BaseMaterial3D::set_albedo); + ClassDB::bind_method(D_METHOD("get_albedo"), &BaseMaterial3D::get_albedo); + + ClassDB::bind_method(D_METHOD("set_transparency", "transparency"), &BaseMaterial3D::set_transparency); + ClassDB::bind_method(D_METHOD("get_transparency"), &BaseMaterial3D::get_transparency); + + ClassDB::bind_method(D_METHOD("set_shading_mode", "shading_mode"), &BaseMaterial3D::set_shading_mode); + ClassDB::bind_method(D_METHOD("get_shading_mode"), &BaseMaterial3D::get_shading_mode); + + ClassDB::bind_method(D_METHOD("set_specular", "specular"), &BaseMaterial3D::set_specular); + ClassDB::bind_method(D_METHOD("get_specular"), &BaseMaterial3D::get_specular); - ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo); - ClassDB::bind_method(D_METHOD("get_albedo"), &SpatialMaterial::get_albedo); + ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &BaseMaterial3D::set_metallic); + ClassDB::bind_method(D_METHOD("get_metallic"), &BaseMaterial3D::get_metallic); - ClassDB::bind_method(D_METHOD("set_specular", "specular"), &SpatialMaterial::set_specular); - ClassDB::bind_method(D_METHOD("get_specular"), &SpatialMaterial::get_specular); + ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &BaseMaterial3D::set_roughness); + ClassDB::bind_method(D_METHOD("get_roughness"), &BaseMaterial3D::get_roughness); - ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &SpatialMaterial::set_metallic); - ClassDB::bind_method(D_METHOD("get_metallic"), &SpatialMaterial::get_metallic); + ClassDB::bind_method(D_METHOD("set_emission", "emission"), &BaseMaterial3D::set_emission); + ClassDB::bind_method(D_METHOD("get_emission"), &BaseMaterial3D::get_emission); - ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &SpatialMaterial::set_roughness); - ClassDB::bind_method(D_METHOD("get_roughness"), &SpatialMaterial::get_roughness); + ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &BaseMaterial3D::set_emission_energy); + ClassDB::bind_method(D_METHOD("get_emission_energy"), &BaseMaterial3D::get_emission_energy); - ClassDB::bind_method(D_METHOD("set_emission", "emission"), &SpatialMaterial::set_emission); - ClassDB::bind_method(D_METHOD("get_emission"), &SpatialMaterial::get_emission); + ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &BaseMaterial3D::set_normal_scale); + ClassDB::bind_method(D_METHOD("get_normal_scale"), &BaseMaterial3D::get_normal_scale); - ClassDB::bind_method(D_METHOD("set_emission_energy", "emission_energy"), &SpatialMaterial::set_emission_energy); - ClassDB::bind_method(D_METHOD("get_emission_energy"), &SpatialMaterial::get_emission_energy); + ClassDB::bind_method(D_METHOD("set_rim", "rim"), &BaseMaterial3D::set_rim); + ClassDB::bind_method(D_METHOD("get_rim"), &BaseMaterial3D::get_rim); - ClassDB::bind_method(D_METHOD("set_normal_scale", "normal_scale"), &SpatialMaterial::set_normal_scale); - ClassDB::bind_method(D_METHOD("get_normal_scale"), &SpatialMaterial::get_normal_scale); + ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &BaseMaterial3D::set_rim_tint); + ClassDB::bind_method(D_METHOD("get_rim_tint"), &BaseMaterial3D::get_rim_tint); - ClassDB::bind_method(D_METHOD("set_rim", "rim"), &SpatialMaterial::set_rim); - ClassDB::bind_method(D_METHOD("get_rim"), &SpatialMaterial::get_rim); + ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &BaseMaterial3D::set_clearcoat); + ClassDB::bind_method(D_METHOD("get_clearcoat"), &BaseMaterial3D::get_clearcoat); - ClassDB::bind_method(D_METHOD("set_rim_tint", "rim_tint"), &SpatialMaterial::set_rim_tint); - ClassDB::bind_method(D_METHOD("get_rim_tint"), &SpatialMaterial::get_rim_tint); + ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &BaseMaterial3D::set_clearcoat_gloss); + ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &BaseMaterial3D::get_clearcoat_gloss); - ClassDB::bind_method(D_METHOD("set_clearcoat", "clearcoat"), &SpatialMaterial::set_clearcoat); - ClassDB::bind_method(D_METHOD("get_clearcoat"), &SpatialMaterial::get_clearcoat); + ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &BaseMaterial3D::set_anisotropy); + ClassDB::bind_method(D_METHOD("get_anisotropy"), &BaseMaterial3D::get_anisotropy); - ClassDB::bind_method(D_METHOD("set_clearcoat_gloss", "clearcoat_gloss"), &SpatialMaterial::set_clearcoat_gloss); - ClassDB::bind_method(D_METHOD("get_clearcoat_gloss"), &SpatialMaterial::get_clearcoat_gloss); + ClassDB::bind_method(D_METHOD("set_heightmap_scale", "heightmap_scale"), &BaseMaterial3D::set_heightmap_scale); + ClassDB::bind_method(D_METHOD("get_heightmap_scale"), &BaseMaterial3D::get_heightmap_scale); - ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &SpatialMaterial::set_anisotropy); - ClassDB::bind_method(D_METHOD("get_anisotropy"), &SpatialMaterial::get_anisotropy); + ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &BaseMaterial3D::set_subsurface_scattering_strength); + ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &BaseMaterial3D::get_subsurface_scattering_strength); - ClassDB::bind_method(D_METHOD("set_depth_scale", "depth_scale"), &SpatialMaterial::set_depth_scale); - ClassDB::bind_method(D_METHOD("get_depth_scale"), &SpatialMaterial::get_depth_scale); + ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &BaseMaterial3D::set_transmission); + ClassDB::bind_method(D_METHOD("get_transmission"), &BaseMaterial3D::get_transmission); - ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength); - ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength); + ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &BaseMaterial3D::set_refraction); + ClassDB::bind_method(D_METHOD("get_refraction"), &BaseMaterial3D::get_refraction); - ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &SpatialMaterial::set_transmission); - ClassDB::bind_method(D_METHOD("get_transmission"), &SpatialMaterial::get_transmission); + ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &BaseMaterial3D::set_point_size); + ClassDB::bind_method(D_METHOD("get_point_size"), &BaseMaterial3D::get_point_size); - ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction); - ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction); + ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &BaseMaterial3D::set_detail_uv); + ClassDB::bind_method(D_METHOD("get_detail_uv"), &BaseMaterial3D::get_detail_uv); - ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width); - ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width); + ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &BaseMaterial3D::set_blend_mode); + ClassDB::bind_method(D_METHOD("get_blend_mode"), &BaseMaterial3D::get_blend_mode); - ClassDB::bind_method(D_METHOD("set_point_size", "point_size"), &SpatialMaterial::set_point_size); - ClassDB::bind_method(D_METHOD("get_point_size"), &SpatialMaterial::get_point_size); + ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &BaseMaterial3D::set_depth_draw_mode); + ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &BaseMaterial3D::get_depth_draw_mode); - ClassDB::bind_method(D_METHOD("set_detail_uv", "detail_uv"), &SpatialMaterial::set_detail_uv); - ClassDB::bind_method(D_METHOD("get_detail_uv"), &SpatialMaterial::get_detail_uv); + ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &BaseMaterial3D::set_cull_mode); + ClassDB::bind_method(D_METHOD("get_cull_mode"), &BaseMaterial3D::get_cull_mode); - ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &SpatialMaterial::set_blend_mode); - ClassDB::bind_method(D_METHOD("get_blend_mode"), &SpatialMaterial::get_blend_mode); + ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &BaseMaterial3D::set_diffuse_mode); + ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &BaseMaterial3D::get_diffuse_mode); - ClassDB::bind_method(D_METHOD("set_depth_draw_mode", "depth_draw_mode"), &SpatialMaterial::set_depth_draw_mode); - ClassDB::bind_method(D_METHOD("get_depth_draw_mode"), &SpatialMaterial::get_depth_draw_mode); + ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &BaseMaterial3D::set_specular_mode); + ClassDB::bind_method(D_METHOD("get_specular_mode"), &BaseMaterial3D::get_specular_mode); - ClassDB::bind_method(D_METHOD("set_cull_mode", "cull_mode"), &SpatialMaterial::set_cull_mode); - ClassDB::bind_method(D_METHOD("get_cull_mode"), &SpatialMaterial::get_cull_mode); + ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &BaseMaterial3D::set_flag); + ClassDB::bind_method(D_METHOD("get_flag", "flag"), &BaseMaterial3D::get_flag); - ClassDB::bind_method(D_METHOD("set_diffuse_mode", "diffuse_mode"), &SpatialMaterial::set_diffuse_mode); - ClassDB::bind_method(D_METHOD("get_diffuse_mode"), &SpatialMaterial::get_diffuse_mode); + ClassDB::bind_method(D_METHOD("set_texture_filter", "mode"), &BaseMaterial3D::set_texture_filter); + ClassDB::bind_method(D_METHOD("get_texture_filter"), &BaseMaterial3D::get_texture_filter); - ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &SpatialMaterial::set_specular_mode); - ClassDB::bind_method(D_METHOD("get_specular_mode"), &SpatialMaterial::get_specular_mode); + ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &BaseMaterial3D::set_feature); + ClassDB::bind_method(D_METHOD("get_feature", "feature"), &BaseMaterial3D::get_feature); - ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &SpatialMaterial::set_flag); - ClassDB::bind_method(D_METHOD("get_flag", "flag"), &SpatialMaterial::get_flag); + ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &BaseMaterial3D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture", "param"), &BaseMaterial3D::get_texture); - ClassDB::bind_method(D_METHOD("set_feature", "feature", "enable"), &SpatialMaterial::set_feature); - ClassDB::bind_method(D_METHOD("get_feature", "feature"), &SpatialMaterial::get_feature); + ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &BaseMaterial3D::set_detail_blend_mode); + ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &BaseMaterial3D::get_detail_blend_mode); - ClassDB::bind_method(D_METHOD("set_texture", "param", "texture"), &SpatialMaterial::set_texture); - ClassDB::bind_method(D_METHOD("get_texture", "param"), &SpatialMaterial::get_texture); + ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &BaseMaterial3D::set_uv1_scale); + ClassDB::bind_method(D_METHOD("get_uv1_scale"), &BaseMaterial3D::get_uv1_scale); - ClassDB::bind_method(D_METHOD("set_detail_blend_mode", "detail_blend_mode"), &SpatialMaterial::set_detail_blend_mode); - ClassDB::bind_method(D_METHOD("get_detail_blend_mode"), &SpatialMaterial::get_detail_blend_mode); + ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &BaseMaterial3D::set_uv1_offset); + ClassDB::bind_method(D_METHOD("get_uv1_offset"), &BaseMaterial3D::get_uv1_offset); - ClassDB::bind_method(D_METHOD("set_uv1_scale", "scale"), &SpatialMaterial::set_uv1_scale); - ClassDB::bind_method(D_METHOD("get_uv1_scale"), &SpatialMaterial::get_uv1_scale); + ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv1_triplanar_blend_sharpness); + ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv1_triplanar_blend_sharpness); - ClassDB::bind_method(D_METHOD("set_uv1_offset", "offset"), &SpatialMaterial::set_uv1_offset); - ClassDB::bind_method(D_METHOD("get_uv1_offset"), &SpatialMaterial::get_uv1_offset); + ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &BaseMaterial3D::set_uv2_scale); + ClassDB::bind_method(D_METHOD("get_uv2_scale"), &BaseMaterial3D::get_uv2_scale); - ClassDB::bind_method(D_METHOD("set_uv1_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv1_triplanar_blend_sharpness); - ClassDB::bind_method(D_METHOD("get_uv1_triplanar_blend_sharpness"), &SpatialMaterial::get_uv1_triplanar_blend_sharpness); + ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &BaseMaterial3D::set_uv2_offset); + ClassDB::bind_method(D_METHOD("get_uv2_offset"), &BaseMaterial3D::get_uv2_offset); - ClassDB::bind_method(D_METHOD("set_uv2_scale", "scale"), &SpatialMaterial::set_uv2_scale); - ClassDB::bind_method(D_METHOD("get_uv2_scale"), &SpatialMaterial::get_uv2_scale); + ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &BaseMaterial3D::set_uv2_triplanar_blend_sharpness); + ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &BaseMaterial3D::get_uv2_triplanar_blend_sharpness); - ClassDB::bind_method(D_METHOD("set_uv2_offset", "offset"), &SpatialMaterial::set_uv2_offset); - ClassDB::bind_method(D_METHOD("get_uv2_offset"), &SpatialMaterial::get_uv2_offset); + ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &BaseMaterial3D::set_billboard_mode); + ClassDB::bind_method(D_METHOD("get_billboard_mode"), &BaseMaterial3D::get_billboard_mode); - ClassDB::bind_method(D_METHOD("set_uv2_triplanar_blend_sharpness", "sharpness"), &SpatialMaterial::set_uv2_triplanar_blend_sharpness); - ClassDB::bind_method(D_METHOD("get_uv2_triplanar_blend_sharpness"), &SpatialMaterial::get_uv2_triplanar_blend_sharpness); + ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &BaseMaterial3D::set_particles_anim_h_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &BaseMaterial3D::get_particles_anim_h_frames); - ClassDB::bind_method(D_METHOD("set_billboard_mode", "mode"), &SpatialMaterial::set_billboard_mode); - ClassDB::bind_method(D_METHOD("get_billboard_mode"), &SpatialMaterial::get_billboard_mode); + ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &BaseMaterial3D::set_particles_anim_v_frames); + ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &BaseMaterial3D::get_particles_anim_v_frames); - ClassDB::bind_method(D_METHOD("set_particles_anim_h_frames", "frames"), &SpatialMaterial::set_particles_anim_h_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_h_frames"), &SpatialMaterial::get_particles_anim_h_frames); + ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &BaseMaterial3D::set_particles_anim_loop); + ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &BaseMaterial3D::get_particles_anim_loop); - ClassDB::bind_method(D_METHOD("set_particles_anim_v_frames", "frames"), &SpatialMaterial::set_particles_anim_v_frames); - ClassDB::bind_method(D_METHOD("get_particles_anim_v_frames"), &SpatialMaterial::get_particles_anim_v_frames); + ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax", "enable"), &BaseMaterial3D::set_heightmap_deep_parallax); + ClassDB::bind_method(D_METHOD("is_heightmap_deep_parallax_enabled"), &BaseMaterial3D::is_heightmap_deep_parallax_enabled); - ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &SpatialMaterial::set_particles_anim_loop); - ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop); + ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_min_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_min_layers); + ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_min_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_min_layers); - ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax); - ClassDB::bind_method(D_METHOD("is_depth_deep_parallax_enabled"), &SpatialMaterial::is_depth_deep_parallax_enabled); + ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_max_layers", "layer"), &BaseMaterial3D::set_heightmap_deep_parallax_max_layers); + ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_max_layers"), &BaseMaterial3D::get_heightmap_deep_parallax_max_layers); - ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_min_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_min_layers); - ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_min_layers"), &SpatialMaterial::get_depth_deep_parallax_min_layers); + ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_tangent", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent); + ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_tangent"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent); - ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers); - ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers); + ClassDB::bind_method(D_METHOD("set_heightmap_deep_parallax_flip_binormal", "flip"), &BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal); + ClassDB::bind_method(D_METHOD("get_heightmap_deep_parallax_flip_binormal"), &BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal); - ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_tangent", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_tangent); - ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_tangent"), &SpatialMaterial::get_depth_deep_parallax_flip_tangent); + ClassDB::bind_method(D_METHOD("set_grow", "amount"), &BaseMaterial3D::set_grow); + ClassDB::bind_method(D_METHOD("get_grow"), &BaseMaterial3D::get_grow); - ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_flip_binormal", "flip"), &SpatialMaterial::set_depth_deep_parallax_flip_binormal); - ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_flip_binormal"), &SpatialMaterial::get_depth_deep_parallax_flip_binormal); + ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &BaseMaterial3D::set_emission_operator); + ClassDB::bind_method(D_METHOD("get_emission_operator"), &BaseMaterial3D::get_emission_operator); - ClassDB::bind_method(D_METHOD("set_grow", "amount"), &SpatialMaterial::set_grow); - ClassDB::bind_method(D_METHOD("get_grow"), &SpatialMaterial::get_grow); + ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &BaseMaterial3D::set_ao_light_affect); + ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &BaseMaterial3D::get_ao_light_affect); - ClassDB::bind_method(D_METHOD("set_emission_operator", "operator"), &SpatialMaterial::set_emission_operator); - ClassDB::bind_method(D_METHOD("get_emission_operator"), &SpatialMaterial::get_emission_operator); + ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &BaseMaterial3D::set_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &BaseMaterial3D::get_alpha_scissor_threshold); - ClassDB::bind_method(D_METHOD("set_ao_light_affect", "amount"), &SpatialMaterial::set_ao_light_affect); - ClassDB::bind_method(D_METHOD("get_ao_light_affect"), &SpatialMaterial::get_ao_light_affect); + ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &BaseMaterial3D::set_grow_enabled); + ClassDB::bind_method(D_METHOD("is_grow_enabled"), &BaseMaterial3D::is_grow_enabled); - ClassDB::bind_method(D_METHOD("set_alpha_scissor_threshold", "threshold"), &SpatialMaterial::set_alpha_scissor_threshold); - ClassDB::bind_method(D_METHOD("get_alpha_scissor_threshold"), &SpatialMaterial::get_alpha_scissor_threshold); + ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &BaseMaterial3D::set_metallic_texture_channel); + ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &BaseMaterial3D::get_metallic_texture_channel); - ClassDB::bind_method(D_METHOD("set_grow_enabled", "enable"), &SpatialMaterial::set_grow_enabled); - ClassDB::bind_method(D_METHOD("is_grow_enabled"), &SpatialMaterial::is_grow_enabled); + ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &BaseMaterial3D::set_roughness_texture_channel); + ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &BaseMaterial3D::get_roughness_texture_channel); - ClassDB::bind_method(D_METHOD("set_metallic_texture_channel", "channel"), &SpatialMaterial::set_metallic_texture_channel); - ClassDB::bind_method(D_METHOD("get_metallic_texture_channel"), &SpatialMaterial::get_metallic_texture_channel); + ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &BaseMaterial3D::set_ao_texture_channel); + ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &BaseMaterial3D::get_ao_texture_channel); - ClassDB::bind_method(D_METHOD("set_roughness_texture_channel", "channel"), &SpatialMaterial::set_roughness_texture_channel); - ClassDB::bind_method(D_METHOD("get_roughness_texture_channel"), &SpatialMaterial::get_roughness_texture_channel); + ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &BaseMaterial3D::set_refraction_texture_channel); + ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &BaseMaterial3D::get_refraction_texture_channel); - ClassDB::bind_method(D_METHOD("set_ao_texture_channel", "channel"), &SpatialMaterial::set_ao_texture_channel); - ClassDB::bind_method(D_METHOD("get_ao_texture_channel"), &SpatialMaterial::get_ao_texture_channel); + ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &BaseMaterial3D::set_proximity_fade); + ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &BaseMaterial3D::is_proximity_fade_enabled); - ClassDB::bind_method(D_METHOD("set_refraction_texture_channel", "channel"), &SpatialMaterial::set_refraction_texture_channel); - ClassDB::bind_method(D_METHOD("get_refraction_texture_channel"), &SpatialMaterial::get_refraction_texture_channel); + ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &BaseMaterial3D::set_proximity_fade_distance); + ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &BaseMaterial3D::get_proximity_fade_distance); - ClassDB::bind_method(D_METHOD("set_proximity_fade", "enabled"), &SpatialMaterial::set_proximity_fade); - ClassDB::bind_method(D_METHOD("is_proximity_fade_enabled"), &SpatialMaterial::is_proximity_fade_enabled); + ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &BaseMaterial3D::set_distance_fade); + ClassDB::bind_method(D_METHOD("get_distance_fade"), &BaseMaterial3D::get_distance_fade); - ClassDB::bind_method(D_METHOD("set_proximity_fade_distance", "distance"), &SpatialMaterial::set_proximity_fade_distance); - ClassDB::bind_method(D_METHOD("get_proximity_fade_distance"), &SpatialMaterial::get_proximity_fade_distance); + ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &BaseMaterial3D::set_distance_fade_max_distance); + ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &BaseMaterial3D::get_distance_fade_max_distance); - ClassDB::bind_method(D_METHOD("set_distance_fade", "mode"), &SpatialMaterial::set_distance_fade); - ClassDB::bind_method(D_METHOD("get_distance_fade"), &SpatialMaterial::get_distance_fade); + ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &BaseMaterial3D::set_distance_fade_min_distance); + ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance); - ClassDB::bind_method(D_METHOD("set_distance_fade_max_distance", "distance"), &SpatialMaterial::set_distance_fade_max_distance); - ClassDB::bind_method(D_METHOD("get_distance_fade_max_distance"), &SpatialMaterial::get_distance_fade_max_distance); + ADD_GROUP("Transparency", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,AlphaScissor,DepthPrePass"), "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::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST); - ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &SpatialMaterial::set_distance_fade_min_distance); - ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &SpatialMaterial::get_distance_fade_min_distance); + ADD_GROUP("Shading", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,PerPixel,PerVertex"), "set_shading_mode", "get_shading_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); - ADD_GROUP("Flags", "flags_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_vertex_lighting"), "set_flag", "get_flag", FLAG_USE_VERTEX_LIGHTING); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_ensure_correct_normals"), "set_flag", "get_flag", FLAG_ENSURE_CORRECT_NORMALS); ADD_GROUP("Vertex Color", "vertex_color"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR); - ADD_GROUP("Parameters", "params_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never,Opaque Pre-Pass"), "set_depth_draw_mode", "get_depth_draw_mode"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_line_width", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_line_width", "get_line_width"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "params_billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "params_grow"), "set_grow_enabled", "is_grow_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "params_use_alpha_scissor"), "set_flag", "get_flag", FLAG_USE_ALPHA_SCISSOR); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "params_alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); - ADD_GROUP("Particles Anim", "particles_anim_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); - ADD_GROUP("Albedo", "albedo_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB); + + ADD_GROUP("ORM", "orm_"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orm_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ORM); ADD_GROUP("Metallic", "metallic_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_METALLIC); ADD_PROPERTY(PropertyInfo(Variant::INT, "metallic_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_metallic_texture_channel", "get_metallic_texture_channel"); ADD_GROUP("Roughness", "roughness_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ROUGHNESS); ADD_PROPERTY(PropertyInfo(Variant::INT, "roughness_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_roughness_texture_channel", "get_roughness_texture_channel"); ADD_GROUP("Emission", "emission_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_emission", "get_emission"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_emission_energy", "get_emission_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_emission_energy", "get_emission_energy"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_operator", PROPERTY_HINT_ENUM, "Add,Multiply"), "set_emission_operator", "get_emission_operator"); 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, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "emission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION); ADD_GROUP("NormalMap", "normal_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "normal_enabled"), "set_feature", "get_feature", FEATURE_NORMAL_MAPPING); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "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, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); + 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); ADD_GROUP("Rim", "rim_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "rim_enabled"), "set_feature", "get_feature", FEATURE_RIM); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim", "get_rim"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "rim_tint", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim_tint", "get_rim_tint"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_RIM); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim", "get_rim"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rim_tint", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_rim_tint", "get_rim_tint"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "rim_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_RIM); ADD_GROUP("Clearcoat", "clearcoat_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "clearcoat_enabled"), "set_feature", "get_feature", FEATURE_CLEARCOAT); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_CLEARCOAT); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat", "get_clearcoat"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "clearcoat_gloss", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_clearcoat_gloss", "get_clearcoat_gloss"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "clearcoat_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_CLEARCOAT); ADD_GROUP("Anisotropy", "anisotropy_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anisotropy_enabled"), "set_feature", "get_feature", FEATURE_ANISOTROPY); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "anisotropy", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_anisotropy", "get_anisotropy"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_FLOWMAP); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "anisotropy", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_anisotropy", "get_anisotropy"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anisotropy_flowmap", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_FLOWMAP); ADD_GROUP("Ambient Occlusion", "ao_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ao_light_affect", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_light_affect", "get_ao_light_affect"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ao_light_affect", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ao_light_affect", "get_ao_light_affect"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_on_uv2"), "set_flag", "get_flag", FLAG_AO_ON_UV2); ADD_PROPERTY(PropertyInfo(Variant::INT, "ao_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_ao_texture_channel", "get_ao_texture_channel"); - ADD_GROUP("Depth", "depth_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_depth_scale", "get_depth_scale"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_tangent"), "set_depth_deep_parallax_flip_tangent", "get_depth_deep_parallax_flip_tangent"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_flip_binormal"), "set_depth_deep_parallax_flip_binormal", "get_depth_deep_parallax_flip_binormal"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH); + ADD_GROUP("Height", "heightmap_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal"); + 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_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_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::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING); ADD_GROUP("Transmission", "transmission_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_TRANSMISSION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_TRANSMISSION); ADD_GROUP("Refraction", "refraction_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_REFRACTION); ADD_PROPERTY(PropertyInfo(Variant::INT, "refraction_texture_channel", PROPERTY_HINT_ENUM, "Red,Green,Blue,Alpha,Gray"), "set_refraction_texture_channel", "get_refraction_texture_channel"); ADD_GROUP("Detail", "detail_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK); ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_detail_blend_mode", "get_detail_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer", PROPERTY_HINT_ENUM, "UV1,UV2"), "set_detail_uv", "get_detail_uv"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL); ADD_GROUP("UV1", "uv1_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_scale"), "set_uv1_scale", "get_uv1_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv1_offset"), "set_uv1_offset", "get_uv1_offset"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_TRIPLANAR); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv1_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv1_triplanar_blend_sharpness", "get_uv1_triplanar_blend_sharpness"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv1_world_triplanar"), "set_flag", "get_flag", FLAG_UV1_USE_WORLD_TRIPLANAR); ADD_GROUP("UV2", "uv2_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_scale"), "set_uv2_scale", "get_uv2_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "uv2_offset"), "set_uv2_offset", "get_uv2_offset"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_TRIPLANAR); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "uv2_triplanar_sharpness", PROPERTY_HINT_EXP_EASING), "set_uv2_triplanar_blend_sharpness", "get_uv2_triplanar_blend_sharpness"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "uv2_world_triplanar"), "set_flag", "get_flag", FLAG_UV2_USE_WORLD_TRIPLANAR); + + ADD_GROUP("Sampling", "texture_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "texture_repeat"), "set_flag", "get_flag", FLAG_USE_TEXTURE_REPEAT); + + ADD_GROUP("Shadows", ""); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "shadow_to_opacity"), "set_flag", "get_flag", FLAG_USE_SHADOW_TO_OPACITY); + + ADD_GROUP("Billboard", "billboard_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "billboard_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Y-Billboard,Particle Billboard"), "set_billboard_mode", "get_billboard_mode"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "billboard_keep_scale"), "set_flag", "get_flag", FLAG_BILLBOARD_KEEP_SCALE); + + ADD_GROUP("Particles Anim", "particles_anim_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_h_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_h_frames", "get_particles_anim_h_frames"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "particles_anim_v_frames", PROPERTY_HINT_RANGE, "1,128,1"), "set_particles_anim_v_frames", "get_particles_anim_v_frames"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_anim_loop"), "set_particles_anim_loop", "get_particles_anim_loop"); + ADD_GROUP("Grow", "grow_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "grow"), "set_grow_enabled", "is_grow_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_amount", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_grow", "get_grow"); + ADD_GROUP("Transform", ""); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_point_size", "get_point_size"); ADD_GROUP("Proximity Fade", "proximity_fade_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enable"), "set_proximity_fade", "is_proximity_fade_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_proximity_fade_distance", "get_proximity_fade_distance"); ADD_GROUP("Distance Fade", "distance_fade_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "distance_fade_mode", PROPERTY_HINT_ENUM, "Disabled,PixelAlpha,PixelDither,ObjectDither"), "set_distance_fade", "get_distance_fade"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_min_distance", "get_distance_fade_min_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_max_distance", "get_distance_fade_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_min_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_min_distance", "get_distance_fade_min_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_distance_fade_max_distance", "get_distance_fade_max_distance"); BIND_ENUM_CONSTANT(TEXTURE_ALBEDO); BIND_ENUM_CONSTANT(TEXTURE_METALLIC); @@ -2250,26 +2360,45 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_CLEARCOAT); BIND_ENUM_CONSTANT(TEXTURE_FLOWMAP); BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION); - BIND_ENUM_CONSTANT(TEXTURE_DEPTH); + BIND_ENUM_CONSTANT(TEXTURE_HEIGHTMAP); BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING); BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION); BIND_ENUM_CONSTANT(TEXTURE_REFRACTION); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_NORMAL); + BIND_ENUM_CONSTANT(TEXTURE_ORM); BIND_ENUM_CONSTANT(TEXTURE_MAX); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC); + BIND_ENUM_CONSTANT(TEXTURE_FILTER_MAX); + BIND_ENUM_CONSTANT(DETAIL_UV_1); BIND_ENUM_CONSTANT(DETAIL_UV_2); - BIND_ENUM_CONSTANT(FEATURE_TRANSPARENT); + BIND_ENUM_CONSTANT(TRANSPARENCY_DISABLED); + BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA); + BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_SCISSOR); + BIND_ENUM_CONSTANT(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); + BIND_ENUM_CONSTANT(TRANSPARENCY_MAX); + + BIND_ENUM_CONSTANT(SHADING_MODE_UNSHADED); + BIND_ENUM_CONSTANT(SHADING_MODE_PER_PIXEL); + BIND_ENUM_CONSTANT(SHADING_MODE_PER_VERTEX); + BIND_ENUM_CONSTANT(SHADING_MODE_MAX); + BIND_ENUM_CONSTANT(FEATURE_EMISSION); BIND_ENUM_CONSTANT(FEATURE_NORMAL_MAPPING); BIND_ENUM_CONSTANT(FEATURE_RIM); BIND_ENUM_CONSTANT(FEATURE_CLEARCOAT); BIND_ENUM_CONSTANT(FEATURE_ANISOTROPY); BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION); - BIND_ENUM_CONSTANT(FEATURE_DEPTH_MAPPING); + BIND_ENUM_CONSTANT(FEATURE_HEIGHT_MAPPING); BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING); BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION); BIND_ENUM_CONSTANT(FEATURE_REFRACTION); @@ -2284,14 +2413,11 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(DEPTH_DRAW_OPAQUE_ONLY); BIND_ENUM_CONSTANT(DEPTH_DRAW_ALWAYS); BIND_ENUM_CONSTANT(DEPTH_DRAW_DISABLED); - BIND_ENUM_CONSTANT(DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); BIND_ENUM_CONSTANT(CULL_BACK); BIND_ENUM_CONSTANT(CULL_FRONT); BIND_ENUM_CONSTANT(CULL_DISABLED); - BIND_ENUM_CONSTANT(FLAG_UNSHADED); - BIND_ENUM_CONSTANT(FLAG_USE_VERTEX_LIGHTING); BIND_ENUM_CONSTANT(FLAG_DISABLE_DEPTH_TEST); BIND_ENUM_CONSTANT(FLAG_ALBEDO_FROM_VERTEX_COLOR); BIND_ENUM_CONSTANT(FLAG_SRGB_VERTEX_COLOR); @@ -2300,15 +2426,16 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_BILLBOARD_KEEP_SCALE); BIND_ENUM_CONSTANT(FLAG_UV1_USE_TRIPLANAR); BIND_ENUM_CONSTANT(FLAG_UV2_USE_TRIPLANAR); + BIND_ENUM_CONSTANT(FLAG_UV1_USE_WORLD_TRIPLANAR); + BIND_ENUM_CONSTANT(FLAG_UV2_USE_WORLD_TRIPLANAR); BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2); BIND_ENUM_CONSTANT(FLAG_EMISSION_ON_UV2); - BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR); - BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD); BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB); BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS); BIND_ENUM_CONSTANT(FLAG_DISABLE_AMBIENT_LIGHT); - BIND_ENUM_CONSTANT(FLAG_ENSURE_CORRECT_NORMALS); BIND_ENUM_CONSTANT(FLAG_USE_SHADOW_TO_OPACITY); + BIND_ENUM_CONSTANT(FLAG_USE_TEXTURE_REPEAT); + BIND_ENUM_CONSTANT(FLAG_INVERT_HEIGHTMAP); BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); @@ -2343,10 +2470,13 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER); } -SpatialMaterial::SpatialMaterial() : +BaseMaterial3D::BaseMaterial3D(bool p_orm) : element(this) { + orm = p_orm; // Initialize to the same values as the shader + transparency = TRANSPARENCY_DISABLED; + shading_mode = SHADING_MODE_PER_PIXEL; set_albedo(Color(1.0, 1.0, 1.0, 1.0)); set_specular(0.5); set_roughness(1.0); @@ -2359,11 +2489,10 @@ SpatialMaterial::SpatialMaterial() : set_clearcoat(1); set_clearcoat_gloss(0.5); set_anisotropy(0); - set_depth_scale(0.05); + set_heightmap_scale(0.05); set_subsurface_scattering_strength(0); set_transmission(Color(0, 0, 0)); set_refraction(0.05); - set_line_width(1); set_point_size(1); set_uv1_offset(Vector3(0, 0, 0)); set_uv1_scale(Vector3(1, 1, 1)); @@ -2395,11 +2524,11 @@ SpatialMaterial::SpatialMaterial() : set_grow(0.0); deep_parallax = false; - depth_parallax_flip_tangent = false; - depth_parallax_flip_binormal = false; - set_depth_deep_parallax_min_layers(8); - set_depth_deep_parallax_max_layers(32); - set_depth_deep_parallax_flip_tangent(false); //also sets binormal + heightmap_parallax_flip_tangent = false; + heightmap_parallax_flip_binormal = false; + set_heightmap_deep_parallax_min_layers(8); + set_heightmap_deep_parallax_max_layers(32); + set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal detail_uv = DETAIL_UV_1; blend_mode = BLEND_MODE_MIX; @@ -2409,6 +2538,8 @@ SpatialMaterial::SpatialMaterial() : for (int i = 0; i < FLAG_MAX; i++) { flags[i] = 0; } + flags[FLAG_USE_TEXTURE_REPEAT] = true; + diffuse_mode = DIFFUSE_BURLEY; specular_mode = SPECULAR_SCHLICK_GGX; @@ -2418,13 +2549,13 @@ SpatialMaterial::SpatialMaterial() : current_key.key = 0; current_key.invalid_key = 1; + texture_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; _queue_shader_change(); } -SpatialMaterial::~SpatialMaterial() { +BaseMaterial3D::~BaseMaterial3D() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -2436,7 +2567,96 @@ SpatialMaterial::~SpatialMaterial() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } +} - if (material_mutex) - material_mutex->unlock(); +////////////////////// + +#ifndef DISABLE_DEPRECATED +// Kept for compatibility from 3.x to 4.0. +bool StandardMaterial3D::_set(const StringName &p_name, const Variant &p_value) { + if (p_name == "flags_transparent") { + bool transparent = p_value; + if (transparent) { + set_transparency(TRANSPARENCY_ALPHA); + } + return true; + } else if (p_name == "flags_unshaded") { + bool unshaded = p_value; + if (unshaded) { + set_shading_mode(SHADING_MODE_UNSHADED); + } + return true; + } else if (p_name == "flags_vertex_lighting") { + bool vertex_lit = p_value; + if (vertex_lit && get_shading_mode() != SHADING_MODE_UNSHADED) { + set_shading_mode(SHADING_MODE_PER_VERTEX); + } + return true; + } else if (p_name == "params_use_alpha_scissor") { + bool use_scissor = p_value; + if (use_scissor) { + set_transparency(TRANSPARENCY_ALPHA_SCISSOR); + } + return true; + } else if (p_name == "params_depth_draw_mode") { + int mode = p_value; + if (mode == 3) { + set_transparency(TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); + } + return true; + } else if (p_name == "depth_enabled") { + bool enabled = p_value; + if (enabled) { + set_feature(FEATURE_HEIGHT_MAPPING, true); + set_flag(FLAG_INVERT_HEIGHTMAP, true); + } + return true; + } else { + static const Pair<const char *, const char *> remaps[] = { + { "flags_use_shadow_to_opacity", "shadow_to_opacity" }, + { "flags_use_shadow_to_opacity", "shadow_to_opacity" }, + { "flags_no_depth_test", "no_depth_test" }, + { "flags_use_point_size", "use_point_size" }, + { "flags_fixed_size", "fixed_Size" }, + { "flags_albedo_tex_force_srg", "albedo_tex_force_srgb" }, + { "flags_do_not_receive_shadows", "disable_receive_shadows" }, + { "flags_disable_ambient_light", "disable_ambient_light" }, + { "params_diffuse_mode", "diffuse_mode" }, + { "params_specular_mode", "specular_mode" }, + { "params_blend_mode", "blend_mode" }, + { "params_cull_mode", "cull_mode" }, + { "params_depth_draw_mode", "params_depth_draw_mode" }, + { "params_point_size", "point_size" }, + { "params_billboard_mode", "billboard_mode" }, + { "params_billboard_keep_scale", "billboard_keep_scale" }, + { "params_grow", "grow" }, + { "params_grow_amount", "grow_amount" }, + { "params_alpha_scissor_threshold", "alpha_scissor_threshold" }, + + { "depth_scale", "heightmap_scale" }, + { "depth_deep_parallax", "heightmap_deep_parallax" }, + { "depth_min_layers", "heightmap_min_layers" }, + { "depth_max_layers", "heightmap_max_layers" }, + { "depth_flip_tangent", "heightmap_flip_tangent" }, + { "depth_flip_binormal", "heightmap_flip_binormal" }, + { "depth_texture", "heightmap_texture" }, + + { NULL, NULL }, + }; + + int idx = 0; + while (remaps[idx].first) { + if (p_name == remaps[idx].first) { + set(remaps[idx].second, p_value); + return true; + } + idx++; + } + + print_line("remapped parameter not found: " + String(p_name)); + return true; + } + + return false; } +#endif // DISABLE_DEPRECATED diff --git a/scene/resources/material.h b/scene/resources/material.h index 8e66011bec..fc77226fb9 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -106,9 +106,11 @@ public: ~ShaderMaterial(); }; -class SpatialMaterial : public Material { +class StandardMaterial3D; - GDCLASS(SpatialMaterial, Material); +class BaseMaterial3D : public Material { + + GDCLASS(BaseMaterial3D, Material); public: enum TextureParam { @@ -121,31 +123,56 @@ public: TEXTURE_CLEARCOAT, TEXTURE_FLOWMAP, TEXTURE_AMBIENT_OCCLUSION, - TEXTURE_DEPTH, + TEXTURE_HEIGHTMAP, TEXTURE_SUBSURFACE_SCATTERING, TEXTURE_TRANSMISSION, TEXTURE_REFRACTION, TEXTURE_DETAIL_MASK, TEXTURE_DETAIL_ALBEDO, TEXTURE_DETAIL_NORMAL, + TEXTURE_ORM, TEXTURE_MAX }; + enum TextureFilter { + TEXTURE_FILTER_NEAREST, + TEXTURE_FILTER_LINEAR, + TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, + TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, + TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, + TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, + TEXTURE_FILTER_MAX + }; + enum DetailUV { DETAIL_UV_1, DETAIL_UV_2 }; + enum Transparency { + TRANSPARENCY_DISABLED, + TRANSPARENCY_ALPHA, + TRANSPARENCY_ALPHA_SCISSOR, + TRANSPARENCY_ALPHA_DEPTH_PRE_PASS, + TRANSPARENCY_MAX, + }; + + enum ShadingMode { + SHADING_MODE_UNSHADED, + SHADING_MODE_PER_PIXEL, + SHADING_MODE_PER_VERTEX, + SHADING_MODE_MAX + }; + enum Feature { - FEATURE_TRANSPARENT, FEATURE_EMISSION, FEATURE_NORMAL_MAPPING, FEATURE_RIM, FEATURE_CLEARCOAT, FEATURE_ANISOTROPY, FEATURE_AMBIENT_OCCLUSION, - FEATURE_DEPTH_MAPPING, + FEATURE_HEIGHT_MAPPING, FEATURE_SUBSURACE_SCATTERING, FEATURE_TRANSMISSION, FEATURE_REFRACTION, @@ -164,8 +191,6 @@ public: DEPTH_DRAW_OPAQUE_ONLY, DEPTH_DRAW_ALWAYS, DEPTH_DRAW_DISABLED, - DEPTH_DRAW_ALPHA_OPAQUE_PREPASS - }; enum CullMode { @@ -175,8 +200,6 @@ public: }; enum Flags { - FLAG_UNSHADED, - FLAG_USE_VERTEX_LIGHTING, FLAG_DISABLE_DEPTH_TEST, FLAG_ALBEDO_FROM_VERTEX_COLOR, FLAG_SRGB_VERTEX_COLOR, @@ -185,15 +208,16 @@ public: FLAG_BILLBOARD_KEEP_SCALE, FLAG_UV1_USE_TRIPLANAR, FLAG_UV2_USE_TRIPLANAR, - FLAG_TRIPLANAR_USE_WORLD, + FLAG_UV1_USE_WORLD_TRIPLANAR, + FLAG_UV2_USE_WORLD_TRIPLANAR, FLAG_AO_ON_UV2, FLAG_EMISSION_ON_UV2, - FLAG_USE_ALPHA_SCISSOR, FLAG_ALBEDO_TEXTURE_FORCE_SRGB, FLAG_DONT_RECEIVE_SHADOWS, - FLAG_ENSURE_CORRECT_NORMALS, FLAG_DISABLE_AMBIENT_LIGHT, FLAG_USE_SHADOW_TO_OPACITY, + FLAG_USE_TEXTURE_REPEAT, + FLAG_INVERT_HEIGHTMAP, FLAG_MAX }; @@ -244,12 +268,12 @@ private: union MaterialKey { struct { - uint64_t feature_mask : 12; + uint64_t feature_mask : FEATURE_MAX; uint64_t detail_uv : 1; uint64_t blend_mode : 2; uint64_t depth_draw_mode : 2; uint64_t cull_mode : 2; - uint64_t flags : 19; + uint64_t flags : FLAG_MAX; uint64_t detail_blend_mode : 2; uint64_t diffuse_mode : 3; uint64_t specular_mode : 3; @@ -260,8 +284,10 @@ private: uint64_t proximity_fade : 1; uint64_t distance_fade : 2; uint64_t emission_op : 1; - uint64_t texture_metallic : 1; - uint64_t texture_roughness : 1; + uint64_t texture_filter : 3; + uint64_t transparency : 2; + uint64_t shading_mode : 2; + uint64_t roughness_channel : 3; }; uint64_t key; @@ -293,6 +319,10 @@ private: mk.blend_mode = blend_mode; mk.depth_draw_mode = depth_draw_mode; mk.cull_mode = cull_mode; + mk.texture_filter = texture_filter; + mk.transparency = transparency; + mk.shading_mode = shading_mode; + mk.roughness_channel = roughness_texture_channel; for (int i = 0; i < FLAG_MAX; i++) { if (flags[i]) { mk.flags |= ((uint64_t)1 << i); @@ -307,8 +337,6 @@ private: mk.proximity_fade = proximity_fade_enabled; mk.distance_fade = distance_fade; mk.emission_op = emission_op; - mk.texture_metallic = textures[TEXTURE_METALLIC].is_valid() ? 1 : 0; - mk.texture_roughness = textures[TEXTURE_ROUGHNESS].is_valid() ? 1 : 0; return mk; } @@ -326,7 +354,7 @@ private: StringName clearcoat; StringName clearcoat_gloss; StringName anisotropy; - StringName depth_scale; + StringName heightmap_scale; StringName subsurface_scattering_strength; StringName transmission; StringName refraction; @@ -338,9 +366,9 @@ private: StringName particles_anim_h_frames; StringName particles_anim_v_frames; StringName particles_anim_loop; - StringName depth_min_layers; - StringName depth_max_layers; - StringName depth_flip; + StringName heightmap_min_layers; + StringName heightmap_max_layers; + StringName heightmap_flip; StringName uv1_blend_sharpness; StringName uv2_blend_sharpness; StringName grow; @@ -350,27 +378,28 @@ private: StringName ao_light_affect; StringName metallic_texture_channel; - StringName roughness_texture_channel; StringName ao_texture_channel; StringName clearcoat_texture_channel; StringName rim_texture_channel; - StringName depth_texture_channel; + StringName heightmap_texture_channel; StringName refraction_texture_channel; StringName alpha_scissor_threshold; StringName texture_names[TEXTURE_MAX]; }; - static Mutex *material_mutex; - static SelfList<SpatialMaterial>::List *dirty_materials; + static Mutex material_mutex; + static SelfList<BaseMaterial3D>::List *dirty_materials; static ShaderNames *shader_names; - SelfList<SpatialMaterial> element; + SelfList<BaseMaterial3D> element; void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + bool orm; + Color albedo; float specular; float metallic; @@ -383,11 +412,10 @@ private: float clearcoat; float clearcoat_gloss; float anisotropy; - float depth_scale; + float heightmap_scale; float subsurface_scattering_strength; Color transmission; float refraction; - float line_width; float point_size; float alpha_scissor_threshold; bool grow_enabled; @@ -396,6 +424,10 @@ private: int particles_anim_h_frames; int particles_anim_v_frames; bool particles_anim_loop; + Transparency transparency; + ShadingMode shading_mode; + + TextureFilter texture_filter; Vector3 uv1_scale; Vector3 uv1_offset; @@ -410,8 +442,8 @@ private: bool deep_parallax; int deep_parallax_min_layers; int deep_parallax_max_layers; - bool depth_parallax_flip_tangent; - bool depth_parallax_flip_binormal; + bool heightmap_parallax_flip_tangent; + bool heightmap_parallax_flip_binormal; bool proximity_fade_enabled; float proximity_fade_distance; @@ -437,13 +469,13 @@ private: bool features[FEATURE_MAX]; - Ref<Texture> textures[TEXTURE_MAX]; + Ref<Texture2D> textures[TEXTURE_MAX]; _FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const; static const int MAX_MATERIALS_FOR_2D = 128; - static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff + static Ref<StandardMaterial3D> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff void _validate_high_end(const String &text, PropertyInfo &property) const; @@ -492,23 +524,23 @@ public: void set_anisotropy(float p_anisotropy); float get_anisotropy() const; - void set_depth_scale(float p_depth_scale); - float get_depth_scale() const; + void set_heightmap_scale(float p_heightmap_scale); + float get_heightmap_scale() const; - void set_depth_deep_parallax(bool p_enable); - bool is_depth_deep_parallax_enabled() const; + void set_heightmap_deep_parallax(bool p_enable); + bool is_heightmap_deep_parallax_enabled() const; - void set_depth_deep_parallax_min_layers(int p_layer); - int get_depth_deep_parallax_min_layers() const; + void set_heightmap_deep_parallax_min_layers(int p_layer); + int get_heightmap_deep_parallax_min_layers() const; - void set_depth_deep_parallax_max_layers(int p_layer); - int get_depth_deep_parallax_max_layers() const; + void set_heightmap_deep_parallax_max_layers(int p_layer); + int get_heightmap_deep_parallax_max_layers() const; - void set_depth_deep_parallax_flip_tangent(bool p_flip); - bool get_depth_deep_parallax_flip_tangent() const; + void set_heightmap_deep_parallax_flip_tangent(bool p_flip); + bool get_heightmap_deep_parallax_flip_tangent() const; - void set_depth_deep_parallax_flip_binormal(bool p_flip); - bool get_depth_deep_parallax_flip_binormal() const; + void set_heightmap_deep_parallax_flip_binormal(bool p_flip); + bool get_heightmap_deep_parallax_flip_binormal() const; void set_subsurface_scattering_strength(float p_subsurface_scattering_strength); float get_subsurface_scattering_strength() const; @@ -519,12 +551,15 @@ public: void set_refraction(float p_refraction); float get_refraction() const; - void set_line_width(float p_line_width); - float get_line_width() const; - void set_point_size(float p_point_size); float get_point_size() const; + void set_transparency(Transparency p_transparency); + Transparency get_transparency() const; + + void set_shading_mode(ShadingMode p_shading_mode); + ShadingMode get_shading_mode() const; + void set_detail_uv(DetailUV p_detail_uv); DetailUV get_detail_uv() const; @@ -549,10 +584,13 @@ public: void set_flag(Flags p_flag, bool p_enabled); bool get_flag(Flags p_flag) const; - void set_texture(TextureParam p_param, const Ref<Texture> &p_texture); - Ref<Texture> get_texture(TextureParam p_param) const; + void set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_texture(TextureParam p_param) const; // Used only for shader material conversion - Ref<Texture> get_texture_by_name(StringName p_name) const; + Ref<Texture2D> get_texture_by_name(StringName p_name) const; + + void set_texture_filter(TextureFilter p_filter); + TextureFilter get_texture_filter() const; void set_feature(Feature p_feature, bool p_enabled); bool get_feature(Feature p_feature) const; @@ -634,23 +672,46 @@ public: virtual Shader::Mode get_shader_mode() const; - SpatialMaterial(); - virtual ~SpatialMaterial(); + BaseMaterial3D(bool p_orm); + virtual ~BaseMaterial3D(); }; -VARIANT_ENUM_CAST(SpatialMaterial::TextureParam) -VARIANT_ENUM_CAST(SpatialMaterial::DetailUV) -VARIANT_ENUM_CAST(SpatialMaterial::Feature) -VARIANT_ENUM_CAST(SpatialMaterial::BlendMode) -VARIANT_ENUM_CAST(SpatialMaterial::DepthDrawMode) -VARIANT_ENUM_CAST(SpatialMaterial::CullMode) -VARIANT_ENUM_CAST(SpatialMaterial::Flags) -VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode) -VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode) -VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode) -VARIANT_ENUM_CAST(SpatialMaterial::TextureChannel) -VARIANT_ENUM_CAST(SpatialMaterial::EmissionOperator) -VARIANT_ENUM_CAST(SpatialMaterial::DistanceFadeMode) +VARIANT_ENUM_CAST(BaseMaterial3D::TextureParam) +VARIANT_ENUM_CAST(BaseMaterial3D::TextureFilter) +VARIANT_ENUM_CAST(BaseMaterial3D::ShadingMode) +VARIANT_ENUM_CAST(BaseMaterial3D::Transparency) +VARIANT_ENUM_CAST(BaseMaterial3D::DetailUV) +VARIANT_ENUM_CAST(BaseMaterial3D::Feature) +VARIANT_ENUM_CAST(BaseMaterial3D::BlendMode) +VARIANT_ENUM_CAST(BaseMaterial3D::DepthDrawMode) +VARIANT_ENUM_CAST(BaseMaterial3D::CullMode) +VARIANT_ENUM_CAST(BaseMaterial3D::Flags) +VARIANT_ENUM_CAST(BaseMaterial3D::DiffuseMode) +VARIANT_ENUM_CAST(BaseMaterial3D::SpecularMode) +VARIANT_ENUM_CAST(BaseMaterial3D::BillboardMode) +VARIANT_ENUM_CAST(BaseMaterial3D::TextureChannel) +VARIANT_ENUM_CAST(BaseMaterial3D::EmissionOperator) +VARIANT_ENUM_CAST(BaseMaterial3D::DistanceFadeMode) + +class StandardMaterial3D : public BaseMaterial3D { + GDCLASS(StandardMaterial3D, BaseMaterial3D) +protected: +#ifndef DISABLE_DEPRECATED + // Kept for compatibility from 3.x to 4.0. + bool _set(const StringName &p_name, const Variant &p_value); +#endif + +public: + StandardMaterial3D() : + BaseMaterial3D(false) {} +}; + +class ORMMaterial3D : public BaseMaterial3D { + GDCLASS(ORMMaterial3D, BaseMaterial3D) +public: + ORMMaterial3D() : + BaseMaterial3D(true) {} +}; ////////////////////// diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 0599920303..a063b7f74f 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -63,9 +63,9 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { if (facecount == 0 || (facecount % 3) != 0) return triangle_mesh; - PoolVector<Vector3> faces; + Vector<Vector3> faces; faces.resize(facecount); - PoolVector<Vector3>::Write facesw = faces.write(); + Vector3 *facesw = faces.ptrw(); int widx = 0; @@ -78,14 +78,14 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>()); int vc = surface_get_array_len(i); - PoolVector<Vector3> vertices = a[ARRAY_VERTEX]; - PoolVector<Vector3>::Read vr = vertices.read(); + Vector<Vector3> vertices = a[ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { int ic = surface_get_array_index_len(i); - PoolVector<int> indices = a[ARRAY_INDEX]; - PoolVector<int>::Read ir = indices.read(); + Vector<int> indices = a[ARRAY_INDEX]; + const int *ir = indices.ptr(); for (int j = 0; j < ic; j++) { int index = ir[j]; @@ -99,8 +99,6 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { } } - facesw.release(); - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); @@ -118,15 +116,15 @@ void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { if (tm.is_null()) return; - PoolVector<int> triangle_indices; + Vector<int> triangle_indices; tm->get_indices(&triangle_indices); const int triangles_num = tm->get_triangles().size(); - PoolVector<Vector3> vertices = tm->get_vertices(); + Vector<Vector3> vertices = tm->get_vertices(); debug_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line - PoolVector<int>::Read ind_r = triangle_indices.read(); - PoolVector<Vector3>::Read ver_r = vertices.read(); + const int *ind_r = triangle_indices.ptr(); + const Vector3 *ver_r = vertices.ptr(); for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) { // Triangle line 1 debug_lines.write[j + 0] = ver_r[ind_r[x + 0]]; @@ -148,7 +146,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { if (tm.is_null()) return; - PoolVector<Vector3> vertices = tm->get_vertices(); + Vector<Vector3> vertices = tm->get_vertices(); int vertices_size = vertices.size(); r_points.resize(vertices_size); @@ -159,23 +157,23 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { bool Mesh::surface_is_softbody_friendly(int p_idx) const { const uint32_t surface_format = surface_get_format(p_idx); - return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_VERTEX)) && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL))); + return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL))); } -PoolVector<Face3> Mesh::get_faces() const { +Vector<Face3> Mesh::get_faces() const { Ref<TriangleMesh> tm = generate_triangle_mesh(); if (tm.is_valid()) return tm->get_faces(); - return PoolVector<Face3>(); + return Vector<Face3>(); /* for (int i=0;i<surfaces.size();i++) { if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES ) continue; - PoolVector<int> indices; - PoolVector<Vector3> vertices; + Vector<int> indices; + Vector<Vector3> vertices; vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX); @@ -196,10 +194,10 @@ PoolVector<Face3> Mesh::get_faces() const { if (len<=0) continue; - PoolVector<int>::Read indicesr = indices.read(); + const int* indicesr = indices.ptr(); const int *indicesptr = indicesr.ptr(); - PoolVector<Vector3>::Read verticesr = vertices.read(); + const Vector3* verticesr = vertices.ptr(); const Vector3 *verticesptr = verticesr.ptr(); int old_faces=faces.size(); @@ -207,7 +205,7 @@ PoolVector<Face3> Mesh::get_faces() const { faces.resize(new_faces); - PoolVector<Face3>::Write facesw = faces.write(); + Face3* facesw = faces.ptrw(); Face3 *facesptr=facesw.ptr(); @@ -230,13 +228,13 @@ PoolVector<Face3> Mesh::get_faces() const { Ref<Shape> Mesh::create_convex_shape() const { - PoolVector<Vector3> vertices; + Vector<Vector3> vertices; for (int i = 0; i < get_surface_count(); i++) { Array a = surface_get_arrays(i); ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape>()); - PoolVector<Vector3> v = a[ARRAY_VERTEX]; + Vector<Vector3> v = a[ARRAY_VERTEX]; vertices.append_array(v); } @@ -247,11 +245,11 @@ Ref<Shape> Mesh::create_convex_shape() const { Ref<Shape> Mesh::create_trimesh_shape() const { - PoolVector<Face3> faces = get_faces(); + Vector<Face3> faces = get_faces(); if (faces.size() == 0) return Ref<Shape>(); - PoolVector<Vector3> face_points; + Vector<Vector3> face_points; face_points.resize(faces.size() * 3); for (int i = 0; i < face_points.size(); i++) { @@ -279,7 +277,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { if (i == 0) { arrays = a; - PoolVector<Vector3> v = a[ARRAY_VERTEX]; + Vector<Vector3> v = a[ARRAY_VERTEX]; index_accum += v.size(); } else { @@ -297,8 +295,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { case ARRAY_VERTEX: case ARRAY_NORMAL: { - PoolVector<Vector3> dst = arrays[j]; - PoolVector<Vector3> src = a[j]; + Vector<Vector3> dst = arrays[j]; + Vector<Vector3> src = a[j]; if (j == ARRAY_VERTEX) vcount = src.size(); if (dst.size() == 0 || src.size() == 0) { @@ -312,8 +310,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { case ARRAY_BONES: case ARRAY_WEIGHTS: { - PoolVector<real_t> dst = arrays[j]; - PoolVector<real_t> src = a[j]; + Vector<real_t> dst = arrays[j]; + Vector<real_t> src = a[j]; if (dst.size() == 0 || src.size() == 0) { arrays[j] = Variant(); continue; @@ -323,8 +321,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { } break; case ARRAY_COLOR: { - PoolVector<Color> dst = arrays[j]; - PoolVector<Color> src = a[j]; + Vector<Color> dst = arrays[j]; + Vector<Color> src = a[j]; if (dst.size() == 0 || src.size() == 0) { arrays[j] = Variant(); continue; @@ -335,8 +333,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { } break; case ARRAY_TEX_UV: case ARRAY_TEX_UV2: { - PoolVector<Vector2> dst = arrays[j]; - PoolVector<Vector2> src = a[j]; + Vector<Vector2> dst = arrays[j]; + Vector<Vector2> src = a[j]; if (dst.size() == 0 || src.size() == 0) { arrays[j] = Variant(); continue; @@ -346,15 +344,15 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { } break; case ARRAY_INDEX: { - PoolVector<int> dst = arrays[j]; - PoolVector<int> src = a[j]; + Vector<int> dst = arrays[j]; + Vector<int> src = a[j]; if (dst.size() == 0 || src.size() == 0) { arrays[j] = Variant(); continue; } { int ss = src.size(); - PoolVector<int>::Write w = src.write(); + int *w = src.ptrw(); for (int k = 0; k < ss; k++) { w[k] += index_accum; } @@ -372,18 +370,18 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>()); { - PoolVector<int>::Write ir; - PoolVector<int> indices = arrays[ARRAY_INDEX]; + int *ir; + Vector<int> indices = arrays[ARRAY_INDEX]; bool has_indices = false; - PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX]; + Vector<Vector3> vertices = arrays[ARRAY_VERTEX]; int vc = vertices.size(); ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>()); - PoolVector<Vector3>::Write r = vertices.write(); + Vector3 *r = vertices.ptrw(); if (indices.size()) { ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>()); vc = indices.size(); - ir = indices.write(); + ir = indices.ptrw(); has_indices = true; } @@ -440,14 +438,13 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { r[i] = t; } - r.release(); arrays[ARRAY_VERTEX] = vertices; if (!has_indices) { - PoolVector<int> new_indices; + Vector<int> new_indices; new_indices.resize(vertices.size()); - PoolVector<int>::Write iw = new_indices.write(); + int *iw = new_indices.ptrw(); for (int j = 0; j < vc2; j += 3) { @@ -456,7 +453,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { iw[j + 2] = j + 1; } - iw.release(); arrays[ARRAY_INDEX] = new_indices; } else { @@ -465,7 +461,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { SWAP(ir[j + 1], ir[j + 2]); } - ir.release(); arrays[ARRAY_INDEX] = indices; } } @@ -500,10 +495,8 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP); - BIND_ENUM_CONSTANT(PRIMITIVE_LINE_LOOP); BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES); BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP); - BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_FAN); BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); @@ -518,19 +511,14 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BASE); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_VERTEX); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BONES); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); - BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_16_BIT_BONES); BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); @@ -555,10 +543,10 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const { ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape> >()); - PoolVector<Face3> faces = get_faces(); + Vector<Face3> faces = get_faces(); Vector<Face3> f3; f3.resize(faces.size()); - PoolVector<Face3>::Read f = faces.read(); + const Face3 *f = faces.ptr(); for (int i = 0; i < f3.size(); i++) { f3.write[i] = f[i]; } @@ -575,10 +563,10 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const { points.insert(decomposed[i][j].vertex[2]); } - PoolVector<Vector3> convex_points; + Vector<Vector3> convex_points; convex_points.resize(points.size()); { - PoolVector<Vector3>::Write w = convex_points.write(); + Vector3 *w = convex_points.ptrw(); int idx = 0; for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) { w[idx++] = E->get(); @@ -597,15 +585,133 @@ Vector<Ref<Shape> > Mesh::convex_decompose() const { Mesh::Mesh() { } +static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) { + + bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE))); + bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES); + bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2)); + bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2)); + + print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32)); + + if (!vertex_16bit && !bone_8 && !weight_32) { + return p_src; + } + + bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1)); + + uint32_t src_stride = p_src.size() / p_elements; + uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0); + + Vector<uint8_t> ret = p_src; + + ret.resize(dst_stride * p_elements); + { + uint8_t *w = ret.ptrw(); + const uint8_t *r = p_src.ptr(); + + for (uint32_t i = 0; i < p_elements; i++) { + + uint32_t remaining = src_stride; + const uint8_t *src = (const uint8_t *)(r + src_stride * i); + uint8_t *dst = (uint8_t *)(w + dst_stride * i); + + if (!vertex_2d) { //3D + if (vertex_16bit) { + float *dstw = (float *)dst; + const uint16_t *srcr = (const uint16_t *)src; + dstw[0] = Math::half_to_float(srcr[0]); + dstw[1] = Math::half_to_float(srcr[1]); + dstw[2] = Math::half_to_float(srcr[2]); + remaining -= 8; + src += 8; + } else { + src += 12; + remaining -= 12; + } + dst += 12; + } else { + if (vertex_16bit) { + float *dstw = (float *)dst; + const uint16_t *srcr = (const uint16_t *)src; + dstw[0] = Math::half_to_float(srcr[0]); + dstw[1] = Math::half_to_float(srcr[1]); + remaining -= 4; + src += 4; + } else { + src += 8; + remaining -= 8; + } + dst += 8; + } + + if (has_bones) { + + remaining -= bone_8 ? 4 : 8; + remaining -= weight_32 ? 16 : 8; + } + + for (uint32_t j = 0; j < remaining; j++) { + dst[j] = src[j]; + } + + if (has_bones) { + + dst += remaining; + src += remaining; + + if (bone_8) { + + const uint8_t *src_bones = (const uint8_t *)src; + uint16_t *dst_bones = (uint16_t *)dst; + + dst_bones[0] = src_bones[0]; + dst_bones[1] = src_bones[1]; + dst_bones[2] = src_bones[2]; + dst_bones[3] = src_bones[3]; + + src += 4; + } else { + for (uint32_t j = 0; j < 8; j++) { + dst[j] = src[j]; + } + + src += 8; + } + + dst += 8; + + if (weight_32) { + + const float *src_weights = (const float *)src; + uint16_t *dst_weights = (uint16_t *)dst; + + dst_weights[0] = CLAMP(src_weights[0] * 65535, 0, 65535); //16bits unorm + dst_weights[1] = CLAMP(src_weights[1] * 65535, 0, 65535); + dst_weights[2] = CLAMP(src_weights[2] * 65535, 0, 65535); + dst_weights[3] = CLAMP(src_weights[3] * 65535, 0, 65535); + + } else { + for (uint32_t j = 0; j < 8; j++) { + dst[j] = src[j]; + } + } + } + } + } + + return ret; +} + bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; if (p_name == "blend_shape/names") { - PoolVector<String> sk = p_value; + Vector<String> sk = p_value; int sz = sk.size(); - PoolVector<String>::Read r = sk.read(); + const String *r = sk.ptr(); for (int i = 0; i < sz; i++) add_blend_shape(r[i]); return true; @@ -631,9 +737,13 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { return true; } +#ifndef DISABLE_DEPRECATED + // Kept for compatibility from 3.x to 4.0. if (!sname.begins_with("surfaces")) return false; + WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene."); + int idx = sname.get_slicec('/', 1).to_int(); String what = sname.get_slicec('/', 2); @@ -644,14 +754,15 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { ERR_FAIL_COND_V(!d.has("primitive"), false); if (d.has("arrays")) { - //old format + //oldest format (2.x) ERR_FAIL_COND_V(!d.has("morph_arrays"), false); add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]); } else if (d.has("array_data")) { - - PoolVector<uint8_t> array_data = d["array_data"]; - PoolVector<uint8_t> array_index_data; + //print_line("array data (old style"); + //older format (3.x) + Vector<uint8_t> array_data = d["array_data"]; + Vector<uint8_t> array_index_data; if (d.has("array_index_data")) array_index_data = d["array_index_data"]; @@ -660,23 +771,44 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { uint32_t primitive = d["primitive"]; + uint32_t primitive_remap[7] = { + PRIMITIVE_POINTS, + PRIMITIVE_LINES, + PRIMITIVE_LINE_STRIP, + PRIMITIVE_LINES, + PRIMITIVE_TRIANGLES, + PRIMITIVE_TRIANGLE_STRIP, + PRIMITIVE_TRIANGLE_STRIP + }; + + primitive = primitive_remap[primitive]; //compatibility + ERR_FAIL_COND_V(!d.has("vertex_count"), false); int vertex_count = d["vertex_count"]; + array_data = _fix_array_compatibility(array_data, format, vertex_count); + int index_count = 0; if (d.has("index_count")) index_count = d["index_count"]; - Vector<PoolVector<uint8_t> > blend_shapes; + Vector<Vector<uint8_t> > blend_shapes; if (d.has("blend_shape_data")) { Array blend_shape_data = d["blend_shape_data"]; for (int i = 0; i < blend_shape_data.size(); i++) { - PoolVector<uint8_t> shape = blend_shape_data[i]; + Vector<uint8_t> shape = blend_shape_data[i]; + shape = _fix_array_compatibility(shape, format, vertex_count); + blend_shapes.push_back(shape); } } + //clear unused flags + print_line("format pre: " + itos(format)); + format &= ~uint32_t((1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE)) | (ARRAY_COMPRESS_INDEX << 2) | (ARRAY_COMPRESS_TEX_UV2 << 2)); + print_line("format post: " + itos(format)); + ERR_FAIL_COND_V(!d.has("aabb"), false); AABB aabb = d["aabb"]; @@ -705,10 +837,203 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { return true; } +#endif // DISABLE_DEPRECATED return false; } +Array ArrayMesh::_get_surfaces() const { + + if (mesh.is_null()) { + return Array(); + } + + Array ret; + for (int i = 0; i < surfaces.size(); i++) { + VisualServer::SurfaceData surface = VS::get_singleton()->mesh_get_surface(mesh, i); + Dictionary data; + data["format"] = surface.format; + data["primitive"] = surface.primitive; + data["vertex_data"] = surface.vertex_data; + data["vertex_count"] = surface.vertex_count; + data["aabb"] = surface.aabb; + if (surface.index_count) { + data["index_data"] = surface.index_data; + data["index_count"] = surface.index_count; + }; + + Array lods; + for (int j = 0; j < surface.lods.size(); j++) { + lods.push_back(surface.lods[j].edge_length); + lods.push_back(surface.lods[j].index_data); + } + + if (lods.size()) { + data["lods"] = lods; + } + + Array bone_aabbs; + for (int j = 0; j < surface.bone_aabbs.size(); j++) { + bone_aabbs.push_back(surface.bone_aabbs[j]); + } + if (bone_aabbs.size()) { + data["bone_aabbs"] = bone_aabbs; + } + + Array blend_shapes; + for (int j = 0; j < surface.blend_shapes.size(); j++) { + blend_shapes.push_back(surface.blend_shapes[j]); + } + + if (surfaces[i].material.is_valid()) { + data["material"] = surfaces[i].material; + } + + if (surfaces[i].name != String()) { + data["name"] = surfaces[i].name; + } + + if (surfaces[i].is_2d) { + data["2d"] = true; + } + + ret.push_back(data); + } + print_line("Saving surfaces: " + itos(ret.size())); + + return ret; +} + +void ArrayMesh::_create_if_empty() const { + if (!mesh.is_valid()) { + mesh = VS::get_singleton()->mesh_create(); + VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)blend_shape_mode); + } +} + +void ArrayMesh::_set_surfaces(const Array &p_surfaces) { + + Vector<VS::SurfaceData> surface_data; + Vector<Ref<Material> > surface_materials; + Vector<String> surface_names; + Vector<bool> surface_2d; + + for (int i = 0; i < p_surfaces.size(); i++) { + VS::SurfaceData surface; + Dictionary d = p_surfaces[i]; + ERR_FAIL_COND(!d.has("format")); + ERR_FAIL_COND(!d.has("primitive")); + ERR_FAIL_COND(!d.has("vertex_data")); + ERR_FAIL_COND(!d.has("vertex_count")); + ERR_FAIL_COND(!d.has("aabb")); + surface.format = d["format"]; + surface.primitive = VS::PrimitiveType(int(d["primitive"])); + surface.vertex_data = d["vertex_data"]; + surface.vertex_count = d["vertex_count"]; + surface.aabb = d["aabb"]; + + if (d.has("index_data")) { + ERR_FAIL_COND(!d.has("index_count")); + surface.index_data = d["index_data"]; + surface.index_count = d["index_count"]; + } + + if (d.has("lods")) { + Array lods = d["lods"]; + ERR_FAIL_COND(lods.size() & 1); //must be even + for (int j = 0; j < lods.size(); j += 2) { + VS::SurfaceData::LOD lod; + lod.edge_length = lods[j + 0]; + lod.index_data = lods[j + 1]; + surface.lods.push_back(lod); + } + } + + if (d.has("bone_aabbs")) { + Array bone_aabbs = d["bone_aabbs"]; + for (int j = 0; j < bone_aabbs.size(); j++) { + surface.bone_aabbs.push_back(bone_aabbs[j]); + } + } + + if (d.has("blend_shapes")) { + Array blend_shapes; + for (int j = 0; j < blend_shapes.size(); j++) { + surface.blend_shapes.push_back(blend_shapes[j]); + } + } + + Ref<Material> material; + if (d.has("material")) { + material = d["material"]; + if (material.is_valid()) { + surface.material = material->get_rid(); + } + } + + String name; + if (d.has("name")) { + name = d["name"]; + } + + bool _2d = false; + if (d.has("2d")) { + _2d = d["2d"]; + } + /* + print_line("format: " + itos(surface.format)); + print_line("aabb: " + surface.aabb); + print_line("array size: " + itos(surface.vertex_data.size())); + print_line("vertex count: " + itos(surface.vertex_count)); + print_line("index size: " + itos(surface.index_data.size())); + print_line("index count: " + itos(surface.index_count)); + print_line("primitive: " + itos(surface.primitive)); +*/ + surface_data.push_back(surface); + surface_materials.push_back(material); + surface_names.push_back(name); + surface_2d.push_back(_2d); + } + + if (mesh.is_valid()) { + //if mesh exists, it needs to be updated + VS::get_singleton()->mesh_clear(mesh); + for (int i = 0; i < surface_data.size(); i++) { + VS::get_singleton()->mesh_add_surface(mesh, surface_data[i]); + } + } else { + // if mesh does not exist (first time this is loaded, most likely), + // we can create it with a single call, which is a lot more efficient and thread friendly + mesh = VS::get_singleton()->mesh_create_from_surfaces(surface_data); + VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)blend_shape_mode); + } + + surfaces.clear(); + + aabb = AABB(); + for (int i = 0; i < surface_data.size(); i++) { + Surface s; + s.aabb = surface_data[i].aabb; + if (i == 0) { + aabb = s.aabb; + blend_shapes.resize(surface_data[i].blend_shapes.size()); + } else { + aabb.merge_with(s.aabb); + } + + s.material = surface_materials[i]; + s.is_2d = surface_2d[i]; + s.name = surface_names[i]; + + s.format = surface_data[i].format; + s.primitive = PrimitiveType(surface_data[i].primitive); + s.array_length = surface_data[i].vertex_count; + s.index_array_length = surface_data[i].index_count; + + surfaces.push_back(s); + } +} + bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { if (_is_generated()) @@ -718,7 +1043,7 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { if (p_name == "blend_shape/names") { - PoolVector<String> sk; + Vector<String> sk; for (int i = 0; i < blend_shapes.size(); i++) sk.push_back(blend_shapes[i]); r_ret = sk; @@ -739,48 +1064,8 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { else if (what == "name") r_ret = surface_get_name(idx); return true; - } else if (!sname.begins_with("surfaces")) - return false; - - int idx = sname.get_slicec('/', 1).to_int(); - ERR_FAIL_INDEX_V(idx, surfaces.size(), false); - - Dictionary d; - - d["array_data"] = VS::get_singleton()->mesh_surface_get_array(mesh, idx); - d["vertex_count"] = VS::get_singleton()->mesh_surface_get_array_len(mesh, idx); - d["array_index_data"] = VS::get_singleton()->mesh_surface_get_index_array(mesh, idx); - d["index_count"] = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, idx); - d["primitive"] = VS::get_singleton()->mesh_surface_get_primitive_type(mesh, idx); - d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx); - d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx); - - Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx); - Array arr; - arr.resize(skel_aabb.size()); - for (int i = 0; i < skel_aabb.size(); i++) { - arr[i] = skel_aabb[i]; - } - d["skeleton_aabb"] = arr; - - Vector<PoolVector<uint8_t> > blend_shape_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh, idx); - - Array md; - for (int i = 0; i < blend_shape_data.size(); i++) { - md.push_back(blend_shape_data[i]); } - d["blend_shape_data"] = md; - - Ref<Material> m = surface_get_material(idx); - if (m.is_valid()) - d["material"] = m; - String n = surface_get_name(idx); - if (n != "") - d["name"] = n; - - r_ret = d; - return true; } @@ -790,18 +1075,17 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { return; if (blend_shapes.size()) { - p_list->push_back(PropertyInfo(Variant::POOL_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); + p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::INT, "blend_shape/mode", PROPERTY_HINT_ENUM, "Normalized,Relative")); } for (int i = 0; i < surfaces.size(); i++) { - p_list->push_back(PropertyInfo(Variant::DICTIONARY, "surfaces/" + itos(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); if (surfaces[i].is_2d) { p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR)); } else { - p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,SpatialMaterial", PROPERTY_USAGE_EDITOR)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_EDITOR)); } } } @@ -819,55 +1103,61 @@ void ArrayMesh::_recompute_aabb() { aabb.merge_with(surfaces[i].aabb); } } +#ifndef _MSC_VER +#warning need to add binding to add_surface using future MeshSurfaceData object +#endif +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<VS::SurfaceData::LOD> &p_lods) { -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { + _create_if_empty(); Surface s; s.aabb = p_aabb; s.is_2d = p_format & ARRAY_FLAG_USE_2D_VERTICES; + s.primitive = p_primitive; + s.array_length = p_vertex_count; + s.index_array_length = p_index_count; + s.format = p_format; + surfaces.push_back(s); _recompute_aabb(); - VisualServer::get_singleton()->mesh_add_surface(mesh, p_format, (VS::PrimitiveType)p_primitive, p_array, p_vertex_count, p_index_array, p_index_count, p_aabb, p_blend_shapes, p_bone_aabbs); -} + VS::SurfaceData sd; + sd.format = p_format; + sd.primitive = VS::PrimitiveType(p_primitive); + sd.aabb = p_aabb; + sd.vertex_count = p_vertex_count; + sd.vertex_data = p_array; + sd.index_count = p_index_count; + sd.index_data = p_index_array; + sd.blend_shapes = p_blend_shapes; + sd.bone_aabbs = p_bone_aabb; + sd.lods = p_lods; -void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_flags) { + VisualServer::get_singleton()->mesh_add_surface(mesh, sd); - ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX); - - Surface s; - - VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_flags); - - /* make aABB? */ { + clear_cache(); + _change_notify(); + emit_changed(); +} - Variant arr = p_arrays[ARRAY_VERTEX]; - PoolVector<Vector3> vertices = arr; - int len = vertices.size(); - ERR_FAIL_COND(len == 0); - PoolVector<Vector3>::Read r = vertices.read(); - const Vector3 *vtx = r.ptr(); +void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { - // check AABB - AABB aabb; - for (int i = 0; i < len; i++) { + ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX); - if (i == 0) - aabb.position = vtx[i]; - else - aabb.expand_to(vtx[i]); - } + VS::SurfaceData surface; - s.aabb = aabb; - s.is_2d = arr.get_type() == Variant::POOL_VECTOR2_ARRAY; - surfaces.push_back(s); + Error err = VS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (VisualServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags); + ERR_FAIL_COND(err != OK); - _recompute_aabb(); - } - - clear_cache(); - _change_notify(); - emit_changed(); + /* print_line("format: " + itos(surface.format)); + print_line("aabb: " + surface.aabb); + print_line("array size: " + itos(surface.vertex_data.size())); + print_line("vertex count: " + itos(surface.vertex_count)); + print_line("index size: " + itos(surface.index_data.size())); + print_line("index count: " + itos(surface.index_count)); + print_line("primitive: " + itos(surface.primitive)); +*/ + add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods); } Array ArrayMesh::surface_get_arrays(int p_surface) const { @@ -880,6 +1170,10 @@ Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array()); return VisualServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface); } +Dictionary ArrayMesh::surface_get_lods(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary()); + return VisualServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface); +} int ArrayMesh::get_surface_count() const { @@ -903,7 +1197,7 @@ void ArrayMesh::add_blend_shape(const StringName &p_name) { } blend_shapes.push_back(name); - VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); + //VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); } int ArrayMesh::get_blend_shape_count() const { @@ -924,7 +1218,9 @@ void ArrayMesh::clear_blend_shapes() { void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) { blend_shape_mode = p_mode; - VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode); + if (mesh.is_valid()) { + VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode); + } } ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const { @@ -932,40 +1228,28 @@ ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const { return blend_shape_mode; } -void ArrayMesh::surface_remove(int p_idx) { - - ERR_FAIL_INDEX(p_idx, surfaces.size()); - VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx); - surfaces.remove(p_idx); - - clear_cache(); - _recompute_aabb(); - _change_notify(); - emit_changed(); -} - int ArrayMesh::surface_get_array_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); - return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx); + return surfaces[p_idx].array_length; } int ArrayMesh::surface_get_array_index_len(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); - return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx); + return surfaces[p_idx].index_array_length; } uint32_t ArrayMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0); - return VisualServer::get_singleton()->mesh_surface_get_format(mesh, p_idx); + return surfaces[p_idx].format; } ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES); - return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type(mesh, p_idx); + return surfaces[p_idx].primitive; } void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { @@ -986,7 +1270,6 @@ int ArrayMesh::surface_find_by_name(const String &p_name) const { return i; } } - return -1; } @@ -1004,7 +1287,7 @@ String ArrayMesh::surface_get_name(int p_idx) const { return surfaces[p_idx].name; } -void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVector<uint8_t> &p_data) { +void ArrayMesh::surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) { ERR_FAIL_INDEX(p_surface, surfaces.size()); VS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data); @@ -1025,35 +1308,9 @@ Ref<Material> ArrayMesh::surface_get_material(int p_idx) const { return surfaces[p_idx].material; } -void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { - - VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data); - AABB aabb; - for (int i = 0; i < p_mesh_data.vertices.size(); i++) { - - if (i == 0) - aabb.position = p_mesh_data.vertices[i]; - else - aabb.expand_to(p_mesh_data.vertices[i]); - } - - Surface s; - s.aabb = aabb; - if (surfaces.size() == 0) - aabb = s.aabb; - else - aabb.merge_with(s.aabb); - - clear_cache(); - - surfaces.push_back(s); - _change_notify(); - - emit_changed(); -} - RID ArrayMesh::get_rid() const { + _create_if_empty(); return mesh; } AABB ArrayMesh::get_aabb() const { @@ -1061,8 +1318,18 @@ AABB ArrayMesh::get_aabb() const { return aabb; } +void ArrayMesh::clear_surfaces() { + if (!mesh.is_valid()) { + return; + } + VS::get_singleton()->mesh_clear(mesh); + surfaces.clear(); + aabb = AABB(); +} + void ArrayMesh::set_custom_aabb(const AABB &p_custom) { + _create_if_empty(); custom_aabb = p_custom; VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb); emit_changed(); @@ -1075,6 +1342,9 @@ AABB ArrayMesh::get_custom_aabb() const { void ArrayMesh::regen_normalmaps() { + if (surfaces.size() == 0) { + return; + } Vector<Ref<SurfaceTool> > surfs; for (int i = 0; i < get_surface_count(); i++) { @@ -1083,9 +1353,7 @@ void ArrayMesh::regen_normalmaps() { surfs.push_back(st); } - while (get_surface_count()) { - surface_remove(0); - } + clear_surfaces(); for (int i = 0; i < surfs.size(); i++) { @@ -1130,12 +1398,12 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe s.material = surface_get_material(i); s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays); - PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX]; + Vector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX]; int vc = rvertices.size(); - PoolVector<Vector3>::Read r = rvertices.read(); + const Vector3 *r = rvertices.ptr(); - PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL]; - PoolVector<Vector3>::Read rn = rnormals.read(); + Vector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL]; + const Vector3 *rn = rnormals.ptr(); int vertex_ofs = vertices.size() / 3; @@ -1157,7 +1425,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j); } - PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX]; + Vector<int> rindices = arrays[Mesh::ARRAY_INDEX]; int ic = rindices.size(); if (ic == 0) { @@ -1173,7 +1441,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe } } else { - PoolVector<int>::Read ri = rindices.read(); + const int *ri = rindices.ptr(); for (int j = 0; j < ic / 3; j++) { if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate()) @@ -1205,9 +1473,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe } //remove surfaces - while (get_surface_count()) { - surface_remove(0); - } + clear_surfaces(); //create surfacetools for each surface.. Vector<Ref<SurfaceTool> > surfaces_tools; @@ -1291,8 +1557,8 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); - ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove); + ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); @@ -1314,7 +1580,11 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative", PROPERTY_USAGE_NOEDITOR), "set_blend_shape_mode", "get_blend_shape_mode"); + ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces); + ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces); + + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); BIND_CONSTANT(NO_INDEX_ARRAY); @@ -1355,11 +1625,14 @@ void ArrayMesh::reload_from_file() { ArrayMesh::ArrayMesh() { - mesh = VisualServer::get_singleton()->mesh_create(); + //mesh is now created on demand + //mesh = VisualServer::get_singleton()->mesh_create(); blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; } ArrayMesh::~ArrayMesh() { - VisualServer::get_singleton()->free(mesh); + if (mesh.is_valid()) { + VisualServer::get_singleton()->free(mesh); + } } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 30ce94f16b..0e356c16a6 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -83,21 +83,17 @@ public: ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX, ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1), - ARRAY_COMPRESS_VERTEX = 1 << (ARRAY_VERTEX + ARRAY_COMPRESS_BASE), // mandatory ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_BONES = 1 << (ARRAY_BONES + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_WEIGHTS = 1 << (ARRAY_WEIGHTS + ARRAY_COMPRESS_BASE), ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, - ARRAY_FLAG_USE_16_BIT_BONES = ARRAY_COMPRESS_INDEX << 2, ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 | ARRAY_COMPRESS_WEIGHTS + ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 }; @@ -105,10 +101,9 @@ public: PRIMITIVE_POINTS = VisualServer::PRIMITIVE_POINTS, PRIMITIVE_LINES = VisualServer::PRIMITIVE_LINES, PRIMITIVE_LINE_STRIP = VisualServer::PRIMITIVE_LINE_STRIP, - PRIMITIVE_LINE_LOOP = VisualServer::PRIMITIVE_LINE_LOOP, PRIMITIVE_TRIANGLES = VisualServer::PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP = VisualServer::PRIMITIVE_TRIANGLE_STRIP, - PRIMITIVE_TRIANGLE_FAN = VisualServer::PRIMITIVE_TRIANGLE_FAN, + PRIMITIVE_MAX = VisualServer::PRIMITIVE_MAX, }; enum BlendShapeMode { @@ -123,6 +118,7 @@ public: virtual bool surface_is_softbody_friendly(int p_idx) const; virtual Array surface_get_arrays(int p_surface) const = 0; virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0; + virtual Dictionary surface_get_lods(int p_surface) const = 0; virtual uint32_t surface_get_format(int p_idx) const = 0; virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0; virtual void surface_set_material(int p_idx, const Ref<Material> &p_material) = 0; @@ -130,7 +126,7 @@ public: virtual int get_blend_shape_count() const = 0; virtual StringName get_blend_shape_name(int p_index) const = 0; - PoolVector<Face3> get_faces() const; + Vector<Face3> get_faces() const; Ref<TriangleMesh> generate_triangle_mesh() const; void generate_debug_mesh_lines(Vector<Vector3> &r_lines); void generate_debug_mesh_indices(Vector<Vector3> &r_points); @@ -160,20 +156,29 @@ class ArrayMesh : public Mesh { GDCLASS(ArrayMesh, Mesh); RES_BASE_EXTENSION("mesh"); + Array _get_surfaces() const; + void _set_surfaces(const Array &p_data); + private: struct Surface { + uint32_t format; + int array_length; + int index_array_length; + PrimitiveType primitive; + String name; AABB aabb; Ref<Material> material; bool is_2d; }; Vector<Surface> surfaces; - RID mesh; + mutable RID mesh; AABB aabb; BlendShapeMode blend_shape_mode; Vector<StringName> blend_shapes; AABB custom_aabb; + _FORCE_INLINE_ void _create_if_empty() const; void _recompute_aabb(); protected: @@ -186,11 +191,13 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); + + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t> > &p_blend_shapes = Vector<Vector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<VS::SurfaceData::LOD> &p_lods = Vector<VS::SurfaceData::LOD>()); Array surface_get_arrays(int p_surface) const; Array surface_get_blend_shape_arrays(int p_surface) const; + Dictionary surface_get_lods(int p_surface) const; void add_blend_shape(const StringName &p_name); int get_blend_shape_count() const; @@ -200,11 +207,13 @@ public: void set_blend_shape_mode(BlendShapeMode p_mode); BlendShapeMode get_blend_shape_mode() const; - void surface_update_region(int p_surface, int p_offset, const PoolVector<uint8_t> &p_data); + void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data); int get_surface_count() const; void surface_remove(int p_idx); + void clear_surfaces(); + void surface_set_custom_aabb(int p_idx, const AABB &p_aabb); //only recognized by driver int surface_get_array_len(int p_idx) const; @@ -220,8 +229,6 @@ public: void surface_set_name(int p_idx, const String &p_name); String surface_get_name(int p_idx) const; - void add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data); - void set_custom_aabb(const AABB &p_custom); AABB get_custom_aabb() const; diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 7a303443e3..675cfc6d64 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -47,7 +47,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf Array arrays = p_mesh->surface_get_arrays(p_surface); ERR_FAIL_COND_V(arrays.empty(), ERR_INVALID_PARAMETER); - PoolVector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX]; + Vector<Vector3> varray = arrays[Mesh::ARRAY_VERTEX]; int vcount = varray.size(); ERR_FAIL_COND_V(vcount == 0, ERR_INVALID_PARAMETER); @@ -56,34 +56,34 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf format = p_mesh->surface_get_format(p_surface); material = p_mesh->surface_get_material(p_surface); - PoolVector<Vector3>::Read vr = varray.read(); + const Vector3 *vr = varray.ptr(); - PoolVector<Vector3>::Read nr; + const Vector3 *nr; if (arrays[Mesh::ARRAY_NORMAL].get_type() != Variant::NIL) - nr = arrays[Mesh::ARRAY_NORMAL].operator PoolVector<Vector3>().read(); + nr = arrays[Mesh::ARRAY_NORMAL].operator Vector<Vector3>().ptr(); - PoolVector<real_t>::Read ta; + const real_t *ta; if (arrays[Mesh::ARRAY_TANGENT].get_type() != Variant::NIL) - ta = arrays[Mesh::ARRAY_TANGENT].operator PoolVector<real_t>().read(); + ta = arrays[Mesh::ARRAY_TANGENT].operator Vector<real_t>().ptr(); - PoolVector<Vector2>::Read uv; + const Vector2 *uv; if (arrays[Mesh::ARRAY_TEX_UV].get_type() != Variant::NIL) - uv = arrays[Mesh::ARRAY_TEX_UV].operator PoolVector<Vector2>().read(); - PoolVector<Vector2>::Read uv2; + uv = arrays[Mesh::ARRAY_TEX_UV].operator Vector<Vector2>().ptr(); + const Vector2 *uv2; if (arrays[Mesh::ARRAY_TEX_UV2].get_type() != Variant::NIL) - uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator PoolVector<Vector2>().read(); + uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator Vector<Vector2>().ptr(); - PoolVector<Color>::Read col; + const Color *col; if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL) - col = arrays[Mesh::ARRAY_COLOR].operator PoolVector<Color>().read(); + col = arrays[Mesh::ARRAY_COLOR].operator Vector<Color>().ptr(); - PoolVector<int>::Read bo; + const int *bo; if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL) - bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<int>().read(); + bo = arrays[Mesh::ARRAY_BONES].operator Vector<int>().ptr(); - PoolVector<real_t>::Read we; + const real_t *we; if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) - we = arrays[Mesh::ARRAY_WEIGHTS].operator PoolVector<real_t>().read(); + we = arrays[Mesh::ARRAY_WEIGHTS].operator Vector<real_t>().ptr(); vertices.resize(vcount); @@ -91,18 +91,18 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf Vertex v; v.vertex = vr[i]; - if (nr.ptr()) + if (nr) v.normal = nr[i]; - if (ta.ptr()) + if (ta) v.tangent = Plane(ta[i * 4 + 0], ta[i * 4 + 1], ta[i * 4 + 2], ta[i * 4 + 3]); - if (uv.ptr()) + if (uv) v.uv = uv[i]; - if (uv2.ptr()) + if (uv2) v.uv2 = uv2[i]; - if (col.ptr()) + if (col) v.color = col[i]; - if (we.ptr()) { + if (we) { v.weights.push_back(we[i * 4 + 0]); v.weights.push_back(we[i * 4 + 1]); @@ -110,7 +110,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf v.weights.push_back(we[i * 4 + 3]); } - if (bo.ptr()) { + if (bo) { v.bones.push_back(bo[i * 4 + 0]); v.bones.push_back(bo[i * 4 + 1]); @@ -121,7 +121,7 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf vertices.write[i] = v; } - PoolVector<int> indices; + Vector<int> indices; if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) { @@ -129,13 +129,13 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf } else { //make code simpler indices.resize(vcount); - PoolVector<int>::Write iw = indices.write(); + int *iw = indices.ptrw(); for (int i = 0; i < vcount; i++) iw[i] = i; } int icount = indices.size(); - PoolVector<int>::Read r = indices.read(); + const int *r = indices.ptr(); Map<Point2i, int> edge_indices; @@ -187,61 +187,61 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { int vcount = vertices.size(); - PoolVector<Vector3> v; - PoolVector<Vector3> n; - PoolVector<real_t> t; - PoolVector<Vector2> u; - PoolVector<Vector2> u2; - PoolVector<Color> c; - PoolVector<int> b; - PoolVector<real_t> w; - PoolVector<int> in; + Vector<Vector3> v; + Vector<Vector3> n; + Vector<real_t> t; + Vector<Vector2> u; + Vector<Vector2> u2; + Vector<Color> c; + Vector<int> b; + Vector<real_t> w; + Vector<int> in; { v.resize(vcount); - PoolVector<Vector3>::Write vr = v.write(); + Vector3 *vr = v.ptrw(); - PoolVector<Vector3>::Write nr; + Vector3 *nr; if (format & Mesh::ARRAY_FORMAT_NORMAL) { n.resize(vcount); - nr = n.write(); + nr = n.ptrw(); } - PoolVector<real_t>::Write ta; + real_t *ta; if (format & Mesh::ARRAY_FORMAT_TANGENT) { t.resize(vcount * 4); - ta = t.write(); + ta = t.ptrw(); } - PoolVector<Vector2>::Write uv; + Vector2 *uv; if (format & Mesh::ARRAY_FORMAT_TEX_UV) { u.resize(vcount); - uv = u.write(); + uv = u.ptrw(); } - PoolVector<Vector2>::Write uv2; + Vector2 *uv2; if (format & Mesh::ARRAY_FORMAT_TEX_UV2) { u2.resize(vcount); - uv2 = u2.write(); + uv2 = u2.ptrw(); } - PoolVector<Color>::Write col; + Color *col; if (format & Mesh::ARRAY_FORMAT_COLOR) { c.resize(vcount); - col = c.write(); + col = c.ptrw(); } - PoolVector<int>::Write bo; + int *bo; if (format & Mesh::ARRAY_FORMAT_BONES) { b.resize(vcount * 4); - bo = b.write(); + bo = b.ptrw(); } - PoolVector<real_t>::Write we; + real_t *we; if (format & Mesh::ARRAY_FORMAT_WEIGHTS) { w.resize(vcount * 4); - we = w.write(); + we = w.ptrw(); } for (int i = 0; i < vcount; i++) { @@ -249,22 +249,22 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { const Vertex &vtx = vertices[i]; vr[i] = vtx.vertex; - if (nr.ptr()) + if (nr) nr[i] = vtx.normal; - if (ta.ptr()) { + if (ta) { ta[i * 4 + 0] = vtx.tangent.normal.x; ta[i * 4 + 1] = vtx.tangent.normal.y; ta[i * 4 + 2] = vtx.tangent.normal.z; ta[i * 4 + 3] = vtx.tangent.d; } - if (uv.ptr()) + if (uv) uv[i] = vtx.uv; - if (uv2.ptr()) + if (uv2) uv2[i] = vtx.uv2; - if (col.ptr()) + if (col) col[i] = vtx.color; - if (we.ptr()) { + if (we) { we[i * 4 + 0] = vtx.weights[0]; we[i * 4 + 1] = vtx.weights[1]; @@ -272,7 +272,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { we[i * 4 + 3] = vtx.weights[3]; } - if (bo.ptr()) { + if (bo) { bo[i * 4 + 0] = vtx.bones[0]; bo[i * 4 + 1] = vtx.bones[1]; @@ -283,7 +283,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { int fc = faces.size(); in.resize(fc * 3); - PoolVector<int>::Write iw = in.write(); + int *iw = in.ptrw(); for (int i = 0; i < fc; i++) { iw[i * 3 + 0] = faces[i].v[0]; diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index 754cad4def..fffd192348 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "mesh_library.h" -#include "core/engine.h" bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) { @@ -104,7 +103,7 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::ARRAY, name + "shapes")); p_list->push_back(PropertyInfo(Variant::OBJECT, name + "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh")); p_list->push_back(PropertyInfo(Variant::TRANSFORM, name + "navmesh_transform")); - p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER)); + p_list->push_back(PropertyInfo(Variant::OBJECT, name + "preview", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_HELPER)); } } @@ -162,7 +161,7 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran _change_notify(); } -void MeshLibrary::set_item_preview(int p_item, const Ref<Texture> &p_preview) { +void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) { ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); item_map[p_item].preview = p_preview; @@ -200,14 +199,9 @@ Transform MeshLibrary::get_item_navmesh_transform(int p_item) const { return item_map[p_item].navmesh_transform; } -Ref<Texture> MeshLibrary::get_item_preview(int p_item) const { +Ref<Texture2D> MeshLibrary::get_item_preview(int p_item) const { - if (!Engine::get_singleton()->is_editor_hint()) { - ERR_PRINT("MeshLibrary item previews are only generated in an editor context, which means they aren't available in a running project."); - return Ref<Texture>(); - } - - ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); + ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture2D>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'."); return item_map[p_item].preview; } diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 471db74175..b256e86b96 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -34,7 +34,7 @@ #include "core/map.h" #include "core/resource.h" #include "mesh.h" -#include "scene/3d/navigation_mesh.h" +#include "scene/3d/navigation_region.h" #include "shape.h" class MeshLibrary : public Resource { @@ -51,7 +51,7 @@ public: String name; Ref<Mesh> mesh; Vector<ShapeData> shapes; - Ref<Texture> preview; + Ref<Texture2D> preview; Transform navmesh_transform; Ref<NavigationMesh> navmesh; }; @@ -75,13 +75,13 @@ public: void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh); void set_item_navmesh_transform(int p_item, const Transform &p_transform); void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes); - void set_item_preview(int p_item, const Ref<Texture> &p_preview); + void set_item_preview(int p_item, const Ref<Texture2D> &p_preview); String get_item_name(int p_item) const; Ref<Mesh> get_item_mesh(int p_item) const; Ref<NavigationMesh> get_item_navmesh(int p_item) const; Transform get_item_navmesh_transform(int p_item) const; Vector<ShapeData> get_item_shapes(int p_item) const; - Ref<Texture> get_item_preview(int p_item) const; + Ref<Texture2D> get_item_preview(int p_item) const; void remove_item(int p_item); bool has_item(int p_item) const; diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index ee831f36f5..aa8be326f5 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -29,19 +29,23 @@ /*************************************************************************/ #include "multimesh.h" + #include "servers/visual_server.h" -void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) { +#ifndef DISABLE_DEPRECATED +// Kept for compatibility from 3.x to 4.0. + +void MultiMesh::_set_transform_array(const Vector<Vector3> &p_array) { if (transform_format != TRANSFORM_3D) return; - const PoolVector<Vector3> &xforms = p_array; + const Vector<Vector3> &xforms = p_array; int len = xforms.size(); ERR_FAIL_COND((len / 4) != instance_count); if (len == 0) return; - PoolVector<Vector3>::Read r = xforms.read(); + const Vector3 *r = xforms.ptr(); for (int i = 0; i < len / 4; i++) { @@ -55,18 +59,18 @@ void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) { } } -PoolVector<Vector3> MultiMesh::_get_transform_array() const { +Vector<Vector3> MultiMesh::_get_transform_array() const { if (transform_format != TRANSFORM_3D) - return PoolVector<Vector3>(); + return Vector<Vector3>(); if (instance_count == 0) - return PoolVector<Vector3>(); + return Vector<Vector3>(); - PoolVector<Vector3> xforms; + Vector<Vector3> xforms; xforms.resize(instance_count * 4); - PoolVector<Vector3>::Write w = xforms.write(); + Vector3 *w = xforms.ptrw(); for (int i = 0; i < instance_count; i++) { @@ -80,18 +84,18 @@ PoolVector<Vector3> MultiMesh::_get_transform_array() const { return xforms; } -void MultiMesh::_set_transform_2d_array(const PoolVector<Vector2> &p_array) { +void MultiMesh::_set_transform_2d_array(const Vector<Vector2> &p_array) { if (transform_format != TRANSFORM_2D) return; - const PoolVector<Vector2> &xforms = p_array; + const Vector<Vector2> &xforms = p_array; int len = xforms.size(); ERR_FAIL_COND((len / 3) != instance_count); if (len == 0) return; - PoolVector<Vector2>::Read r = xforms.read(); + const Vector2 *r = xforms.ptr(); for (int i = 0; i < len / 3; i++) { @@ -104,18 +108,18 @@ void MultiMesh::_set_transform_2d_array(const PoolVector<Vector2> &p_array) { } } -PoolVector<Vector2> MultiMesh::_get_transform_2d_array() const { +Vector<Vector2> MultiMesh::_get_transform_2d_array() const { if (transform_format != TRANSFORM_2D) - return PoolVector<Vector2>(); + return Vector<Vector2>(); if (instance_count == 0) - return PoolVector<Vector2>(); + return Vector<Vector2>(); - PoolVector<Vector2> xforms; + Vector<Vector2> xforms; xforms.resize(instance_count * 3); - PoolVector<Vector2>::Write w = xforms.write(); + Vector2 *w = xforms.ptrw(); for (int i = 0; i < instance_count; i++) { @@ -128,15 +132,15 @@ PoolVector<Vector2> MultiMesh::_get_transform_2d_array() const { return xforms; } -void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) { +void MultiMesh::_set_color_array(const Vector<Color> &p_array) { - const PoolVector<Color> &colors = p_array; + const Vector<Color> &colors = p_array; int len = colors.size(); if (len == 0) return; ERR_FAIL_COND(len != instance_count); - PoolVector<Color>::Read r = colors.read(); + const Color *r = colors.ptr(); for (int i = 0; i < len; i++) { @@ -144,12 +148,12 @@ void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) { } } -PoolVector<Color> MultiMesh::_get_color_array() const { +Vector<Color> MultiMesh::_get_color_array() const { - if (instance_count == 0 || color_format == COLOR_NONE) - return PoolVector<Color>(); + if (instance_count == 0 || !use_colors) + return Vector<Color>(); - PoolVector<Color> colors; + Vector<Color> colors; colors.resize(instance_count); for (int i = 0; i < instance_count; i++) { @@ -160,15 +164,15 @@ PoolVector<Color> MultiMesh::_get_color_array() const { return colors; } -void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) { +void MultiMesh::_set_custom_data_array(const Vector<Color> &p_array) { - const PoolVector<Color> &custom_datas = p_array; + const Vector<Color> &custom_datas = p_array; int len = custom_datas.size(); if (len == 0) return; ERR_FAIL_COND(len != instance_count); - PoolVector<Color>::Read r = custom_datas.read(); + const Color *r = custom_datas.ptr(); for (int i = 0; i < len; i++) { @@ -176,12 +180,12 @@ void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) { } } -PoolVector<Color> MultiMesh::_get_custom_data_array() const { +Vector<Color> MultiMesh::_get_custom_data_array() const { - if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE) - return PoolVector<Color>(); + if (instance_count == 0 || !use_custom_data) + return Vector<Color>(); - PoolVector<Color> custom_datas; + Vector<Color> custom_datas; custom_datas.resize(instance_count); for (int i = 0; i < instance_count; i++) { @@ -191,6 +195,16 @@ PoolVector<Color> MultiMesh::_get_custom_data_array() const { return custom_datas; } +#endif // DISABLE_DEPRECATED + +void MultiMesh::set_buffer(const Vector<float> &p_buffer) { + VS::get_singleton()->multimesh_set_buffer(multimesh, p_buffer); +} + +Vector<float> MultiMesh::get_buffer() const { + return VS::get_singleton()->multimesh_get_buffer(multimesh); +} + void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) { mesh = p_mesh; @@ -207,7 +221,7 @@ Ref<Mesh> MultiMesh::get_mesh() const { void MultiMesh::set_instance_count(int p_count) { ERR_FAIL_COND(p_count < 0); - VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format)); + VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data); instance_count = p_count; } int MultiMesh::get_instance_count() const { @@ -217,6 +231,7 @@ int MultiMesh::get_instance_count() const { void MultiMesh::set_visible_instance_count(int p_count) { ERR_FAIL_COND(p_count < -1); + ERR_FAIL_COND(p_count > instance_count); VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count); visible_instance_count = p_count; } @@ -263,11 +278,6 @@ Color MultiMesh::get_instance_custom_data(int p_instance) const { return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance); } -void MultiMesh::set_as_bulk_array(const PoolVector<float> &p_array) { - - VisualServer::get_singleton()->multimesh_set_as_bulk_array(multimesh, p_array); -} - AABB MultiMesh::get_aabb() const { return VisualServer::get_singleton()->multimesh_get_aabb(multimesh); @@ -278,26 +288,22 @@ RID MultiMesh::get_rid() const { return multimesh; } -void MultiMesh::set_color_format(ColorFormat p_color_format) { - +void MultiMesh::set_use_colors(bool p_enable) { ERR_FAIL_COND(instance_count > 0); - color_format = p_color_format; + use_colors = p_enable; } -MultiMesh::ColorFormat MultiMesh::get_color_format() const { - - return color_format; +bool MultiMesh::is_using_colors() const { + return use_colors; } -void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) { - +void MultiMesh::set_use_custom_data(bool p_enable) { ERR_FAIL_COND(instance_count > 0); - custom_data_format = p_custom_data_format; + use_custom_data = p_enable; } -MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const { - - return custom_data_format; +bool MultiMesh::is_using_custom_data() const { + return use_custom_data; } void MultiMesh::set_transform_format(TransformFormat p_transform_format) { @@ -314,10 +320,10 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MultiMesh::set_mesh); ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh); - ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format); - ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format); - ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format); - ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format); + ClassDB::bind_method(D_METHOD("set_use_colors", "enable"), &MultiMesh::set_use_colors); + ClassDB::bind_method(D_METHOD("is_using_colors"), &MultiMesh::is_using_colors); + ClassDB::bind_method(D_METHOD("set_use_custom_data", "enable"), &MultiMesh::set_use_custom_data); + ClassDB::bind_method(D_METHOD("is_using_custom_data"), &MultiMesh::is_using_custom_data); ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format); ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format); @@ -333,9 +339,21 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color); ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data); ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data); - ClassDB::bind_method(D_METHOD("set_as_bulk_array", "array"), &MultiMesh::set_as_bulk_array); ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb); + ClassDB::bind_method(D_METHOD("get_buffer"), &MultiMesh::get_buffer); + ClassDB::bind_method(D_METHOD("set_buffer", "buffer"), &MultiMesh::set_buffer); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_colors"), "set_use_colors", "is_using_colors"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_data"), "set_use_custom_data", "is_using_custom_data"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "buffer", PROPERTY_HINT_NONE), "set_buffer", "get_buffer"); + +#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("_get_transform_array"), &MultiMesh::_get_transform_array); ClassDB::bind_method(D_METHOD("_set_transform_2d_array"), &MultiMesh::_set_transform_2d_array); @@ -345,34 +363,21 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array); ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array); - ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_instance_count", PROPERTY_HINT_RANGE, "-1,16384,1,or_greater"), "set_visible_instance_count", "get_visible_instance_count"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_2d_array", "_get_transform_2d_array"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array"); - ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_array", "_get_transform_array"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "transform_2d_array", PROPERTY_HINT_NONE, "", 0), "_set_transform_2d_array", "_get_transform_2d_array"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", 0), "_set_color_array", "_get_color_array"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", 0), "_set_custom_data_array", "_get_custom_data_array"); +#endif BIND_ENUM_CONSTANT(TRANSFORM_2D); BIND_ENUM_CONSTANT(TRANSFORM_3D); - - BIND_ENUM_CONSTANT(COLOR_NONE); - BIND_ENUM_CONSTANT(COLOR_8BIT); - BIND_ENUM_CONSTANT(COLOR_FLOAT); - - BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE); - BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT); - BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT); } MultiMesh::MultiMesh() { multimesh = VisualServer::get_singleton()->multimesh_create(); - color_format = COLOR_NONE; - custom_data_format = CUSTOM_DATA_NONE; + use_colors = false; + use_custom_data = false; transform_format = TRANSFORM_2D; visible_instance_count = -1; instance_count = 0; diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 9394737799..8ca30a5b88 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -45,51 +45,44 @@ public: TRANSFORM_3D = VS::MULTIMESH_TRANSFORM_3D }; - enum ColorFormat { - COLOR_NONE = VS::MULTIMESH_COLOR_NONE, - COLOR_8BIT = VS::MULTIMESH_COLOR_8BIT, - COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT, - }; - - enum CustomDataFormat { - CUSTOM_DATA_NONE, - CUSTOM_DATA_8BIT, - CUSTOM_DATA_FLOAT, - }; - private: Ref<Mesh> mesh; RID multimesh; TransformFormat transform_format; - ColorFormat color_format; - CustomDataFormat custom_data_format; + bool use_colors; + bool use_custom_data; int instance_count; int visible_instance_count; protected: static void _bind_methods(); - void _set_transform_array(const PoolVector<Vector3> &p_array); - PoolVector<Vector3> _get_transform_array() const; +#ifndef DISABLE_DEPRECATED + // Kept for compatibility from 3.x to 4.0. + void _set_transform_array(const Vector<Vector3> &p_array); + Vector<Vector3> _get_transform_array() const; - void _set_transform_2d_array(const PoolVector<Vector2> &p_array); - PoolVector<Vector2> _get_transform_2d_array() const; + void _set_transform_2d_array(const Vector<Vector2> &p_array); + Vector<Vector2> _get_transform_2d_array() const; - void _set_color_array(const PoolVector<Color> &p_array); - PoolVector<Color> _get_color_array() const; + void _set_color_array(const Vector<Color> &p_array); + Vector<Color> _get_color_array() const; - void _set_custom_data_array(const PoolVector<Color> &p_array); - PoolVector<Color> _get_custom_data_array() const; + void _set_custom_data_array(const Vector<Color> &p_array); + Vector<Color> _get_custom_data_array() const; +#endif + void set_buffer(const Vector<float> &p_buffer); + Vector<float> get_buffer() const; public: void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; - void set_color_format(ColorFormat p_color_format); - ColorFormat get_color_format() const; + void set_use_colors(bool p_enable); + bool is_using_colors() const; - void set_custom_data_format(CustomDataFormat p_custom_data_format); - CustomDataFormat get_custom_data_format() const; + void set_use_custom_data(bool p_enable); + bool is_using_custom_data() const; void set_transform_format(TransformFormat p_transform_format); TransformFormat get_transform_format() const; @@ -111,8 +104,6 @@ public: void set_instance_custom_data(int p_instance, const Color &p_custom_data); Color get_instance_custom_data(int p_instance) const; - void set_as_bulk_array(const PoolVector<float> &p_array); - virtual AABB get_aabb() const; virtual RID get_rid() const; @@ -122,7 +113,5 @@ public: }; VARIANT_ENUM_CAST(MultiMesh::TransformFormat); -VARIANT_ENUM_CAST(MultiMesh::ColorFormat); -VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat); #endif // MULTI_MESH_H diff --git a/scene/3d/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index aaba91125e..e0aff2182e 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -29,12 +29,10 @@ /*************************************************************************/ #include "navigation_mesh.h" -#include "mesh_instance.h" -#include "navigation.h" void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { - vertices = PoolVector<Vector3>(); + vertices = Vector<Vector3>(); clear_polygons(); for (int i = 0; i < p_mesh->get_surface_count(); i++) { @@ -42,15 +40,15 @@ void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) { if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) continue; Array arr = p_mesh->surface_get_arrays(i); - PoolVector<Vector3> varr = arr[Mesh::ARRAY_VERTEX]; - PoolVector<int> iarr = arr[Mesh::ARRAY_INDEX]; + Vector<Vector3> varr = arr[Mesh::ARRAY_VERTEX]; + Vector<int> iarr = arr[Mesh::ARRAY_INDEX]; if (varr.size() == 0 || iarr.size() == 0) continue; int from = vertices.size(); vertices.append_array(varr); int rlen = iarr.size(); - PoolVector<int>::Read r = iarr.read(); + const int *r = iarr.ptr(); for (int j = 0; j < rlen; j += 3) { Vector<int> vi; @@ -254,13 +252,13 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const { return filter_walkable_low_height_spans; } -void NavigationMesh::set_vertices(const PoolVector<Vector3> &p_vertices) { +void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) { vertices = p_vertices; _change_notify(); } -PoolVector<Vector3> NavigationMesh::get_vertices() const { +Vector<Vector3> NavigationMesh::get_vertices() const { return vertices; } @@ -311,8 +309,8 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { if (debug_mesh.is_valid()) return debug_mesh; - PoolVector<Vector3> vertices = get_vertices(); - PoolVector<Vector3>::Read vr = vertices.read(); + Vector<Vector3> vertices = get_vertices(); + const Vector3 *vr = vertices.ptr(); List<Face3> faces; for (int i = 0; i < get_polygon_count(); i++) { Vector<int> p = get_polygon(i); @@ -328,11 +326,11 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { } Map<_EdgeKey, bool> edge_map; - PoolVector<Vector3> tmeshfaces; + Vector<Vector3> tmeshfaces; tmeshfaces.resize(faces.size() * 3); { - PoolVector<Vector3>::Write tw = tmeshfaces.write(); + Vector3 *tw = tmeshfaces.ptrw(); int tidx = 0; for (List<Face3>::Element *E = faces.front(); E; E = E->next()) { @@ -371,10 +369,10 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() { } } - PoolVector<Vector3> varr; + Vector<Vector3> varr; varr.resize(lines.size()); { - PoolVector<Vector3>::Write w = varr.write(); + Vector3 *w = varr.ptrw(); int idx = 0; for (List<Vector3>::Element *E = lines.front(); E; E = E->next()) { w[idx++] = E->get(); @@ -480,7 +478,7 @@ void NavigationMesh::_bind_methods() { BIND_CONSTANT(PARSED_GEOMETRY_STATIC_COLLIDERS); BIND_CONSTANT(PARSED_GEOMETRY_BOTH); - ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_vertices", "get_vertices"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_polygons", "_get_polygons"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type/sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type"); @@ -489,19 +487,19 @@ void NavigationMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/height", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_height", "get_agent_height"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/radius", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_climb", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "agent/max_slope", PROPERTY_HINT_RANGE, "0.0,90.0,0.1"), "set_agent_max_slope", "get_agent_max_slope"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_verts_per_poly", "get_verts_per_poly"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/height", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_height", "get_agent_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/radius", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_radius", "get_agent_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/max_climb", PROPERTY_HINT_RANGE, "0.1,5.0,0.01,or_greater"), "set_agent_max_climb", "get_agent_max_climb"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent/max_slope", PROPERTY_HINT_RANGE, "0.0,90.0,0.1"), "set_agent_max_slope", "get_agent_max_slope"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "region/min_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_min_size", "get_region_min_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "region/merge_size", PROPERTY_HINT_RANGE, "0.0,150.0,0.01,or_greater"), "set_region_merge_size", "get_region_merge_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_verts_per_poly", "get_verts_per_poly"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans"); @@ -548,197 +546,3 @@ NavigationMesh::NavigationMesh() { filter_ledge_spans = false; filter_walkable_low_height_spans = false; } - -void NavigationMeshInstance::set_enabled(bool p_enabled) { - - if (enabled == p_enabled) - return; - enabled = p_enabled; - - if (!is_inside_tree()) - return; - - if (!enabled) { - - if (nav_id != -1) { - navigation->navmesh_remove(nav_id); - nav_id = -1; - } - } else { - - if (navigation) { - - if (navmesh.is_valid()) { - - nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); - } - } - } - - if (debug_view) { - MeshInstance *dm = Object::cast_to<MeshInstance>(debug_view); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); - } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); - } - } - - update_gizmo(); -} - -bool NavigationMeshInstance::is_enabled() const { - - return enabled; -} - -///////////////////////////// - -void NavigationMeshInstance::_notification(int p_what) { - - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - - Spatial *c = this; - while (c) { - - navigation = Object::cast_to<Navigation>(c); - if (navigation) { - - if (enabled && navmesh.is_valid()) { - - nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); - } - break; - } - - c = c->get_parent_spatial(); - } - - if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { - - MeshInstance *dm = memnew(MeshInstance); - dm->set_mesh(navmesh->get_debug_mesh()); - if (is_enabled()) { - dm->set_material_override(get_tree()->get_debug_navigation_material()); - } else { - dm->set_material_override(get_tree()->get_debug_navigation_disabled_material()); - } - add_child(dm); - debug_view = dm; - } - - } break; - case NOTIFICATION_TRANSFORM_CHANGED: { - - if (navigation && nav_id != -1) { - navigation->navmesh_set_transform(nav_id, get_relative_transform(navigation)); - } - - } break; - case NOTIFICATION_EXIT_TREE: { - - if (navigation) { - - if (nav_id != -1) { - navigation->navmesh_remove(nav_id); - nav_id = -1; - } - } - - if (debug_view) { - debug_view->queue_delete(); - debug_view = NULL; - } - navigation = NULL; - } break; - } -} - -void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) { - - if (p_navmesh == navmesh) - return; - - if (navigation && nav_id != -1) { - navigation->navmesh_remove(nav_id); - nav_id = -1; - } - - if (navmesh.is_valid()) { - navmesh->remove_change_receptor(this); - } - - navmesh = p_navmesh; - - if (navmesh.is_valid()) { - navmesh->add_change_receptor(this); - } - - if (navigation && navmesh.is_valid() && enabled) { - nav_id = navigation->navmesh_add(navmesh, get_relative_transform(navigation), this); - } - - if (debug_view && navmesh.is_valid()) { - Object::cast_to<MeshInstance>(debug_view)->set_mesh(navmesh->get_debug_mesh()); - } - - update_gizmo(); - update_configuration_warning(); -} - -Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const { - - return navmesh; -} - -String NavigationMeshInstance::get_configuration_warning() const { - - if (!is_visible_in_tree() || !is_inside_tree()) - return String(); - - if (!navmesh.is_valid()) { - return TTR("A NavigationMesh resource must be set or created for this node to work."); - } - const Spatial *c = this; - while (c) { - - if (Object::cast_to<Navigation>(c)) - return String(); - - c = Object::cast_to<Spatial>(c->get_parent()); - } - - return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); -} - -void NavigationMeshInstance::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh); - ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh); - - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationMeshInstance::is_enabled); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); -} - -void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_prop) { - update_gizmo(); - update_configuration_warning(); -} - -NavigationMeshInstance::NavigationMeshInstance() { - - debug_view = NULL; - navigation = NULL; - nav_id = -1; - enabled = true; - set_notify_transform(true); -} - -NavigationMeshInstance::~NavigationMeshInstance() { - if (navmesh.is_valid()) - navmesh->remove_change_receptor(this); -} diff --git a/scene/3d/navigation_mesh.h b/scene/resources/navigation_mesh.h index f9ab911bea..cc3ac6e3fd 100644 --- a/scene/3d/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -31,7 +31,6 @@ #ifndef NAVIGATION_MESH_H #define NAVIGATION_MESH_H -#include "scene/3d/spatial.h" #include "scene/resources/mesh.h" class Mesh; @@ -40,7 +39,7 @@ class NavigationMesh : public Resource { GDCLASS(NavigationMesh, Resource); - PoolVector<Vector3> vertices; + Vector<Vector3> vertices; struct Polygon { Vector<int> indices; }; @@ -180,8 +179,8 @@ public: void create_from_mesh(const Ref<Mesh> &p_mesh); - void set_vertices(const PoolVector<Vector3> &p_vertices); - PoolVector<Vector3> get_vertices() const; + void set_vertices(const Vector<Vector3> &p_vertices); + Vector<Vector3> get_vertices() const; void add_polygon(const Vector<int> &p_polygon); int get_polygon_count() const; @@ -193,35 +192,4 @@ public: NavigationMesh(); }; -class Navigation; - -class NavigationMeshInstance : public Spatial { - - GDCLASS(NavigationMeshInstance, Spatial); - - bool enabled; - int nav_id; - Navigation *navigation; - Ref<NavigationMesh> navmesh; - - Node *debug_view; - -protected: - void _notification(int p_what); - static void _bind_methods(); - void _changed_callback(Object *p_changed, const char *p_prop); - -public: - void set_enabled(bool p_enabled); - bool is_enabled() const; - - void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh); - Ref<NavigationMesh> get_navigation_mesh() const; - - String get_configuration_warning() const; - - NavigationMeshInstance(); - ~NavigationMeshInstance(); -}; - #endif // NAVIGATION_MESH_H diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 3e7d350eec..0538f679cc 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -331,7 +331,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { binds.write[j] = props[c.binds[j]]; } - cfrom->connect(snames[c.signal], cto, snames[c.method], binds, CONNECT_PERSIST | c.flags); + cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags); } //Node *s = ret_nodes[0]; @@ -532,7 +532,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map if (exists) { //check if already exists and did not change - if (value.get_type() == Variant::REAL && original.get_type() == Variant::REAL) { + if (value.get_type() == Variant::FLOAT && original.get_type() == Variant::FLOAT) { //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error float a = value; float b = original; @@ -702,7 +702,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName // only connections that originate or end into main saved scene are saved // everything else is discarded - Node *target = Object::cast_to<Node>(c.target); + Node *target = Object::cast_to<Node>(c.callable.get_object()); if (!target) { continue; @@ -734,7 +734,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName NodePath signal_from = common_parent->get_path_to(p_node); NodePath signal_to = common_parent->get_path_to(target); - if (ps->has_connection(signal_from, c.signal, signal_to, c.method)) { + if (ps->has_connection(signal_from, c.signal.get_name(), signal_to, c.callable.get_method())) { exists = true; break; } @@ -766,7 +766,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save - if (state->is_connection(from_node, c.signal, to_node, c.method)) { + if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) { exists2 = true; break; } @@ -784,7 +784,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName if (from_node >= 0 && to_node >= 0) { //this one has state for this node, save - if (state->is_connection(from_node, c.signal, to_node, c.method)) { + if (state->is_connection(from_node, c.signal.get_name(), to_node, c.callable.get_method())) { exists2 = true; break; } @@ -831,8 +831,8 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName ConnectionData cd; cd.from = src_id; cd.to = target_id; - cd.method = _nm_get_string(c.method, name_map); - cd.signal = _nm_get_string(c.signal, name_map); + cd.method = _nm_get_string(c.callable.get_method(), name_map); + cd.signal = _nm_get_string(c.signal.get_name(), name_map); cd.flags = c.flags; for (int i = 0; i < c.binds.size(); i++) { @@ -1098,19 +1098,19 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { ERR_FAIL_COND_MSG(version > PACKED_SCENE_VERSION, "Save format version too new."); const int node_count = p_dictionary["node_count"]; - const PoolVector<int> snodes = p_dictionary["nodes"]; + const Vector<int> snodes = p_dictionary["nodes"]; ERR_FAIL_COND(snodes.size() < node_count); const int conn_count = p_dictionary["conn_count"]; - const PoolVector<int> sconns = p_dictionary["conns"]; + const Vector<int> sconns = p_dictionary["conns"]; ERR_FAIL_COND(sconns.size() < conn_count); - PoolVector<String> snames = p_dictionary["names"]; + Vector<String> snames = p_dictionary["names"]; if (snames.size()) { int namecount = snames.size(); names.resize(namecount); - PoolVector<String>::Read r = snames.read(); + const String *r = snames.ptr(); for (int i = 0; i < names.size(); i++) names.write[i] = r[i]; } @@ -1131,7 +1131,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { nodes.resize(node_count); if (node_count) { - PoolVector<int>::Read r = snodes.read(); + const int *r = snodes.ptr(); int idx = 0; for (int i = 0; i < node_count; i++) { NodeData &nd = nodes.write[i]; @@ -1159,7 +1159,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { connections.resize(conn_count); if (conn_count) { - PoolVector<int>::Read r = sconns.read(); + const int *r = sconns.ptr(); int idx = 0; for (int i = 0; i < conn_count; i++) { ConnectionData &cd = connections.write[i]; @@ -1205,12 +1205,12 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { Dictionary SceneState::get_bundled_scene() const { - PoolVector<String> rnames; + Vector<String> rnames; rnames.resize(names.size()); if (names.size()) { - PoolVector<String>::Write r = rnames.write(); + String *r = rnames.ptrw(); for (int i = 0; i < names.size(); i++) r[i] = names[i]; @@ -1612,10 +1612,10 @@ void SceneState::add_editable_instance(const NodePath &p_path) { editable_instances.push_back(p_path); } -PoolVector<String> SceneState::_get_node_groups(int p_idx) const { +Vector<String> SceneState::_get_node_groups(int p_idx) const { Vector<StringName> groups = get_node_groups(p_idx); - PoolVector<String> ret; + Vector<String> ret; for (int i = 0; i < groups.size(); i++) ret.push_back(groups[i]); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index b4966e2528..c5873a0792 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -103,7 +103,7 @@ class SceneState : public Reference { static bool disable_placeholders; - PoolVector<String> _get_node_groups(int p_idx) const; + Vector<String> _get_node_groups(int p_idx) const; int _find_base_scene_node_remap_key(int p_idx) const; diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 412b5c259c..f18e8956f1 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -30,17 +30,13 @@ #include "particles_material.h" -Mutex *ParticlesMaterial::material_mutex = NULL; +Mutex ParticlesMaterial::material_mutex; SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL; Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map; ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL; void ParticlesMaterial::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - dirty_materials = memnew(SelfList<ParticlesMaterial>::List); shader_names = memnew(ShaderNames); @@ -107,10 +103,6 @@ void ParticlesMaterial::init_shaders() { void ParticlesMaterial::finish_shaders() { -#ifndef NO_THREADS - memdelete(material_mutex); -#endif - memdelete(dirty_materials); dirty_materials = NULL; @@ -189,7 +181,7 @@ void ParticlesMaterial::_update_shader() { } break; case EMISSION_SHAPE_DIRECTED_POINTS: { code += "uniform sampler2D emission_texture_normal : hint_black;\n"; - FALLTHROUGH; + [[fallthrough]]; } case EMISSION_SHAPE_POINTS: { code += "uniform sampler2D emission_texture_points : hint_black;\n"; @@ -316,14 +308,17 @@ void ParticlesMaterial::_update_shader() { if (flags[FLAG_DISABLE_Z]) { - code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n"; + code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n"; code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; @@ -609,44 +604,28 @@ void ParticlesMaterial::_update_shader() { void ParticlesMaterial::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } void ParticlesMaterial::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } bool ParticlesMaterial::_is_shader_dirty() const { - bool dirty = false; + MutexLock lock(material_mutex); - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); - - if (material_mutex) - material_mutex->unlock(); - - return dirty; + return element.in_list(); } void ParticlesMaterial::set_direction(Vector3 p_direction) { @@ -787,7 +766,7 @@ float ParticlesMaterial::get_param_randomness(Parameter p_param) const { return randomness[p_param]; } -static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, float p_max) { +static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, float p_max) { Ref<CurveTexture> curve_tex = p_texture; if (!curve_tex.is_valid()) @@ -796,7 +775,7 @@ static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, floa curve_tex->ensure_default_setup(p_min, p_max); } -void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> &p_texture) { +void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, PARAM_MAX); @@ -854,9 +833,9 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> _queue_shader_change(); } -Ref<Texture> ParticlesMaterial::get_param_texture(Parameter p_param) const { +Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const { - ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture>()); + ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture2D>()); return tex_parameters[p_param]; } @@ -872,7 +851,7 @@ Color ParticlesMaterial::get_color() const { return color; } -void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) { +void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture); @@ -880,7 +859,7 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) { _change_notify(); } -Ref<Texture> ParticlesMaterial::get_color_ramp() const { +Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { return color_ramp; } @@ -918,19 +897,19 @@ void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) { VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents); } -void ParticlesMaterial::set_emission_point_texture(const Ref<Texture> &p_points) { +void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) { emission_point_texture = p_points; VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points); } -void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture> &p_normals) { +void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) { emission_normal_texture = p_normals; VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals); } -void ParticlesMaterial::set_emission_color_texture(const Ref<Texture> &p_colors) { +void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) { emission_color_texture = p_colors; VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors); @@ -956,16 +935,16 @@ Vector3 ParticlesMaterial::get_emission_box_extents() const { return emission_box_extents; } -Ref<Texture> ParticlesMaterial::get_emission_point_texture() const { +Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const { return emission_point_texture; } -Ref<Texture> ParticlesMaterial::get_emission_normal_texture() const { +Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const { return emission_normal_texture; } -Ref<Texture> ParticlesMaterial::get_emission_color_texture() const { +Ref<Texture2D> ParticlesMaterial::get_emission_color_texture() const { return emission_color_texture; } @@ -1150,18 +1129,18 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness); ADD_GROUP("Time", ""); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_GROUP("Trail", "trail_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier"); ADD_GROUP("Emission Shape", "emission_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_point_texture", "get_emission_point_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_normal_texture", "get_emission_normal_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_color_texture", "get_emission_color_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_point_texture", "get_emission_point_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); @@ -1169,59 +1148,59 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity"); ADD_GROUP("Initial Velocity", "initial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); ADD_GROUP("Angular Velocity", "angular_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY); ADD_GROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_GROUP("Linear Accel", "linear_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL); ADD_GROUP("Radial Accel", "radial_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL); ADD_GROUP("Tangential Accel", "tangential_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL); ADD_GROUP("Damping", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING); ADD_GROUP("Angle", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE); ADD_GROUP("Scale", ""); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE); ADD_GROUP("Color", ""); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp"); ADD_GROUP("Hue Variation", "hue_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", 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("Animation", "anim_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); @@ -1295,8 +1274,7 @@ ParticlesMaterial::ParticlesMaterial() : ParticlesMaterial::~ParticlesMaterial() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -1308,7 +1286,4 @@ ParticlesMaterial::~ParticlesMaterial() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } - - if (material_mutex) - material_mutex->unlock(); } diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index cc860b3812..c6c8316995 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -126,7 +126,7 @@ private: return mk; } - static Mutex *material_mutex; + static Mutex material_mutex; static SelfList<ParticlesMaterial>::List *dirty_materials; struct ShaderNames { @@ -205,18 +205,18 @@ private: float parameters[PARAM_MAX]; float randomness[PARAM_MAX]; - Ref<Texture> tex_parameters[PARAM_MAX]; + Ref<Texture2D> tex_parameters[PARAM_MAX]; Color color; - Ref<Texture> color_ramp; + Ref<Texture2D> color_ramp; bool flags[FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; Vector3 emission_box_extents; - Ref<Texture> emission_point_texture; - Ref<Texture> emission_normal_texture; - Ref<Texture> emission_color_texture; + Ref<Texture2D> emission_point_texture; + Ref<Texture2D> emission_normal_texture; + Ref<Texture2D> emission_color_texture; int emission_point_count; bool anim_loop; @@ -252,14 +252,14 @@ public: void set_param_randomness(Parameter p_param, float p_value); float get_param_randomness(Parameter p_param) const; - void set_param_texture(Parameter p_param, const Ref<Texture> &p_texture); - Ref<Texture> get_param_texture(Parameter p_param) const; + void set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_param_texture(Parameter p_param) const; void set_color(const Color &p_color); Color get_color() const; - void set_color_ramp(const Ref<Texture> &p_texture); - Ref<Texture> get_color_ramp() const; + void set_color_ramp(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_color_ramp() const; void set_flag(Flags p_flag, bool p_enable); bool get_flag(Flags p_flag) const; @@ -267,17 +267,17 @@ public: void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); void set_emission_box_extents(Vector3 p_extents); - void set_emission_point_texture(const Ref<Texture> &p_points); - void set_emission_normal_texture(const Ref<Texture> &p_normals); - void set_emission_color_texture(const Ref<Texture> &p_colors); + void set_emission_point_texture(const Ref<Texture2D> &p_points); + void set_emission_normal_texture(const Ref<Texture2D> &p_normals); + void set_emission_color_texture(const Ref<Texture2D> &p_colors); void set_emission_point_count(int p_count); EmissionShape get_emission_shape() const; float get_emission_sphere_radius() const; Vector3 get_emission_box_extents() const; - Ref<Texture> get_emission_point_texture() const; - Ref<Texture> get_emission_normal_texture() const; - Ref<Texture> get_emission_color_texture() const; + Ref<Texture2D> get_emission_point_texture() const; + Ref<Texture2D> get_emission_normal_texture() const; + Ref<Texture2D> get_emission_color_texture() const; int get_emission_point_count() const; void set_trail_divisor(int p_divisor); diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp index 0db115ecc0..8ac0191452 100644 --- a/scene/resources/physics_material.cpp +++ b/scene/resources/physics_material.cpp @@ -44,9 +44,9 @@ void PhysicsMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_absorbent", "absorbent"), &PhysicsMaterial::set_absorbent); ClassDB::bind_method(D_METHOD("is_absorbent"), &PhysicsMaterial::is_absorbent); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction"), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rough"), "set_rough", "is_rough"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce"), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "absorbent"), "set_absorbent", "is_absorbent"); } diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index 9a1d478777..eff0721cef 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -415,7 +415,7 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("segments")); ERR_FAIL_COND(!p_data.has("bounds")); - PoolVector<Vector2> p = p_data["points"]; + Vector<Vector2> p = p_data["points"]; Array c = p_data["connections"]; ERR_FAIL_COND(c.size() != p.size()); @@ -425,11 +425,11 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { int pc = p.size(); points.resize(pc + 2); - PoolVector<Vector2>::Read pr = p.read(); + const Vector2 *pr = p.ptr(); for (int i = 0; i < pc; i++) { points.write[i].pos = pr[i]; - PoolVector<int> con = c[i]; - PoolVector<int>::Read cr = con.read(); + Vector<int> con = c[i]; + const int *cr = con.ptr(); int cc = con.size(); for (int j = 0; j < cc; j++) { @@ -439,19 +439,19 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { if (p_data.has("penalties")) { - PoolVector<float> penalties = p_data["penalties"]; + Vector<float> penalties = p_data["penalties"]; if (penalties.size() == pc) { - PoolVector<float>::Read pr2 = penalties.read(); + const float *pr2 = penalties.ptr(); for (int i = 0; i < pc; i++) { points.write[i].penalty = pr2[i]; } } } - PoolVector<int> segs = p_data["segments"]; + Vector<int> segs = p_data["segments"]; int sc = segs.size(); ERR_FAIL_COND(sc & 1); - PoolVector<int>::Read sr = segs.read(); + const int *sr = segs.ptr(); for (int i = 0; i < sc; i += 2) { Edge e(sr[i], sr[i + 1]); @@ -463,25 +463,25 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) { Dictionary PolygonPathFinder::_get_data() const { Dictionary d; - PoolVector<Vector2> p; - PoolVector<int> ind; + Vector<Vector2> p; + Vector<int> ind; Array connections; p.resize(MAX(0, points.size() - 2)); connections.resize(MAX(0, points.size() - 2)); ind.resize(edges.size() * 2); - PoolVector<float> penalties; + Vector<float> penalties; penalties.resize(MAX(0, points.size() - 2)); { - PoolVector<Vector2>::Write wp = p.write(); - PoolVector<float>::Write pw = penalties.write(); + Vector2 *wp = p.ptrw(); + float *pw = penalties.ptrw(); for (int i = 0; i < points.size() - 2; i++) { wp[i] = points[i].pos; pw[i] = points[i].penalty; - PoolVector<int> c; + Vector<int> c; c.resize(points[i].connections.size()); { - PoolVector<int>::Write cw = c.write(); + int *cw = c.ptrw(); int idx = 0; for (Set<int>::Element *E = points[i].connections.front(); E; E = E->next()) { cw[idx++] = E->get(); @@ -492,7 +492,7 @@ Dictionary PolygonPathFinder::_get_data() const { } { - PoolVector<int>::Write iw = ind.write(); + int *iw = ind.ptrw(); int idx = 0; for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) { iw[idx++] = E->get().points[0]; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 74df72619a..00fc016ca1 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -40,7 +40,7 @@ void PrimitiveMesh::_update() const { arr.resize(VS::ARRAY_MAX); _create_mesh_array(arr); - PoolVector<Vector3> points = arr[VS::ARRAY_VERTEX]; + Vector<Vector3> points = arr[VS::ARRAY_VERTEX]; aabb = AABB(); @@ -48,7 +48,7 @@ void PrimitiveMesh::_update() const { ERR_FAIL_COND(pc == 0); { - PoolVector<Vector3>::Read r = points.read(); + const Vector3 *r = points.ptr(); for (int i = 0; i < pc; i++) { if (i == 0) aabb.position = r[i]; @@ -57,14 +57,16 @@ void PrimitiveMesh::_update() const { } } + Vector<int> indices = arr[VS::ARRAY_INDEX]; + if (flip_faces) { - PoolVector<Vector3> normals = arr[VS::ARRAY_NORMAL]; - PoolVector<int> indices = arr[VS::ARRAY_INDEX]; + Vector<Vector3> normals = arr[VS::ARRAY_NORMAL]; + if (normals.size() && indices.size()) { { int nc = normals.size(); - PoolVector<Vector3>::Write w = normals.write(); + Vector3 *w = normals.ptrw(); for (int i = 0; i < nc; i++) { w[i] = -w[i]; } @@ -72,7 +74,7 @@ void PrimitiveMesh::_update() const { { int ic = indices.size(); - PoolVector<int>::Write w = indices.write(); + int *w = indices.ptrw(); for (int i = 0; i < ic; i += 3) { SWAP(w[i + 0], w[i + 1]); } @@ -82,6 +84,8 @@ void PrimitiveMesh::_update() const { } } + array_len = pc; + index_array_len = indices.size(); // in with the new VisualServer::get_singleton()->mesh_clear(mesh); VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr); @@ -114,7 +118,7 @@ int PrimitiveMesh::surface_get_array_len(int p_idx) const { _update(); } - return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0); + return array_len; } int PrimitiveMesh::surface_get_array_index_len(int p_idx) const { @@ -123,7 +127,7 @@ int PrimitiveMesh::surface_get_array_index_len(int p_idx) const { _update(); } - return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); + return index_array_len; } Array PrimitiveMesh::surface_get_arrays(int p_surface) const { @@ -135,22 +139,18 @@ Array PrimitiveMesh::surface_get_arrays(int p_surface) const { return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0); } +Dictionary PrimitiveMesh::surface_get_lods(int p_surface) const { + return Dictionary(); //not really supported +} Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { - ERR_FAIL_INDEX_V(p_surface, 1, Array()); - if (pending_request) { - _update(); - } - return Array(); + return Array(); //not really supported } uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); - if (pending_request) { - _update(); - } - return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0); + return VS::ARRAY_COMPRESS_DEFAULT; } Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { @@ -206,7 +206,7 @@ void PrimitiveMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces); ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces"); } @@ -261,6 +261,9 @@ PrimitiveMesh::PrimitiveMesh() { // make sure we do an update after we've finished constructing our object pending_request = true; + + array_len = 0; + index_array_len = 0; } PrimitiveMesh::~PrimitiveMesh() { @@ -279,11 +282,11 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { // note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -300,19 +303,19 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { v /= (rings + 1); w = sin(0.5 * Math_PI * v); - z = radius * cos(0.5 * Math_PI * v); + y = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - y = -cos(u * (Math_PI * 2.0)); + x = -sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); - Vector3 p = Vector3(x * radius * w, y * radius * w, z); - points.push_back(p + Vector3(0.0, 0.0, 0.5 * mid_height)); + Vector3 p = Vector3(x * radius * w, y, -z * radius * w); + points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0)); normals.push_back(p.normalized()); - ADD_TANGENT(-y, x, 0.0, 1.0) + ADD_TANGENT(z, 0.0, x, 1.0) uvs.push_back(Vector2(u, v * onethird)); point++; @@ -338,20 +341,20 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { v = j; v /= (rings + 1); - z = mid_height * v; - z = (mid_height * 0.5) - z; + y = mid_height * v; + y = (mid_height * 0.5) - y; for (i = 0; i <= radial_segments; i++) { u = i; u /= radial_segments; - x = sin(u * (Math_PI * 2.0)); - y = -cos(u * (Math_PI * 2.0)); + x = -sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); - Vector3 p = Vector3(x * radius, y * radius, z); + Vector3 p = Vector3(x * radius, y, -z * radius); points.push_back(p); - normals.push_back(Vector3(x, y, 0.0)); - ADD_TANGENT(-y, x, 0.0, 1.0) + normals.push_back(Vector3(x, 0.0, -z)); + ADD_TANGENT(z, 0.0, x, 1.0) uvs.push_back(Vector2(u, onethird + (v * onethird))); point++; @@ -379,19 +382,19 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { v /= (rings + 1); v += 1.0; w = sin(0.5 * Math_PI * v); - z = radius * cos(0.5 * Math_PI * v); + y = radius * cos(0.5 * Math_PI * v); for (i = 0; i <= radial_segments; i++) { float u2 = i; u2 /= radial_segments; - x = sin(u2 * (Math_PI * 2.0)); - y = -cos(u2 * (Math_PI * 2.0)); + x = -sin(u2 * (Math_PI * 2.0)); + z = cos(u2 * (Math_PI * 2.0)); - Vector3 p = Vector3(x * radius * w, y * radius * w, z); - points.push_back(p + Vector3(0.0, 0.0, -0.5 * mid_height)); + Vector3 p = Vector3(x * radius * w, y, -z * radius * w); + points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0)); normals.push_back(p.normalized()); - ADD_TANGENT(-y, x, 0.0, 1.0) + ADD_TANGENT(z, 0.0, x, 1.0) uvs.push_back(Vector2(u2, twothirds + ((v - 1.0) * onethird))); point++; @@ -428,8 +431,8 @@ void CapsuleMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CapsuleMesh::set_rings); ClassDB::bind_method(D_METHOD("get_rings"), &CapsuleMesh::get_rings); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_mid_height", "get_mid_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_mid_height", "get_mid_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings"); } @@ -492,11 +495,11 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { // set our bounding box - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -743,11 +746,11 @@ void CylinderMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z, u, v, radius; - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -888,9 +891,9 @@ void CylinderMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CylinderMesh::set_rings); ClassDB::bind_method(D_METHOD("get_rings"), &CylinderMesh::get_rings); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_top_radius", "get_top_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_bottom_radius", "get_bottom_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "top_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_top_radius", "get_top_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bottom_radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_bottom_radius", "get_bottom_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings"); } @@ -959,11 +962,11 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const { Size2 start_pos = size * -0.5; - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -1076,11 +1079,11 @@ void PrismMesh::_create_mesh_array(Array &p_arr) const { // set our bounding box - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -1288,7 +1291,7 @@ void PrismMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_subdivide_depth", "segments"), &PrismMesh::set_subdivide_depth); ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_height", "get_subdivide_height"); @@ -1354,10 +1357,10 @@ PrismMesh::PrismMesh() { */ void QuadMesh::_create_mesh_array(Array &p_arr) const { - PoolVector<Vector3> faces; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; + Vector<Vector3> faces; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; faces.resize(6); normals.resize(6); @@ -1434,11 +1437,11 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const { // set our bounding box - PoolVector<Vector3> points; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - PoolVector<int> indices; + Vector<Vector3> points; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int> indices; point = 0; #define ADD_TANGENT(m_x, m_y, m_z, m_d) \ @@ -1512,8 +1515,8 @@ void SphereMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_is_hemisphere", "is_hemisphere"), &SphereMesh::set_is_hemisphere); ClassDB::bind_method(D_METHOD("get_is_hemisphere"), &SphereMesh::get_is_hemisphere); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100.0,0.001,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_radial_segments", "get_radial_segments"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1,or_greater"), "set_rings", "get_rings"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_hemisphere"), "set_is_hemisphere", "get_is_hemisphere"); @@ -1578,7 +1581,7 @@ SphereMesh::SphereMesh() { */ void PointMesh::_create_mesh_array(Array &p_arr) const { - PoolVector<Vector3> faces; + Vector<Vector3> faces; faces.resize(1); faces.set(0, Vector3(0.0, 0.0, 0.0)); diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 47126f1862..5f17680c9e 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -50,6 +50,9 @@ private: mutable AABB aabb; AABB custom_aabb; + mutable int array_len; + mutable int index_array_len; + Ref<Material> material; bool flip_faces; @@ -70,6 +73,7 @@ public: virtual int surface_get_array_index_len(int p_idx) const; virtual Array surface_get_arrays(int p_surface) const; virtual Array surface_get_blend_shape_arrays(int p_surface) const; + virtual Dictionary surface_get_lods(int p_surface) const; virtual uint32_t surface_get_format(int p_idx) const; virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const; virtual void surface_set_material(int p_idx, const Ref<Material> &p_material); diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index 3062e96293..906abaf60c 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -41,6 +41,10 @@ Vector<Vector3> RayShape::get_debug_mesh_lines() { return points; } +real_t RayShape::get_enclosing_radius() const { + return length; +} + void RayShape::_update_shape() { Dictionary d; @@ -83,7 +87,7 @@ void RayShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape::set_slips_on_slope); ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape::get_slips_on_slope); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); } diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h index ddf9f56ea3..c89705ad7d 100644 --- a/scene/resources/ray_shape.h +++ b/scene/resources/ray_shape.h @@ -50,6 +50,7 @@ public: bool get_slips_on_slope() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; RayShape(); }; diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp index 0030e6dd4f..f8c8ffb289 100644 --- a/scene/resources/rectangle_shape_2d.cpp +++ b/scene/resources/rectangle_shape_2d.cpp @@ -59,6 +59,10 @@ Rect2 RectangleShape2D::get_rect() const { return Rect2(-extents, extents * 2.0); } +real_t RectangleShape2D::get_enclosing_radius() const { + return extents.length(); +} + void RectangleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &RectangleShape2D::set_extents); diff --git a/scene/resources/rectangle_shape_2d.h b/scene/resources/rectangle_shape_2d.h index 686b421a2a..68fc539085 100644 --- a/scene/resources/rectangle_shape_2d.h +++ b/scene/resources/rectangle_shape_2d.h @@ -48,6 +48,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; RectangleShape2D(); }; diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 849fb087ba..97bd12c119 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -35,7 +35,7 @@ #include "core/project_settings.h" #include "core/version.h" -//version 2: changed names for basis, aabb, poolvectors, etc. +//version 2: changed names for basis, aabb, Vectors, etc. #define FORMAT_VERSION 2 #include "core/os/dir_access.h" @@ -45,17 +45,17 @@ /// -void ResourceInteractiveLoaderText::set_local_path(const String &p_local_path) { +void ResourceLoaderText::set_local_path(const String &p_local_path) { res_path = p_local_path; } -Ref<Resource> ResourceInteractiveLoaderText::get_resource() { +Ref<Resource> ResourceLoaderText::get_resource() { return resource; } -Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { +Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); @@ -85,7 +85,7 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource_dummy(DummyReadData *p_ return OK; } -Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { +Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); @@ -109,7 +109,7 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource_dummy(DummyReadData *p_ return OK; } -Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { +Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); @@ -143,7 +143,7 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream * return OK; } -Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { +Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { VariantParser::Token token; VariantParser::get_token(p_stream, token, line, r_err_str); @@ -164,15 +164,30 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream * String path = ext_resources[id].path; String type = ext_resources[id].type; - if (path.find("://") == -1 && path.is_rel_path()) { - // path is relative to file being loaded, so convert to a resource path - path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path)); - } + if (ext_resources[id].cache.is_valid()) { + r_res = ext_resources[id].cache; + } else if (use_sub_threads) { - r_res = ResourceLoader::load(path, type); + RES res = ResourceLoader::load_threaded_get(path); + if (res.is_null()) { - if (r_res.is_null()) { - WARN_PRINT(String("Couldn't load external resource: " + path).utf8().get_data()); + if (ResourceLoader::get_abort_on_missing_resources()) { + error = ERR_FILE_CORRUPT; + error_text = "[ext_resource] referenced nonexistent resource at: " + path; + _printerr(); + return error; + } else { + ResourceLoader::notify_dependency_error(local_path, path, type); + } + } else { + ext_resources[id].cache = res; + r_res = res; + } + } else { + error = ERR_FILE_CORRUPT; + error_text = "[ext_resource] referenced non-loaded resource at: " + path; + _printerr(); + return error; } } else { r_res = RES(); @@ -187,7 +202,7 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream * return OK; } -Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) { +Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourceParser &parser) { Ref<PackedScene> packed_scene; packed_scene.instance(); @@ -278,6 +293,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R _printerr(); return Ref<PackedScene>(); } else { + error = OK; return packed_scene; } } @@ -321,7 +337,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R NodePath to = next_tag.fields["to"]; StringName method = next_tag.fields["method"]; StringName signal = next_tag.fields["signal"]; - int flags = CONNECT_PERSIST; + int flags = Object::CONNECT_PERSIST; Array binds; if (next_tag.fields.has("flags")) { @@ -352,6 +368,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R _printerr(); return Ref<PackedScene>(); } else { + error = OK; return packed_scene; } } @@ -375,6 +392,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R _printerr(); return Ref<PackedScene>(); } else { + error = OK; return packed_scene; } } @@ -389,12 +407,15 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R return packed_scene; } -Error ResourceInteractiveLoaderText::poll() { +Error ResourceLoaderText::load() { if (error != OK) return error; - if (next_tag.name == "ext_resource") { + while (true) { + if (next_tag.name != "ext_resource") { + break; + } if (!next_tag.fields.has("path")) { error = ERR_FILE_CORRUPT; @@ -430,30 +451,49 @@ Error ResourceInteractiveLoaderText::poll() { path = remaps[path]; } - RES res = ResourceLoader::load(path, type); + ExtResource er; + er.path = path; + er.type = type; + + if (use_sub_threads) { - if (res.is_null()) { + Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path); - if (ResourceLoader::get_abort_on_missing_resources()) { - error = ERR_FILE_CORRUPT; - error_text = "[ext_resource] referenced nonexistent resource at: " + path; - _printerr(); - return error; - } else { - ResourceLoader::notify_dependency_error(local_path, path, type); + if (err != OK) { + if (ResourceLoader::get_abort_on_missing_resources()) { + error = ERR_FILE_CORRUPT; + error_text = "[ext_resource] referenced broken resource at: " + path; + _printerr(); + return error; + } else { + ResourceLoader::notify_dependency_error(local_path, path, type); + } } + } else { + RES res = ResourceLoader::load(path, type); + + if (res.is_null()) { + + if (ResourceLoader::get_abort_on_missing_resources()) { + error = ERR_FILE_CORRUPT; + error_text = "[ext_resource] referenced nonexistent resource at: " + path; + _printerr(); + return error; + } else { + ResourceLoader::notify_dependency_error(local_path, path, type); + } + } else { - resource_cache.push_back(res); #ifdef TOOLS_ENABLED - //remember ID for saving - res->set_id_for_path(local_path, index); + //remember ID for saving + res->set_id_for_path(local_path, index); #endif + } + + er.cache = res; } - ExtResource er; - er.path = path; - er.type = type; ext_resources[index] = er; error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); @@ -463,9 +503,16 @@ Error ResourceInteractiveLoaderText::poll() { } resource_current++; - return error; + } - } else if (next_tag.name == "sub_resource") { + //these are the ones that count + resources_total -= resource_current; + resource_current = 0; + + while (true) { + if (next_tag.name != "sub_resource") { + break; + } if (!next_tag.fields.has("type")) { error = ERR_FILE_CORRUPT; @@ -546,9 +593,15 @@ Error ResourceInteractiveLoaderText::poll() { } } - return OK; + if (progress) { + *progress = resource_current / float(resources_total); + } + } - } else if (next_tag.name == "resource") { + while (true) { + if (next_tag.name != "resource") { + break; + } if (is_scene) { @@ -591,6 +644,7 @@ Error ResourceInteractiveLoaderText::poll() { if (error != ERR_FILE_EOF) { _printerr(); } else { + error = OK; if (!ResourceCache::has(res_path)) { resource->set_path(res_path); } @@ -609,14 +663,23 @@ Error ResourceInteractiveLoaderText::poll() { _printerr(); return error; } else { - error = ERR_FILE_EOF; + error = OK; + if (progress) { + *progress = resource_current / float(resources_total); + } + return error; } } - return OK; + if (progress) { + *progress = resource_current / float(resources_total); + } + } - } else if (next_tag.name == "node") { + //for scene files + + if (next_tag.name == "node") { if (!is_scene) { @@ -631,49 +694,54 @@ Error ResourceInteractiveLoaderText::poll() { if (!packed_scene.is_valid()) return error; - error = ERR_FILE_EOF; + error = OK; //get it here resource = packed_scene; if (!ResourceCache::has(res_path)) { packed_scene->set_path(res_path); } - return error; + resource_current++; + + if (progress) { + *progress = resource_current / float(resources_total); + } + return error; } else { error_text += "Unknown tag in file: " + next_tag.name; _printerr(); error = ERR_FILE_CORRUPT; return error; } - - return OK; } -int ResourceInteractiveLoaderText::get_stage() const { +int ResourceLoaderText::get_stage() const { return resource_current; } -int ResourceInteractiveLoaderText::get_stage_count() const { +int ResourceLoaderText::get_stage_count() const { return resources_total; //+ext_resources; } -void ResourceInteractiveLoaderText::set_translation_remapped(bool p_remapped) { +void ResourceLoaderText::set_translation_remapped(bool p_remapped) { translation_remapped = p_remapped; } -ResourceInteractiveLoaderText::ResourceInteractiveLoaderText() { +ResourceLoaderText::ResourceLoaderText() { + progress = nullptr; translation_remapped = false; + use_sub_threads = false; } -ResourceInteractiveLoaderText::~ResourceInteractiveLoaderText() { +ResourceLoaderText::~ResourceLoaderText() { memdelete(f); } -void ResourceInteractiveLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { +void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) { open(p_f); ignore_resource_parsing = true; @@ -720,7 +788,7 @@ void ResourceInteractiveLoaderText::get_dependencies(FileAccess *p_f, List<Strin } } -Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map) { +Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map) { open(p_f, true); ERR_FAIL_COND_V(error != OK, error); @@ -822,7 +890,7 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const return OK; } -void ResourceInteractiveLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) { +void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) { error = OK; @@ -908,7 +976,7 @@ static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); } -Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) { +Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) { if (error) return error; @@ -1172,7 +1240,7 @@ Error ResourceInteractiveLoaderText::save_as_binary(FileAccess *p_f, const Strin return OK; } -String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { +String ResourceLoaderText::recognize(FileAccess *p_f) { error = OK; @@ -1217,24 +1285,34 @@ String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) { ///////////////////// -Ref<ResourceInteractiveLoader> ResourceFormatLoaderText::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) *r_error = ERR_CANT_OPEN; Error err; + FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, Ref<ResourceInteractiveLoader>(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'."); - Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); + ResourceLoaderText loader; String path = p_original_path != "" ? p_original_path : p_path; - ria->local_path = ProjectSettings::get_singleton()->localize_path(path); - ria->res_path = ria->local_path; - //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); - ria->open(f); - - return ria; + loader.use_sub_threads = p_use_sub_threads; + loader.local_path = ProjectSettings::get_singleton()->localize_path(path); + loader.progress = r_progress; + loader.res_path = loader.local_path; + //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + loader.open(f); + err = loader.load(); + if (r_error) { + *r_error = err; + } + if (err == OK) { + return loader.get_resource(); + } else { + return RES(); + } } void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { @@ -1276,12 +1354,12 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const { return ""; //could not rwead } - Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); - ria->res_path = ria->local_path; - //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); - String r = ria->recognize(f); - return r; + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + String r = loader.recognize(f); + return ClassDB::get_compatibility_remapped_class(r); } void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { @@ -1292,11 +1370,11 @@ void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<Strin ERR_FAIL(); } - Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); - ria->res_path = ria->local_path; - //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); - ria->get_dependencies(f, p_dependencies, p_add_types); + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + loader.get_dependencies(f, p_dependencies, p_add_types); } Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { @@ -1307,11 +1385,11 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const ERR_FAIL_V(ERR_CANT_OPEN); } - Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); - ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path); - ria->res_path = ria->local_path; - //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); - return ria->rename_dependencies(f, p_path, p_map); + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + return loader.rename_dependencies(f, p_path, p_map); } ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = NULL; @@ -1323,13 +1401,13 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, ERR_FAIL_COND_V_MSG(err != OK, ERR_CANT_OPEN, "Cannot open file '" + p_src_path + "'."); - Ref<ResourceInteractiveLoaderText> ria = memnew(ResourceInteractiveLoaderText); + ResourceLoaderText loader; const String &path = p_src_path; - ria->local_path = ProjectSettings::get_singleton()->localize_path(path); - ria->res_path = ria->local_path; - //ria->set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); - ria->open(f); - return ria->save_as_binary(f, p_dst_path); + loader.local_path = ProjectSettings::get_singleton()->localize_path(path); + loader.res_path = loader.local_path; + //loader.set_local_path( ProjectSettings::get_singleton()->localize_path(p_path) ); + loader.open(f); + return loader.save_as_binary(f, p_dst_path); } /*****************************************************************************************************/ @@ -1377,7 +1455,7 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, switch (p_variant.get_type()) { case Variant::OBJECT: { - RES res = p_variant.operator RefPtr(); + RES res = p_variant; if (res.is_null() || external_resources.has(res)) return; diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 66c69725e8..2425ac7f6c 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -37,7 +37,7 @@ #include "core/variant_parser.h" #include "scene/resources/packed_scene.h" -class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { +class ResourceLoaderText { bool translation_remapped; String local_path; @@ -49,6 +49,7 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { VariantParser::StreamFile stream; struct ExtResource { + RES cache; String path; String type; }; @@ -68,13 +69,16 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { VariantParser::Tag next_tag; + bool use_sub_threads; + float *progress; + mutable int lines; Map<String, String> remaps; //void _printerr(); - static Error _parse_sub_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText *>(p_self)->_parse_sub_resource(p_stream, r_res, line, r_err_str); } - static Error _parse_ext_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText *>(p_self)->_parse_ext_resource(p_stream, r_res, line, r_err_str); } + static Error _parse_sub_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_sub_resource(p_stream, r_res, line, r_err_str); } + static Error _parse_ext_resources(void *p_self, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) { return reinterpret_cast<ResourceLoaderText *>(p_self)->_parse_ext_resource(p_stream, r_res, line, r_err_str); } Error _parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); Error _parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str); @@ -110,12 +114,12 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { Ref<PackedScene> _parse_node_tag(VariantParser::ResourceParser &parser); public: - virtual void set_local_path(const String &p_local_path); - virtual Ref<Resource> get_resource(); - virtual Error poll(); - virtual int get_stage() const; - virtual int get_stage_count() const; - virtual void set_translation_remapped(bool p_remapped); + void set_local_path(const String &p_local_path); + Ref<Resource> get_resource(); + Error load(); + int get_stage() const; + int get_stage_count() const; + void set_translation_remapped(bool p_remapped); void open(FileAccess *p_f, bool p_skip_first_tag = false); String recognize(FileAccess *p_f); @@ -123,14 +127,14 @@ public: Error rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map); Error save_as_binary(FileAccess *p_f, const String &p_path); - ResourceInteractiveLoaderText(); - ~ResourceInteractiveLoaderText(); + ResourceLoaderText(); + ~ResourceLoaderText(); }; class ResourceFormatLoaderText : public ResourceFormatLoader { public: static ResourceFormatLoaderText *singleton; - virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp index 0070de72a2..2e78a4fccf 100644 --- a/scene/resources/segment_shape_2d.cpp +++ b/scene/resources/segment_shape_2d.cpp @@ -82,6 +82,10 @@ Rect2 SegmentShape2D::get_rect() const { return rect; } +real_t SegmentShape2D::get_enclosing_radius() const { + return (a + b).length(); +} + void SegmentShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_a", "a"), &SegmentShape2D::set_a); @@ -138,6 +142,10 @@ Rect2 RayShape2D::get_rect() const { return rect; } +real_t RayShape2D::get_enclosing_radius() const { + return length; +} + void RayShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length); @@ -146,7 +154,7 @@ void RayShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope); ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "length"), "set_length", "get_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope"); } diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h index aaf838ebfb..ca10c24f07 100644 --- a/scene/resources/segment_shape_2d.h +++ b/scene/resources/segment_shape_2d.h @@ -55,6 +55,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; SegmentShape2D(); }; @@ -79,6 +80,7 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color); virtual Rect2 get_rect() const; + virtual real_t get_enclosing_radius() const; RayShape2D(); }; diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 44c2a46065..8f76c0165f 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -98,7 +98,7 @@ RID Shader::get_rid() const { return shader; } -void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture) { +void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture) { if (p_texture.is_valid()) { default_textures[p_param] = p_texture; @@ -111,17 +111,17 @@ void Shader::set_default_texture_param(const StringName &p_param, const Ref<Text emit_changed(); } -Ref<Texture> Shader::get_default_texture_param(const StringName &p_param) const { +Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) const { if (default_textures.has(p_param)) return default_textures[p_param]; else - return Ref<Texture>(); + return Ref<Texture2D>(); } void Shader::get_default_texture_param_list(List<StringName> *r_textures) const { - for (const Map<StringName, Ref<Texture> >::Element *E = default_textures.front(); E; E = E->next()) { + for (const Map<StringName, Ref<Texture2D> >::Element *E = default_textures.front(); E; E = E->next()) { r_textures->push_back(E->key()); } @@ -173,7 +173,7 @@ Shader::~Shader() { } //////////// -RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 67ae436a4c..5050632dd5 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -59,7 +59,7 @@ private: // conversion fast and save memory. mutable bool params_cache_dirty; mutable Map<StringName, StringName> params_cache; //map a shader param to a material param.. - Map<StringName, Ref<Texture> > default_textures; + Map<StringName, Ref<Texture2D> > default_textures; virtual void _update_shader() const; //used for visual shader protected: @@ -75,8 +75,8 @@ public: void get_param_list(List<PropertyInfo> *p_params) const; bool has_param(const StringName &p_param) const; - void set_default_texture_param(const StringName &p_param, const Ref<Texture> &p_texture); - Ref<Texture> get_default_texture_param(const StringName &p_param) const; + void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_default_texture_param(const StringName &p_param) const; void get_default_texture_param_list(List<StringName> *r_textures) const; virtual bool is_text_shader() const; @@ -101,7 +101,7 @@ VARIANT_ENUM_CAST(Shader::Mode); class ResourceFormatLoaderShader : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index b50c68727a..4a6da18f2b 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -35,7 +35,7 @@ #include "scene/resources/mesh.h" #include "servers/physics_server.h" -void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform) { +void Shape::add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform) { Vector<Vector3> toadd = get_debug_mesh_lines(); @@ -43,7 +43,7 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p int base = array.size(); array.resize(base + toadd.size()); - PoolVector<Vector3>::Write w = array.write(); + Vector3 *w = array.ptrw(); for (int i = 0; i < toadd.size(); i++) { w[i + base] = p_xform.xform(toadd[i]); } @@ -70,11 +70,11 @@ Ref<ArrayMesh> Shape::get_debug_mesh() { if (!lines.empty()) { //make mesh - PoolVector<Vector3> array; + Vector<Vector3> array; array.resize(lines.size()); { - PoolVector<Vector3>::Write w = array.write(); + Vector3 *w = array.ptrw(); for (int i = 0; i < lines.size(); i++) { w[i] = lines[i]; } @@ -106,7 +106,7 @@ void Shape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &Shape::get_margin); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin"); } Shape::Shape() : diff --git a/scene/resources/shape.h b/scene/resources/shape.h index 8fc265f3bc..e5ccbf7e28 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -32,6 +32,7 @@ #define SHAPE_H #include "core/resource.h" + class ArrayMesh; class Shape : public Resource { @@ -57,8 +58,10 @@ public: Ref<ArrayMesh> get_debug_mesh(); virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } + /// Returns the radius of a sphere that fully enclose this shape + virtual real_t get_enclosing_radius() const = 0; - void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform); + void add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform); real_t get_margin() const; void set_margin(real_t p_margin); diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp index 9e97c65a3c..64930c3117 100644 --- a/scene/resources/shape_2d.cpp +++ b/scene/resources/shape_2d.cpp @@ -105,7 +105,7 @@ void Shape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("collide_and_get_contacts", "local_xform", "with_shape", "shape_xform"), &Shape2D::collide_and_get_contacts); ClassDB::bind_method(D_METHOD("collide_with_motion_and_get_contacts", "local_xform", "local_motion", "with_shape", "shape_xform", "shape_motion"), &Shape2D::collide_with_motion_and_get_contacts); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_solver_bias", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_custom_solver_bias", "get_custom_solver_bias"); } Shape2D::Shape2D(const RID &p_rid) { diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index 13ad7492ae..e2933ec031 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -58,6 +58,8 @@ public: virtual void draw(const RID &p_to_rid, const Color &p_color) {} virtual Rect2 get_rect() const { return Rect2(); } + /// Returns the radius of a circle that fully enclose this shape + virtual real_t get_enclosing_radius() const = 0; virtual RID get_rid() const; Shape2D(); ~Shape2D(); diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp index 9c8710a59c..df0620b6c4 100644 --- a/scene/resources/skin.cpp +++ b/scene/resources/skin.cpp @@ -45,6 +45,24 @@ void Skin::add_bind(int p_bone, const Transform &p_pose) { set_bind_pose(index, p_pose); } +void Skin::add_named_bind(const String &p_name, const Transform &p_pose) { + + uint32_t index = bind_count; + set_bind_count(bind_count + 1); + set_bind_name(index, p_name); + set_bind_pose(index, p_pose); +} + +void Skin::set_bind_name(int p_index, const StringName &p_name) { + ERR_FAIL_INDEX(p_index, bind_count); + bool notify_change = (binds_ptr[p_index].name != StringName()) != (p_name != StringName()); + binds_ptr[p_index].name = p_name; + emit_changed(); + if (notify_change) { + _change_notify(); + } +} + void Skin::set_bind_bone(int p_index, int p_bone) { ERR_FAIL_INDEX(p_index, bind_count); binds_ptr[p_index].bone = p_bone; @@ -75,6 +93,9 @@ bool Skin::_set(const StringName &p_name, const Variant &p_value) { if (what == "bone") { set_bind_bone(index, p_value); return true; + } else if (what == "name") { + set_bind_name(index, p_value); + return true; } else if (what == "pose") { set_bind_pose(index, p_value); return true; @@ -95,6 +116,9 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const { if (what == "bone") { r_ret = get_bind_bone(index); return true; + } else if (what == "name") { + r_ret = get_bind_name(index); + return true; } else if (what == "pose") { r_ret = get_bind_pose(index); return true; @@ -105,7 +129,8 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const { void Skin::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "bind_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater")); for (int i = 0; i < get_bind_count(); i++) { - p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater")); + p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bind/" + itos(i) + "/name")); + p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater", get_bind_name(i) != StringName() ? PROPERTY_USAGE_NOEDITOR : PROPERTY_USAGE_DEFAULT)); p_list->push_back(PropertyInfo(Variant::TRANSFORM, "bind/" + itos(i) + "/pose")); } } @@ -120,6 +145,9 @@ void Skin::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose); ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose); + ClassDB::bind_method(D_METHOD("set_bind_name", "bind_index", "name"), &Skin::set_bind_name); + ClassDB::bind_method(D_METHOD("get_bind_name", "bind_index"), &Skin::get_bind_name); + ClassDB::bind_method(D_METHOD("set_bind_bone", "bind_index", "bone"), &Skin::set_bind_bone); ClassDB::bind_method(D_METHOD("get_bind_bone", "bind_index"), &Skin::get_bind_bone); diff --git a/scene/resources/skin.h b/scene/resources/skin.h index ddc7c655f5..57aaf1afd4 100644 --- a/scene/resources/skin.h +++ b/scene/resources/skin.h @@ -37,7 +37,8 @@ class Skin : public Resource { GDCLASS(Skin, Resource) struct Bind { - int bone; + int bone = -1; + StringName name; Transform pose; }; @@ -58,9 +59,11 @@ public: inline int get_bind_count() const { return bind_count; } void add_bind(int p_bone, const Transform &p_pose); + void add_named_bind(const String &p_name, const Transform &p_pose); void set_bind_bone(int p_index, int p_bone); void set_bind_pose(int p_index, const Transform &p_pose); + void set_bind_name(int p_index, const StringName &p_name); inline int get_bind_bone(int p_index) const { #ifdef DEBUG_ENABLED @@ -69,6 +72,13 @@ public: return binds_ptr[p_index].bone; } + inline StringName get_bind_name(int p_index) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_INDEX_V(p_index, bind_count, StringName()); +#endif + return binds_ptr[p_index].name; + } + inline Transform get_bind_pose(int p_index) const { #ifdef DEBUG_ENABLED ERR_FAIL_INDEX_V(p_index, bind_count, Transform()); diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp index c20fbb4129..54648e8af7 100644 --- a/scene/resources/sky.cpp +++ b/scene/resources/sky.cpp @@ -36,7 +36,10 @@ void Sky::set_radiance_size(RadianceSize p_size) { ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX); radiance_size = p_size; - _radiance_changed(); + static const int size[RADIANCE_SIZE_MAX] = { + 32, 64, 128, 256, 512, 1024, 2048 + }; + VS::get_singleton()->sky_set_radiance_size(sky, size[radiance_size]); } Sky::RadianceSize Sky::get_radiance_size() const { @@ -44,12 +47,30 @@ Sky::RadianceSize Sky::get_radiance_size() const { return radiance_size; } +void Sky::set_process_mode(ProcessMode p_mode) { + mode = p_mode; + VS::get_singleton()->sky_set_mode(sky, VS::SkyMode(mode)); +} + +Sky::ProcessMode Sky::get_process_mode() const { + return mode; +} + +RID Sky::get_rid() const { + + return sky; +} + void Sky::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size); ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size); + ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Sky::set_process_mode); + ClassDB::bind_method(D_METHOD("get_process_mode"), &Sky::get_process_mode); + ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "32,64,128,256,512,1024,2048"), "set_radiance_size", "get_radiance_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "HighQuality,RealTime"), "set_process_mode", "get_process_mode"); BIND_ENUM_CONSTANT(RADIANCE_SIZE_32); BIND_ENUM_CONSTANT(RADIANCE_SIZE_64); @@ -59,82 +80,57 @@ void Sky::_bind_methods() { BIND_ENUM_CONSTANT(RADIANCE_SIZE_1024); BIND_ENUM_CONSTANT(RADIANCE_SIZE_2048); BIND_ENUM_CONSTANT(RADIANCE_SIZE_MAX); + + BIND_ENUM_CONSTANT(PROCESS_MODE_QUALITY); + BIND_ENUM_CONSTANT(PROCESS_MODE_REALTIME); } Sky::Sky() { + mode = PROCESS_MODE_QUALITY; radiance_size = RADIANCE_SIZE_128; + sky = VS::get_singleton()->sky_create(); } -///////////////////////////////////////// - -void PanoramaSky::_radiance_changed() { +Sky::~Sky() { - if (panorama.is_valid()) { - static const int size[RADIANCE_SIZE_MAX] = { - 32, 64, 128, 256, 512, 1024, 2048 - }; - VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]); - } + VS::get_singleton()->free(sky); } -void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) { - - panorama = p_panorama; +///////////////////////////////////////// - if (panorama.is_valid()) { +void PanoramaSky::set_panorama(const Ref<Texture2D> &p_panorama) { - _radiance_changed(); + panorama = p_panorama; - } else { - VS::get_singleton()->sky_set_texture(sky, RID(), 0); - } + RID rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID(); + VS::get_singleton()->sky_set_texture(get_rid(), rid); } -Ref<Texture> PanoramaSky::get_panorama() const { +Ref<Texture2D> PanoramaSky::get_panorama() const { return panorama; } -RID PanoramaSky::get_rid() const { - - return sky; -} - void PanoramaSky::_bind_methods() { ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSky::set_panorama); ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSky::get_panorama); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_panorama", "get_panorama"); } PanoramaSky::PanoramaSky() { - - sky = VS::get_singleton()->sky_create(); } PanoramaSky::~PanoramaSky() { - - VS::get_singleton()->free(sky); } ////////////////////////////////// -void ProceduralSky::_radiance_changed() { - - if (update_queued) - return; //do nothing yet - - static const int size[RADIANCE_SIZE_MAX] = { - 32, 64, 128, 256, 512, 1024, 2048 - }; - VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]); -} - Ref<Image> ProceduralSky::_generate_sky() { update_queued = false; - PoolVector<uint8_t> imgdata; + Vector<uint8_t> imgdata; static const int size[TEXTURE_SIZE_MAX] = { 256, 512, 1024, 2048, 4096 @@ -146,9 +142,9 @@ Ref<Image> ProceduralSky::_generate_sky() { imgdata.resize(w * h * 4); //RGBE { - PoolVector<uint8_t>::Write dataw = imgdata.write(); + uint8_t *dataw = imgdata.ptrw(); - uint32_t *ptr = (uint32_t *)dataw.ptr(); + uint32_t *ptr = (uint32_t *)dataw; Color sky_top_linear = sky_top_color.to_linear(); Color sky_horizon_linear = sky_horizon_color.to_linear(); @@ -390,10 +386,6 @@ ProceduralSky::TextureSize ProceduralSky::get_texture_size() const { return texture_size; } -RID ProceduralSky::get_rid() const { - return sky; -} - void ProceduralSky::_update_sky() { bool use_thread = true; @@ -415,9 +407,13 @@ void ProceduralSky::_update_sky() { } else { Ref<Image> image = _generate_sky(); - VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); - VS::get_singleton()->texture_set_data(texture, image); - _radiance_changed(); + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(image); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_create(image); + } + VS::get_singleton()->sky_set_texture(get_rid(), texture); } } @@ -432,9 +428,15 @@ void ProceduralSky::_queue_update() { void ProceduralSky::_thread_done(const Ref<Image> &p_image) { - VS::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, Image::FORMAT_RGBE9995, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT); - VS::get_singleton()->texture_set_data(texture, p_image); - _radiance_changed(); + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(p_image); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_create(p_image); + } + + VS::get_singleton()->sky_set_texture(get_rid(), texture); + Thread::wait_to_finish(sky_thread); memdelete(sky_thread); sky_thread = NULL; @@ -507,25 +509,25 @@ void ProceduralSky::_bind_methods() { ADD_GROUP("Sky", "sky_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy"); ADD_GROUP("Ground", "ground_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy"); ADD_GROUP("Sun", "sun_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy"); - - ADD_GROUP("Texture", "texture_"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy"); + + ADD_GROUP("Texture2D", "texture_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_texture_size", "get_texture_size"); BIND_ENUM_CONSTANT(TEXTURE_SIZE_256); @@ -538,9 +540,6 @@ void ProceduralSky::_bind_methods() { ProceduralSky::ProceduralSky(bool p_desaturate) { - sky = VS::get_singleton()->sky_create(); - texture = VS::get_singleton()->texture_create(); - update_queued = false; sky_top_color = Color::hex(0xa5d6f1ff); sky_horizon_color = Color::hex(0xd6eafaff); @@ -581,6 +580,7 @@ ProceduralSky::~ProceduralSky() { memdelete(sky_thread); sky_thread = NULL; } - VS::get_singleton()->free(sky); - VS::get_singleton()->free(texture); + if (texture.is_valid()) { + VS::get_singleton()->free(texture); + } } diff --git a/scene/resources/sky.h b/scene/resources/sky.h index 70ea9c4c18..09ebbd88a0 100644 --- a/scene/resources/sky.h +++ b/scene/resources/sky.h @@ -49,37 +49,47 @@ public: RADIANCE_SIZE_MAX }; + enum ProcessMode { + PROCESS_MODE_QUALITY, + PROCESS_MODE_REALTIME + }; + private: + RID sky; + ProcessMode mode; RadianceSize radiance_size; protected: static void _bind_methods(); - virtual void _radiance_changed() = 0; public: void set_radiance_size(RadianceSize p_size); RadianceSize get_radiance_size() const; + + void set_process_mode(ProcessMode p_mode); + ProcessMode get_process_mode() const; + + virtual RID get_rid() const; + Sky(); + ~Sky(); }; VARIANT_ENUM_CAST(Sky::RadianceSize) +VARIANT_ENUM_CAST(Sky::ProcessMode) class PanoramaSky : public Sky { GDCLASS(PanoramaSky, Sky); private: - RID sky; - Ref<Texture> panorama; + Ref<Texture2D> panorama; protected: static void _bind_methods(); - virtual void _radiance_changed(); public: - void set_panorama(const Ref<Texture> &p_panorama); - Ref<Texture> get_panorama() const; - - virtual RID get_rid() const; + void set_panorama(const Ref<Texture2D> &p_panorama); + Ref<Texture2D> get_panorama() const; PanoramaSky(); ~PanoramaSky(); @@ -120,7 +130,6 @@ private: TextureSize texture_size; - RID sky; RID texture; bool update_queued; @@ -133,7 +142,6 @@ private: protected: static void _bind_methods(); - virtual void _radiance_changed(); Ref<Image> _generate_sky(); void _update_sky(); @@ -189,8 +197,6 @@ public: void set_texture_size(TextureSize p_size); TextureSize get_texture_size() const; - virtual RID get_rid() const; - ProceduralSky(bool p_desaturate = false); ~ProceduralSky(); }; diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp index f408717834..825708d1e2 100644 --- a/scene/resources/sphere_shape.cpp +++ b/scene/resources/sphere_shape.cpp @@ -55,6 +55,10 @@ Vector<Vector3> SphereShape::get_debug_mesh_lines() { return points; } +real_t SphereShape::get_enclosing_radius() const { + return radius; +} + void SphereShape::_update_shape() { PhysicsServer::get_singleton()->shape_set_data(get_shape(), radius); @@ -79,7 +83,7 @@ void SphereShape::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereShape::set_radius); ClassDB::bind_method(D_METHOD("get_radius"), &SphereShape::get_radius); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius"); } SphereShape::SphereShape() : diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h index 6002a3baeb..07e8f1e233 100644 --- a/scene/resources/sphere_shape.h +++ b/scene/resources/sphere_shape.h @@ -48,6 +48,7 @@ public: float get_radius() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const; SphereShape(); }; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 9408d1aa71..119cbcd098 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -104,10 +104,10 @@ void StyleBox::_bind_methods() { ClassDB::bind_method(D_METHOD("draw", "canvas_item", "rect"), &StyleBox::draw); ADD_GROUP("Content Margin", "content_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_left", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_right", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_top", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "content_margin_bottom", PROPERTY_HINT_RANGE, "-1,2048,1"), "set_default_margin", "get_default_margin", MARGIN_BOTTOM); } StyleBox::StyleBox() { @@ -118,7 +118,7 @@ StyleBox::StyleBox() { } } -void StyleBoxTexture::set_texture(Ref<Texture> p_texture) { +void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) { if (texture == p_texture) return; @@ -133,12 +133,12 @@ void StyleBoxTexture::set_texture(Ref<Texture> p_texture) { _change_notify("texture"); } -Ref<Texture> StyleBoxTexture::get_texture() const { +Ref<Texture2D> StyleBoxTexture::get_texture() const { return texture; } -void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) { +void StyleBoxTexture::set_normal_map(Ref<Texture2D> p_normal_map) { if (normal_map == p_normal_map) return; @@ -146,7 +146,7 @@ void StyleBoxTexture::set_normal_map(Ref<Texture> p_normal_map) { emit_changed(); } -Ref<Texture> StyleBoxTexture::get_normal_map() const { +Ref<Texture2D> StyleBoxTexture::get_normal_map() const { return normal_map; } @@ -335,19 +335,19 @@ void StyleBoxTexture::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_GROUP("Margin", "margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_BOTTOM); ADD_GROUP("Expand Margin", "expand_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin_size", "get_expand_margin_size", MARGIN_BOTTOM); ADD_GROUP("Axis Stretch", "axis_stretch_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_horizontal", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_h_axis_stretch_mode", "get_h_axis_stretch_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_stretch_vertical", PROPERTY_HINT_ENUM, "Stretch,Tile,Tile Fit"), "set_v_axis_stretch_mode", "get_v_axis_stretch_mode"); @@ -933,10 +933,10 @@ void StyleBoxFlat::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "corner_detail", PROPERTY_HINT_RANGE, "1,20,1"), "set_corner_detail", "get_corner_detail"); ADD_GROUP("Expand Margin", "expand_margin_"); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_BOTTOM); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_right", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_top", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "expand_margin_bottom", PROPERTY_HINT_RANGE, "0,2048,1"), "set_expand_margin", "get_expand_margin", MARGIN_BOTTOM); ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); @@ -1035,8 +1035,8 @@ void StyleBoxLine::_bind_methods() { ClassDB::bind_method(D_METHOD("is_vertical"), &StyleBoxLine::is_vertical); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_begin", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_begin", "get_grow_begin"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "grow_end", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_end", "get_grow_end"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_begin", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_begin", "get_grow_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "grow_end", PROPERTY_HINT_RANGE, "-300,300,1"), "set_grow_end", "get_grow_end"); ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 3e0fffdcd9..1aa1a00c55 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -92,8 +92,8 @@ private: float expand_margin[4]; float margin[4]; Rect2 region_rect; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; bool draw_center; Color modulate; AxisStretchMode axis_h; @@ -115,11 +115,11 @@ public: void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; - void set_texture(Ref<Texture> p_texture); - Ref<Texture> get_texture() const; + void set_texture(Ref<Texture2D> p_texture); + Ref<Texture2D> get_texture() const; - void set_normal_map(Ref<Texture> p_normal_map); - Ref<Texture> get_normal_map() const; + void set_normal_map(Ref<Texture2D> p_normal_map); + Ref<Texture2D> get_normal_map() const; void set_draw_center(bool p_enabled); bool is_draw_center_enabled() const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index f921a9695c..fa177d03fb 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -288,9 +288,9 @@ Array SurfaceTool::commit_to_arrays() { case Mesh::ARRAY_VERTEX: case Mesh::ARRAY_NORMAL: { - PoolVector<Vector3> array; + Vector<Vector3> array; array.resize(varr_len); - PoolVector<Vector3>::Write w = array.write(); + Vector3 *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { @@ -307,7 +307,6 @@ Array SurfaceTool::commit_to_arrays() { } } - w.release(); a[i] = array; } break; @@ -315,9 +314,9 @@ Array SurfaceTool::commit_to_arrays() { case Mesh::ARRAY_TEX_UV: case Mesh::ARRAY_TEX_UV2: { - PoolVector<Vector2> array; + Vector<Vector2> array; array.resize(varr_len); - PoolVector<Vector2>::Write w = array.write(); + Vector2 *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { @@ -335,14 +334,13 @@ Array SurfaceTool::commit_to_arrays() { } } - w.release(); a[i] = array; } break; case Mesh::ARRAY_TANGENT: { - PoolVector<float> array; + Vector<float> array; array.resize(varr_len * 4); - PoolVector<float>::Write w = array.write(); + float *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { @@ -358,15 +356,14 @@ Array SurfaceTool::commit_to_arrays() { w[idx + 3] = d < 0 ? -1 : 1; } - w.release(); a[i] = array; } break; case Mesh::ARRAY_COLOR: { - PoolVector<Color> array; + Vector<Color> array; array.resize(varr_len); - PoolVector<Color>::Write w = array.write(); + Color *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { @@ -375,14 +372,13 @@ Array SurfaceTool::commit_to_arrays() { w[idx] = v.color; } - w.release(); a[i] = array; } break; case Mesh::ARRAY_BONES: { - PoolVector<int> array; + Vector<int> array; array.resize(varr_len * 4); - PoolVector<int>::Write w = array.write(); + int *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { @@ -396,15 +392,14 @@ Array SurfaceTool::commit_to_arrays() { } } - w.release(); a[i] = array; } break; case Mesh::ARRAY_WEIGHTS: { - PoolVector<float> array; + Vector<float> array; array.resize(varr_len * 4); - PoolVector<float>::Write w = array.write(); + float *w = array.ptrw(); int idx = 0; for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { @@ -418,7 +413,6 @@ Array SurfaceTool::commit_to_arrays() { } } - w.release(); a[i] = array; } break; @@ -426,9 +420,9 @@ Array SurfaceTool::commit_to_arrays() { ERR_CONTINUE(index_array.size() == 0); - PoolVector<int> array; + Vector<int> array; array.resize(index_array.size()); - PoolVector<int>::Write w = array.write(); + int *w = array.ptrw(); int idx = 0; for (List<int>::Element *E = index_array.front(); E; E = E->next(), idx++) { @@ -436,8 +430,6 @@ Array SurfaceTool::commit_to_arrays() { w[idx] = E->get(); } - w.release(); - a[i] = array; } break; @@ -466,7 +458,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_ Array a = commit_to_arrays(); - mesh->add_surface_from_arrays(primitive, a, Array(), p_flags); + mesh->add_surface_from_arrays(primitive, a, Array(), Dictionary(), p_flags); if (material.is_valid()) mesh->surface_set_material(surface, material); @@ -535,68 +527,46 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array Vector<SurfaceTool::Vertex> ret; - PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX]; - PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL]; - PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT]; - PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR]; - PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV]; - PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2]; - PoolVector<int> barr = p_arrays[VS::ARRAY_BONES]; - PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS]; + Vector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX]; + Vector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL]; + Vector<float> tarr = p_arrays[VS::ARRAY_TANGENT]; + Vector<Color> carr = p_arrays[VS::ARRAY_COLOR]; + Vector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV]; + Vector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2]; + Vector<int> barr = p_arrays[VS::ARRAY_BONES]; + Vector<float> warr = p_arrays[VS::ARRAY_WEIGHTS]; int vc = varr.size(); - if (vc == 0) return ret; - int lformat = 0; - PoolVector<Vector3>::Read rv; + int lformat = 0; if (varr.size()) { lformat |= VS::ARRAY_FORMAT_VERTEX; - rv = varr.read(); } - PoolVector<Vector3>::Read rn; if (narr.size()) { lformat |= VS::ARRAY_FORMAT_NORMAL; - rn = narr.read(); } - PoolVector<float>::Read rt; if (tarr.size()) { lformat |= VS::ARRAY_FORMAT_TANGENT; - rt = tarr.read(); } - PoolVector<Color>::Read rc; if (carr.size()) { lformat |= VS::ARRAY_FORMAT_COLOR; - rc = carr.read(); } - - PoolVector<Vector2>::Read ruv; if (uvarr.size()) { lformat |= VS::ARRAY_FORMAT_TEX_UV; - ruv = uvarr.read(); } - - PoolVector<Vector2>::Read ruv2; if (uv2arr.size()) { lformat |= VS::ARRAY_FORMAT_TEX_UV2; - ruv2 = uv2arr.read(); } - - PoolVector<int>::Read rb; if (barr.size()) { lformat |= VS::ARRAY_FORMAT_BONES; - rb = barr.read(); } - - PoolVector<float>::Read rw; if (warr.size()) { lformat |= VS::ARRAY_FORMAT_WEIGHTS; - rw = warr.read(); } for (int i = 0; i < vc; i++) { - Vertex v; if (lformat & VS::ARRAY_FORMAT_VERTEX) v.vertex = varr[i]; @@ -640,68 +610,46 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { - PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX]; - PoolVector<Vector3> narr = arr[VS::ARRAY_NORMAL]; - PoolVector<float> tarr = arr[VS::ARRAY_TANGENT]; - PoolVector<Color> carr = arr[VS::ARRAY_COLOR]; - PoolVector<Vector2> uvarr = arr[VS::ARRAY_TEX_UV]; - PoolVector<Vector2> uv2arr = arr[VS::ARRAY_TEX_UV2]; - PoolVector<int> barr = arr[VS::ARRAY_BONES]; - PoolVector<float> warr = arr[VS::ARRAY_WEIGHTS]; + Vector<Vector3> varr = arr[VS::ARRAY_VERTEX]; + Vector<Vector3> narr = arr[VS::ARRAY_NORMAL]; + Vector<float> tarr = arr[VS::ARRAY_TANGENT]; + Vector<Color> carr = arr[VS::ARRAY_COLOR]; + Vector<Vector2> uvarr = arr[VS::ARRAY_TEX_UV]; + Vector<Vector2> uv2arr = arr[VS::ARRAY_TEX_UV2]; + Vector<int> barr = arr[VS::ARRAY_BONES]; + Vector<float> warr = arr[VS::ARRAY_WEIGHTS]; int vc = varr.size(); - if (vc == 0) return; - lformat = 0; - PoolVector<Vector3>::Read rv; + lformat = 0; if (varr.size()) { lformat |= VS::ARRAY_FORMAT_VERTEX; - rv = varr.read(); } - PoolVector<Vector3>::Read rn; if (narr.size()) { lformat |= VS::ARRAY_FORMAT_NORMAL; - rn = narr.read(); } - PoolVector<float>::Read rt; if (tarr.size()) { lformat |= VS::ARRAY_FORMAT_TANGENT; - rt = tarr.read(); } - PoolVector<Color>::Read rc; if (carr.size()) { lformat |= VS::ARRAY_FORMAT_COLOR; - rc = carr.read(); } - - PoolVector<Vector2>::Read ruv; if (uvarr.size()) { lformat |= VS::ARRAY_FORMAT_TEX_UV; - ruv = uvarr.read(); } - - PoolVector<Vector2>::Read ruv2; if (uv2arr.size()) { lformat |= VS::ARRAY_FORMAT_TEX_UV2; - ruv2 = uv2arr.read(); } - - PoolVector<int>::Read rb; if (barr.size()) { lformat |= VS::ARRAY_FORMAT_BONES; - rb = barr.read(); } - - PoolVector<float>::Read rw; if (warr.size()) { lformat |= VS::ARRAY_FORMAT_WEIGHTS; - rw = warr.read(); } for (int i = 0; i < vc; i++) { - Vertex v; if (lformat & VS::ARRAY_FORMAT_VERTEX) v.vertex = varr[i]; @@ -742,12 +690,12 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li //indices - PoolVector<int> idx = arr[VS::ARRAY_INDEX]; + Vector<int> idx = arr[VS::ARRAY_INDEX]; int is = idx.size(); if (is) { lformat |= VS::ARRAY_FORMAT_INDEX; - PoolVector<int>::Read iarr = idx.read(); + const int *iarr = idx.ptr(); for (int i = 0; i < is; i++) { r_index->push_back(iarr[i]); } diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index af55d2dde3..e291dcb67e 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -50,7 +50,7 @@ void TextFile::reload_from_file() { Error TextFile::load_text(const String &p_path) { - PoolVector<uint8_t> sourcef; + Vector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -58,15 +58,15 @@ Error TextFile::load_text(const String &p_path) { int len = f->get_len(); sourcef.resize(len + 1); - PoolVector<uint8_t>::Write w = sourcef.write(); - int r = f->get_buffer(w.ptr(), len); + uint8_t *w = sourcef.ptrw(); + int r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); w[len] = 0; String s; - ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w.ptr()), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode."); + ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode."); text = s; path = p_path; return OK; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index b7805b7e38..cb827c4b0b 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -38,31 +38,37 @@ #include "scene/resources/bit_map.h" #include "servers/camera/camera_feed.h" -Size2 Texture::get_size() const { +Size2 Texture2D::get_size() const { return Size2(get_width(), get_height()); } -bool Texture::is_pixel_opaque(int p_x, int p_y) const { +bool Texture2D::is_pixel_opaque(int p_x, int p_y) const { return true; } -void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { + +void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { + +void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { + +void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat); } -bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { +bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { r_rect = p_rect; r_src_rect = p_src_rect; @@ -70,34 +76,21 @@ bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect return true; } -void Texture::_bind_methods() { +void Texture2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_width"), &Texture::get_width); - ClassDB::bind_method(D_METHOD("get_height"), &Texture::get_height); - ClassDB::bind_method(D_METHOD("get_size"), &Texture::get_size); - ClassDB::bind_method(D_METHOD("has_alpha"), &Texture::has_alpha); - ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture::set_flags); - ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags); - ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_data"), &Texture::get_data); + ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width); + ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height); + ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size); + ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha); + ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT)); + ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT)); + ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data); - ADD_GROUP("Flags", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic Linear,Convert to Linear,Mirrored Repeat,Video Surface"), "set_flags", "get_flags"); ADD_GROUP("", ""); - - BIND_ENUM_CONSTANT(FLAGS_DEFAULT); - BIND_ENUM_CONSTANT(FLAG_MIPMAPS); - BIND_ENUM_CONSTANT(FLAG_REPEAT); - BIND_ENUM_CONSTANT(FLAG_FILTER); - BIND_ENUM_CONSTANT(FLAG_ANISOTROPIC_FILTER); - BIND_ENUM_CONSTANT(FLAG_CONVERT_TO_LINEAR); - BIND_ENUM_CONSTANT(FLAG_MIRRORED_REPEAT); - BIND_ENUM_CONSTANT(FLAG_VIDEO_SURFACE); } -Texture::Texture() { +Texture2D::Texture2D() { } ///////////////////// @@ -108,12 +101,11 @@ void ImageTexture::reload_from_file() { if (!path.is_resource_file()) return; - uint32_t flags = get_flags(); Ref<Image> img; img.instance(); if (ImageLoader::load_image(path, img) == OK) { - create_from_image(img, flags); + create_from_image(img); } else { Resource::reload_from_file(); _change_notify(); @@ -124,19 +116,12 @@ void ImageTexture::reload_from_file() { bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) { if (p_name == "image") - create_from_image(p_value, flags); - else if (p_name == "flags") - if (w * h == 0) - flags = p_value; - else - set_flags(p_value); + create_from_image(p_value); else if (p_name == "size") { Size2 s = p_value; w = s.width; h = s.height; - VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0); - } else if (p_name == "_data") { - _set_data(p_value); + VisualServer::get_singleton()->texture_set_size_override(texture, w, h); } else return false; @@ -145,12 +130,8 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) { bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { - if (p_name == "image_data") { - - } else if (p_name == "image") + if (p_name == "image") r_ret = get_data(); - else if (p_name == "flags") - r_ret = flags; else if (p_name == "size") r_ret = Size2(w, h); else @@ -161,7 +142,6 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat")); p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "")); } @@ -178,79 +158,51 @@ void ImageTexture::_reload_hook(const RID &p_hook) { ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'."); - VisualServer::get_singleton()->texture_set_data(texture, img); + RID new_texture = VisualServer::get_singleton()->texture_2d_create(img); + VisualServer::get_singleton()->texture_replace(texture, new_texture); _change_notify(); emit_changed(); } -void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { - - flags = p_flags; - VisualServer::get_singleton()->texture_allocate(texture, p_width, p_height, 0, p_format, VS::TEXTURE_TYPE_2D, p_flags); - format = p_format; - w = p_width; - h = p_height; - _change_notify(); - emit_changed(); -} -void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) { +void ImageTexture::create_from_image(const Ref<Image> &p_image) { ERR_FAIL_COND(p_image.is_null()); - flags = p_flags; w = p_image->get_width(); h = p_image->get_height(); format = p_image->get_format(); + mipmaps = p_image->has_mipmaps(); - VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags); - VisualServer::get_singleton()->texture_set_data(texture, p_image); + if (texture.is_null()) { + texture = VisualServer::get_singleton()->texture_2d_create(p_image); + } else { + RID new_texture = VisualServer::get_singleton()->texture_2d_create(p_image); + VisualServer::get_singleton()->texture_replace(texture, new_texture); + } _change_notify(); emit_changed(); image_stored = true; } -void ImageTexture::set_flags(uint32_t p_flags) { - - if (flags == p_flags) - return; - - flags = p_flags; - if (w == 0 || h == 0) { - return; //uninitialized, do not set to texture - } - VisualServer::get_singleton()->texture_set_flags(texture, p_flags); - _change_notify("flags"); - emit_changed(); -} - -uint32_t ImageTexture::get_flags() const { - - return ImageTexture::flags; -} - Image::Format ImageTexture::get_format() const { return format; } -#ifndef DISABLE_DEPRECATED -Error ImageTexture::load(const String &p_path) { - WARN_DEPRECATED; - Ref<Image> img; - img.instance(); - Error err = img->load(p_path); - if (err == OK) { - create_from_image(img); - } - return err; -} -#endif -void ImageTexture::set_data(const Ref<Image> &p_image) { +void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) { ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(texture.is_null()); + ERR_FAIL_COND(p_image->get_width() != w || p_image->get_height() != h); + ERR_FAIL_COND(p_image->get_format() != format); + ERR_FAIL_COND(mipmaps != p_image->has_mipmaps()); - VisualServer::get_singleton()->texture_set_data(texture, p_image); + if (p_immediate) { + VisualServer::get_singleton()->texture_2d_update_immediate(texture, p_image); + } else { + VisualServer::get_singleton()->texture_2d_update(texture, p_image); + } _change_notify(); emit_changed(); @@ -267,7 +219,7 @@ void ImageTexture::_resource_path_changed() { Ref<Image> ImageTexture::get_data() const { if (image_stored) { - return VisualServer::get_singleton()->texture_get_data(texture); + return VisualServer::get_singleton()->texture_2d_get(texture); } else { return Ref<Image>(); } @@ -285,6 +237,10 @@ int ImageTexture::get_height() const { RID ImageTexture::get_rid() const { + if (texture.is_null()) { + //we are in trouble, create something temporary + texture = VisualServer::get_singleton()->texture_2d_placeholder_create(); + } return texture; } @@ -293,26 +249,29 @@ bool ImageTexture::has_alpha() const { return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8); } -void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { +void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat); } bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const { @@ -357,7 +316,7 @@ void ImageTexture::set_size_override(const Size2 &p_size) { w = s.x; if (s.y != 0) h = s.y; - VisualServer::get_singleton()->texture_set_size_override(texture, w, h, 0); + VisualServer::get_singleton()->texture_set_size_override(texture, w, h); } void ImageTexture::set_path(const String &p_path, bool p_take_over) { @@ -369,377 +328,335 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); } -void ImageTexture::set_storage(Storage p_storage) { - - storage = p_storage; -} - -ImageTexture::Storage ImageTexture::get_storage() const { - - return storage; -} - -void ImageTexture::set_lossy_storage_quality(float p_lossy_storage_quality) { - - lossy_storage_quality = p_lossy_storage_quality; -} - -float ImageTexture::get_lossy_storage_quality() const { - - return lossy_storage_quality; -} - -void ImageTexture::_set_data(Dictionary p_data) { - - Ref<Image> img = p_data["image"]; - ERR_FAIL_COND(!img.is_valid()); - uint32_t flags = p_data["flags"]; - - create_from_image(img, flags); - - set_storage(Storage(p_data["storage"].operator int())); - set_lossy_storage_quality(p_data["lossy_quality"]); - - set_size_override(p_data["size"]); -}; - void ImageTexture::_bind_methods() { - ClassDB::bind_method(D_METHOD("create", "width", "height", "format", "flags"), &ImageTexture::create, DEFVAL(FLAGS_DEFAULT)); - ClassDB::bind_method(D_METHOD("create_from_image", "image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT)); + ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image); ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format); -#ifndef DISABLE_DEPRECATED - ClassDB::bind_method(D_METHOD("load", "path"), &ImageTexture::load); -#endif - ClassDB::bind_method(D_METHOD("set_data", "image"), &ImageTexture::set_data); - ClassDB::bind_method(D_METHOD("set_storage", "mode"), &ImageTexture::set_storage); - ClassDB::bind_method(D_METHOD("get_storage"), &ImageTexture::get_storage); - ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &ImageTexture::set_lossy_storage_quality); - ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &ImageTexture::get_lossy_storage_quality); + ClassDB::bind_method(D_METHOD("update", "image", "immediate"), &ImageTexture::update, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override); ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"), "set_storage", "get_storage"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_lossy_storage_quality", "get_lossy_storage_quality"); - - BIND_ENUM_CONSTANT(STORAGE_RAW); - BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY); - BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS); } ImageTexture::ImageTexture() { w = h = 0; - flags = FLAGS_DEFAULT; - texture = VisualServer::get_singleton()->texture_create(); - storage = STORAGE_RAW; - lossy_storage_quality = 0.7; image_stored = false; + mipmaps = false; format = Image::FORMAT_L8; } ImageTexture::~ImageTexture() { - VisualServer::get_singleton()->free(texture); -} - -////////////////////////////////////////// - -void StreamTexture::set_path(const String &p_path, bool p_take_over) { - if (texture.is_valid()) { - VisualServer::get_singleton()->texture_set_path(texture, p_path); + VisualServer::get_singleton()->free(texture); } - - Resource::set_path(p_path, p_take_over); -} - -void StreamTexture::_requested_3d(void *p_ud) { - - StreamTexture *st = (StreamTexture *)p_ud; - Ref<StreamTexture> stex(st); - ERR_FAIL_COND(!request_3d_callback); - request_3d_callback(stex); -} - -void StreamTexture::_requested_srgb(void *p_ud) { - - StreamTexture *st = (StreamTexture *)p_ud; - Ref<StreamTexture> stex(st); - ERR_FAIL_COND(!request_srgb_callback); - request_srgb_callback(stex); -} - -void StreamTexture::_requested_normal(void *p_ud) { - - StreamTexture *st = (StreamTexture *)p_ud; - Ref<StreamTexture> stex(st); - ERR_FAIL_COND(!request_normal_callback); - request_normal_callback(stex); -} - -StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL; -StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL; -StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL; - -uint32_t StreamTexture::get_flags() const { - - return flags; -} -Image::Format StreamTexture::get_format() const { - - return format; } -Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit) { - - alpha_cache.unref(); - - ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); - - FileAccess *f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); - - uint8_t header[4]; - f->get_buffer(header, 4); - if (header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T') { - memdelete(f); - ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); - } - - tw = f->get_16(); - tw_custom = f->get_16(); - th = f->get_16(); - th_custom = f->get_16(); - - flags = f->get_32(); //texture flags! - uint32_t df = f->get_32(); //data format - - /* - print_line("width: " + itos(tw)); - print_line("height: " + itos(th)); - print_line("flags: " + itos(flags)); - print_line("df: " + itos(df)); - */ -#ifdef TOOLS_ENABLED - - if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) { - //print_line("request detect 3D at " + p_path); - VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this); - } else { - //print_line("not requesting detect 3D at " + p_path); - VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL); - } +////////////////////////////////////////// - if (request_srgb_callback && df & FORMAT_BIT_DETECT_SRGB) { - //print_line("request detect srgb at " + p_path); - VS::get_singleton()->texture_set_detect_srgb_callback(texture, _requested_srgb, this); - } else { - //print_line("not requesting detect srgb at " + p_path); - VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL); - } +Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit) { - if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) { - //print_line("request detect srgb at " + p_path); - VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this); - } else { - //print_line("not requesting detect normal at " + p_path); - VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL); - } -#endif - if (!(df & FORMAT_BIT_STREAM)) { - p_size_limit = 0; - } + uint32_t data_format = f->get_32(); + uint32_t w = f->get_16(); + uint32_t h = f->get_16(); + uint32_t mipmaps = f->get_32(); + Image::Format format = Image::Format(f->get_32()); - if (df & FORMAT_BIT_LOSSLESS || df & FORMAT_BIT_LOSSY) { + if (data_format == DATA_FORMAT_LOSSLESS || data_format == DATA_FORMAT_LOSSY || data_format == DATA_FORMAT_BASIS_UNIVERSAL) { //look for a PNG or WEBP file inside - int sw = tw; - int sh = th; - - uint32_t mipmaps = f->get_32(); - uint32_t size = f->get_32(); - - //print_line("mipmaps: " + itos(mipmaps)); - - while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { - - f->seek(f->get_position() + size); - mipmaps = f->get_32(); - size = f->get_32(); - - sw = MAX(sw >> 1, 1); - sh = MAX(sh >> 1, 1); - mipmaps--; - } + int sw = w; + int sh = h; //mipmaps need to be read independently, they will be later combined Vector<Ref<Image> > mipmap_images; int total_size = 0; - for (uint32_t i = 0; i < mipmaps; i++) { + bool first = true; + + for (uint32_t i = 0; i < mipmaps + 1; i++) { - if (i) { - size = f->get_32(); + uint32_t size = f->get_32(); + + if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) { + //can't load this due to size limit + sw = MAX(sw >> 1, 1); + sh = MAX(sh >> 1, 1); + f->seek(f->get_position() + size); + continue; } - PoolVector<uint8_t> pv; + Vector<uint8_t> pv; pv.resize(size); { - PoolVector<uint8_t>::Write w = pv.write(); - f->get_buffer(w.ptr(), size); + uint8_t *wr = pv.ptrw(); + f->get_buffer(wr, size); } Ref<Image> img; - if (df & FORMAT_BIT_LOSSLESS) { + if (data_format == DATA_FORMAT_BASIS_UNIVERSAL) { + img = Image::basis_universal_unpacker(pv); + } else if (data_format == DATA_FORMAT_LOSSLESS) { img = Image::lossless_unpacker(pv); } else { img = Image::lossy_unpacker(pv); } if (img.is_null() || img->empty()) { - memdelete(f); - ERR_FAIL_COND_V(img.is_null() || img->empty(), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(img.is_null() || img->empty(), Ref<Image>()); + } + + if (first) { + //format will actually be the format of the first image, + //as it may have changed on compression + format = img->get_format(); + first = false; + } else if (img->get_format() != format) { + img->convert(format); //all needs to be the same format } total_size += img->get_data().size(); mipmap_images.push_back(img); + + sw = MAX(sw >> 1, 1); + sh = MAX(sh >> 1, 1); } //print_line("mipmap read total: " + itos(mipmap_images.size())); - memdelete(f); //no longer needed + Ref<Image> image; + image.instance(); if (mipmap_images.size() == 1) { - + //only one image (which will most likely be the case anyway for this format) image = mipmap_images[0]; - return OK; + return image; } else { - PoolVector<uint8_t> img_data; + //rarer use case, but needs to be supported + Vector<uint8_t> img_data; img_data.resize(total_size); { - PoolVector<uint8_t>::Write w = img_data.write(); + uint8_t *wr = img_data.ptrw(); int ofs = 0; for (int i = 0; i < mipmap_images.size(); i++) { - PoolVector<uint8_t> id = mipmap_images[i]->get_data(); + Vector<uint8_t> id = mipmap_images[i]->get_data(); int len = id.size(); - PoolVector<uint8_t>::Read r = id.read(); - copymem(&w[ofs], r.ptr(), len); + const uint8_t *r = id.ptr(); + copymem(&wr[ofs], r, len); ofs += len; } } - image->create(sw, sh, true, mipmap_images[0]->get_format(), img_data); - return OK; + image->create(w, h, true, mipmap_images[0]->get_format(), img_data); + return image; } - } else { + } else if (data_format == DATA_FORMAT_IMAGE) { + + int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false); - //look for regular format - Image::Format format = (Image::Format)(df & FORMAT_MASK_IMAGE_FORMAT); - bool mipmaps = df & FORMAT_BIT_HAS_MIPMAPS; + for (uint32_t i = 0; i < mipmaps + 1; i++) { + int tw, th; + int ofs = Image::get_image_mipmap_offset_and_dimensions(w, h, format, i, tw, th); - if (!mipmaps) { - int size = Image::get_image_data_size(tw, th, format, false); + if (p_size_limit > 0 && i < mipmaps && (p_size_limit > tw || p_size_limit > th)) { + if (ofs) { + f->seek(f->get_position() + ofs); + } + continue; //oops, size limit enforced, go to next + } - PoolVector<uint8_t> img_data; - img_data.resize(size); + Vector<uint8_t> data; + data.resize(size - ofs); { - PoolVector<uint8_t>::Write w = img_data.write(); - f->get_buffer(w.ptr(), size); + uint8_t *wr = data.ptrw(); + f->get_buffer(wr, data.size()); } - memdelete(f); + Ref<Image> image; + image.instance(); - image->create(tw, th, false, format, img_data); - return OK; - } else { + image->create(tw, th, mipmaps - i ? true : false, format, data); - int sw = tw; - int sh = th; + return image; + } + } - int mipmaps2 = Image::get_image_required_mipmaps(tw, th, format); - int total_size = Image::get_image_data_size(tw, th, format, true); - int idx = 0; + return Ref<Image>(); +} - while (mipmaps2 > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { +void StreamTexture::set_path(const String &p_path, bool p_take_over) { - sw = MAX(sw >> 1, 1); - sh = MAX(sh >> 1, 1); - mipmaps2--; - idx++; - } + if (texture.is_valid()) { + VisualServer::get_singleton()->texture_set_path(texture, p_path); + } - int ofs = Image::get_image_mipmap_offset(tw, th, format, idx); + Resource::set_path(p_path, p_take_over); +} - if (total_size - ofs <= 0) { - memdelete(f); - ERR_FAIL_V(ERR_FILE_CORRUPT); - } +void StreamTexture::_requested_3d(void *p_ud) { + + StreamTexture *st = (StreamTexture *)p_ud; + Ref<StreamTexture> stex(st); + ERR_FAIL_COND(!request_3d_callback); + request_3d_callback(stex); +} - f->seek(f->get_position() + ofs); +void StreamTexture::_requested_roughness(void *p_ud, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel) { - PoolVector<uint8_t> img_data; - img_data.resize(total_size - ofs); + StreamTexture *st = (StreamTexture *)p_ud; + Ref<StreamTexture> stex(st); + ERR_FAIL_COND(!request_roughness_callback); + request_roughness_callback(stex, p_normal_path, p_roughness_channel); +} - { - PoolVector<uint8_t>::Write w = img_data.write(); - int bytes = f->get_buffer(w.ptr(), total_size - ofs); - //print_line("requested read: " + itos(total_size - ofs) + " but got: " + itos(bytes)); - - memdelete(f); - - int expected = total_size - ofs; - if (bytes < expected) { - //this is a compatibility workaround for older format, which saved less mipmaps2. It is still recommended the image is reimported. - zeromem(w.ptr() + bytes, (expected - bytes)); - } else if (bytes != expected) { - ERR_FAIL_V(ERR_FILE_CORRUPT); - } - } +void StreamTexture::_requested_normal(void *p_ud) { - image->create(sw, sh, true, format, img_data); + StreamTexture *st = (StreamTexture *)p_ud; + Ref<StreamTexture> stex(st); + ERR_FAIL_COND(!request_normal_callback); + request_normal_callback(stex); +} - return OK; - } +StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL; +StreamTexture::TextureFormatRoughnessRequestCallback StreamTexture::request_roughness_callback = NULL; +StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL; + +Image::Format StreamTexture::get_format() const { + + return format; +} + +Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) { + + alpha_cache.unref(); + + ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER); + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + + uint8_t header[4]; + f->get_buffer(header, 4); + if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') { + memdelete(f); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header)."); + } + + uint32_t version = f->get_32(); + + if (version > FORMAT_VERSION) { + memdelete(f); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + } + tw_custom = f->get_32(); + th_custom = f->get_32(); + uint32_t df = f->get_32(); //data format + + //skip reserved + mipmap_limit = int(f->get_32()); + //reserved + f->get_32(); + f->get_32(); + f->get_32(); + +#ifdef TOOLS_ENABLED + + r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D; + r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS; + r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL; + +#else + + r_request_3d = false; + r_request_roughness = false; + r_request_normal = false; + +#endif + if (!(df & FORMAT_BIT_STREAM)) { + p_size_limit = 0; + } + + image = load_image_from_file(f, p_size_limit); + + memdelete(f); + + if (image.is_null() || image->empty()) { + return ERR_CANT_OPEN; } - return ERR_BUG; //unreachable + return OK; } Error StreamTexture::load(const String &p_path) { - int lw, lh, lwc, lhc, lflags; + int lw, lh, lwc, lhc; Ref<Image> image; image.instance(); - Error err = _load_data(p_path, lw, lh, lwc, lhc, lflags, image); + + bool request_3d; + bool request_normal; + bool request_roughness; + int mipmap_limit; + + Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit); if (err) return err; - if (get_path() == String()) { - //temporarily set path if no path set for resource, helps find errors - VisualServer::get_singleton()->texture_set_path(texture, p_path); + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(image); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_create(image); } - VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), 0, image->get_format(), VS::TEXTURE_TYPE_2D, lflags); - VS::get_singleton()->texture_set_data(texture, image); if (lwc || lhc) { - VS::get_singleton()->texture_set_size_override(texture, lwc, lhc, 0); - } else { + VS::get_singleton()->texture_set_size_override(texture, lwc, lhc); } w = lwc ? lwc : lw; h = lhc ? lhc : lh; - flags = lflags; path_to_file = p_path; format = image->get_format(); + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + VisualServer::get_singleton()->texture_set_path(texture, p_path); + } + +#ifdef TOOLS_ENABLED + + if (request_3d) { + //print_line("request detect 3D at " + p_path); + VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this); + } else { + //print_line("not requesting detect 3D at " + p_path); + VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL); + } + + if (request_roughness) { + //print_line("request detect srgb at " + p_path); + VS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this); + } else { + //print_line("not requesting detect srgb at " + p_path); + VS::get_singleton()->texture_set_detect_roughness_callback(texture, NULL, NULL); + } + + if (request_normal) { + //print_line("request detect srgb at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this); + } else { + //print_line("not requesting detect normal at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL); + } + +#endif _change_notify(); emit_changed(); return OK; @@ -759,29 +676,35 @@ int StreamTexture::get_height() const { } RID StreamTexture::get_rid() const { + if (!texture.is_valid()) { + texture = VS::get_singleton()->texture_2d_placeholder_create(); + } return texture; } -void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { +void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { if ((w | h) == 0) return; RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat); } bool StreamTexture::has_alpha() const { @@ -791,7 +714,11 @@ bool StreamTexture::has_alpha() const { Ref<Image> StreamTexture::get_data() const { - return VS::get_singleton()->texture_get_data(texture); + if (texture.is_valid()) { + return VS::get_singleton()->texture_2d_get(texture); + } else { + return Ref<Image>(); + } } bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { @@ -829,12 +756,6 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const { return true; } -void StreamTexture::set_flags(uint32_t p_flags) { - flags = p_flags; - VS::get_singleton()->texture_set_flags(texture, flags); - _change_notify("flags"); - emit_changed(); -} void StreamTexture::reload_from_file() { @@ -851,9 +772,6 @@ void StreamTexture::reload_from_file() { } void StreamTexture::_validate_property(PropertyInfo &property) const { - if (property.name == "flags") { - property.usage = PROPERTY_USAGE_NOEDITOR; - } } void StreamTexture::_bind_methods() { @@ -867,19 +785,18 @@ void StreamTexture::_bind_methods() { StreamTexture::StreamTexture() { format = Image::FORMAT_MAX; - flags = 0; w = 0; h = 0; - - texture = VS::get_singleton()->texture_create(); } StreamTexture::~StreamTexture() { - VS::get_singleton()->free(texture); + if (texture.is_valid()) { + VS::get_singleton()->free(texture); + } } -RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { Ref<StreamTexture> st; st.instance(); @@ -944,21 +861,7 @@ bool AtlasTexture::has_alpha() const { return false; } -void AtlasTexture::set_flags(uint32_t p_flags) { - - if (atlas.is_valid()) - atlas->set_flags(p_flags); -} - -uint32_t AtlasTexture::get_flags() const { - - if (atlas.is_valid()) - return atlas->get_flags(); - - return 0; -} - -void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) { +void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) { ERR_FAIL_COND(p_atlas == this); if (atlas == p_atlas) @@ -967,7 +870,7 @@ void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) { emit_changed(); _change_notify("atlas"); } -Ref<Texture> AtlasTexture::get_atlas() const { +Ref<Texture2D> AtlasTexture::get_atlas() const { return atlas; } @@ -1026,13 +929,13 @@ void AtlasTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip); ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_atlas", "get_atlas"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip"); } -void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if (!atlas.is_valid()) return; @@ -1048,10 +951,11 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m } RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat); } -void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if (!atlas.is_valid()) return; @@ -1070,9 +974,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat); } -void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { +void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { //this might not necessarily work well if using a rect, needs to be fixed properly if (!atlas.is_valid()) @@ -1083,7 +988,8 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons get_rect_region(p_rect, p_src_rect, dr, src_c); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, filter_clip); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -1157,13 +1063,6 @@ bool MeshTexture::has_alpha() const { return false; } -void MeshTexture::set_flags(uint32_t p_flags) { -} - -uint32_t MeshTexture::get_flags() const { - return 0; -} - void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) { mesh = p_mesh; } @@ -1180,15 +1079,15 @@ Size2 MeshTexture::get_image_size() const { return size; } -void MeshTexture::set_base_texture(const Ref<Texture> &p_texture) { +void MeshTexture::set_base_texture(const Ref<Texture2D> &p_texture) { base_texture = p_texture; } -Ref<Texture> MeshTexture::get_base_texture() const { +Ref<Texture2D> MeshTexture::get_base_texture() const { return base_texture; } -void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if (mesh.is_null() || base_texture.is_null()) { return; @@ -1200,9 +1099,10 @@ void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_mo SWAP(xform.elements[0][0], xform.elements[1][1]); } RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { if (mesh.is_null() || base_texture.is_null()) { return; } @@ -1222,9 +1122,10 @@ void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, SWAP(xform.elements[0][0], xform.elements[1][1]); } RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } -void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { +void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { if (mesh.is_null() || base_texture.is_null()) { return; @@ -1245,7 +1146,8 @@ void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const SWAP(xform.elements[0][0], xform.elements[1][1]); } RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid); + RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { r_rect = p_rect; @@ -1266,7 +1168,7 @@ void MeshTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base_texture", "get_base_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base_texture", "get_base_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1"), "set_image_size", "get_image_size"); } @@ -1298,22 +1200,7 @@ bool LargeTexture::has_alpha() const { return false; } -void LargeTexture::set_flags(uint32_t p_flags) { - - for (int i = 0; i < pieces.size(); i++) { - pieces.write[i].texture->set_flags(p_flags); - } -} - -uint32_t LargeTexture::get_flags() const { - - if (pieces.size()) - return pieces[0].texture->get_flags(); - - return 0; -} - -int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture) { +int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND_V(p_texture.is_null(), -1); Piece p; @@ -1330,7 +1217,7 @@ void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) { pieces.write[p_idx].offset = p_offset; }; -void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture> &p_texture) { +void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); ERR_FAIL_COND(p_texture.is_null()); @@ -1378,9 +1265,9 @@ Vector2 LargeTexture::get_piece_offset(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, pieces.size(), Vector2()); return pieces[p_idx].offset; } -Ref<Texture> LargeTexture::get_piece_texture(int p_idx) const { +Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const { - ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture>()); + ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture2D>()); return pieces[p_idx].texture; } Ref<Image> LargeTexture::to_image() const { @@ -1413,16 +1300,16 @@ void LargeTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); } -void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { for (int i = 0; i < pieces.size(); i++) { // TODO - pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map); + pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } } -void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { +void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const { //tiling not supported for this if (size.x == 0 || size.y == 0) @@ -1433,10 +1320,10 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile for (int i = 0; i < pieces.size(); i++) { // TODO - pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map); + pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat); } } -void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { +void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const { //tiling not supported for this if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0) @@ -1455,7 +1342,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons target.size *= scale; target.position = p_rect.position + (p_src_rect.position + rect.position) * scale; local.position -= rect.position; - pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false); + pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat, false); } } @@ -1479,211 +1366,7 @@ bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const { LargeTexture::LargeTexture() { } -/////////////////////////////////////////////// - -void CubeMap::set_flags(uint32_t p_flags) { - - flags = p_flags; - if (_is_valid()) - VS::get_singleton()->texture_set_flags(cubemap, flags); -} - -uint32_t CubeMap::get_flags() const { - - return flags; -} - -void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) { - - ERR_FAIL_COND(p_image.is_null()); - ERR_FAIL_COND(p_image->empty()); - ERR_FAIL_INDEX(p_side, 6); - - if (!_is_valid()) { - format = p_image->get_format(); - w = p_image->get_width(); - h = p_image->get_height(); - VS::get_singleton()->texture_allocate(cubemap, w, h, 0, p_image->get_format(), VS::TEXTURE_TYPE_CUBEMAP, flags); - } - - VS::get_singleton()->texture_set_data(cubemap, p_image, VS::CubeMapSide(p_side)); - valid[p_side] = true; -} - -Ref<Image> CubeMap::get_side(Side p_side) const { - - ERR_FAIL_INDEX_V(p_side, 6, Ref<Image>()); - if (!valid[p_side]) - return Ref<Image>(); - return VS::get_singleton()->texture_get_data(cubemap, VS::CubeMapSide(p_side)); -} - -Image::Format CubeMap::get_format() const { - - return format; -} -int CubeMap::get_width() const { - - return w; -} -int CubeMap::get_height() const { - - return h; -} - -RID CubeMap::get_rid() const { - - return cubemap; -} - -void CubeMap::set_storage(Storage p_storage) { - - storage = p_storage; -} - -CubeMap::Storage CubeMap::get_storage() const { - - return storage; -} - -void CubeMap::set_lossy_storage_quality(float p_lossy_storage_quality) { - - lossy_storage_quality = p_lossy_storage_quality; -} - -float CubeMap::get_lossy_storage_quality() const { - - return lossy_storage_quality; -} - -void CubeMap::set_path(const String &p_path, bool p_take_over) { - - if (cubemap.is_valid()) { - VisualServer::get_singleton()->texture_set_path(cubemap, p_path); - } - - Resource::set_path(p_path, p_take_over); -} - -bool CubeMap::_set(const StringName &p_name, const Variant &p_value) { - - if (p_name == "side/left") { - set_side(SIDE_LEFT, p_value); - } else if (p_name == "side/right") { - set_side(SIDE_RIGHT, p_value); - } else if (p_name == "side/bottom") { - set_side(SIDE_BOTTOM, p_value); - } else if (p_name == "side/top") { - set_side(SIDE_TOP, p_value); - } else if (p_name == "side/front") { - set_side(SIDE_FRONT, p_value); - } else if (p_name == "side/back") { - set_side(SIDE_BACK, p_value); - } else if (p_name == "storage") { - storage = Storage(p_value.operator int()); - } else if (p_name == "lossy_quality") { - lossy_storage_quality = p_value; - } else - return false; - - return true; -} - -bool CubeMap::_get(const StringName &p_name, Variant &r_ret) const { - - if (p_name == "side/left") { - r_ret = get_side(SIDE_LEFT); - } else if (p_name == "side/right") { - r_ret = get_side(SIDE_RIGHT); - } else if (p_name == "side/bottom") { - r_ret = get_side(SIDE_BOTTOM); - } else if (p_name == "side/top") { - r_ret = get_side(SIDE_TOP); - } else if (p_name == "side/front") { - r_ret = get_side(SIDE_FRONT); - } else if (p_name == "side/back") { - r_ret = get_side(SIDE_BACK); - } else if (p_name == "storage") { - r_ret = storage; - } else if (p_name == "lossy_quality") { - r_ret = lossy_storage_quality; - } else - return false; - - return true; -} - -void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const { - - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/top", PROPERTY_HINT_RESOURCE_TYPE, "Image")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/front", PROPERTY_HINT_RESOURCE_TYPE, "Image")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "side/back", PROPERTY_HINT_RESOURCE_TYPE, "Image")); -} - -void CubeMap::_bind_methods() { - - ClassDB::bind_method(D_METHOD("get_width"), &CubeMap::get_width); - ClassDB::bind_method(D_METHOD("get_height"), &CubeMap::get_height); - ClassDB::bind_method(D_METHOD("set_flags", "flags"), &CubeMap::set_flags); - ClassDB::bind_method(D_METHOD("get_flags"), &CubeMap::get_flags); - ClassDB::bind_method(D_METHOD("set_side", "side", "image"), &CubeMap::set_side); - ClassDB::bind_method(D_METHOD("get_side", "side"), &CubeMap::get_side); - ClassDB::bind_method(D_METHOD("set_storage", "mode"), &CubeMap::set_storage); - ClassDB::bind_method(D_METHOD("get_storage"), &CubeMap::get_storage); - ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &CubeMap::set_lossy_storage_quality); - ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &CubeMap::get_lossy_storage_quality); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "storage_mode", PROPERTY_HINT_ENUM, "Raw,Lossy Compressed,Lossless Compressed"), "set_storage", "get_storage"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lossy_storage_quality"), "set_lossy_storage_quality", "get_lossy_storage_quality"); - - BIND_ENUM_CONSTANT(STORAGE_RAW); - BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSY); - BIND_ENUM_CONSTANT(STORAGE_COMPRESS_LOSSLESS); - - BIND_ENUM_CONSTANT(SIDE_LEFT); - BIND_ENUM_CONSTANT(SIDE_RIGHT); - BIND_ENUM_CONSTANT(SIDE_BOTTOM); - BIND_ENUM_CONSTANT(SIDE_TOP); - BIND_ENUM_CONSTANT(SIDE_FRONT); - BIND_ENUM_CONSTANT(SIDE_BACK); - - BIND_ENUM_CONSTANT(FLAG_MIPMAPS); - BIND_ENUM_CONSTANT(FLAG_REPEAT); - BIND_ENUM_CONSTANT(FLAG_FILTER); - BIND_ENUM_CONSTANT(FLAGS_DEFAULT); -} - -CubeMap::CubeMap() { - - w = h = 0; - flags = FLAGS_DEFAULT; - for (int i = 0; i < 6; i++) - valid[i] = false; - cubemap = VisualServer::get_singleton()->texture_create(); - storage = STORAGE_RAW; - lossy_storage_quality = 0.7; - format = Image::FORMAT_BPTC_RGBA; -} - -CubeMap::~CubeMap() { - - VisualServer::get_singleton()->free(cubemap); -} - -/* BIND_ENUM(CubeMapSize); - BIND_ENUM_CONSTANT( FLAG_CUBEMAP ); - BIND_ENUM_CONSTANT( CUBEMAP_LEFT ); - BIND_ENUM_CONSTANT( CUBEMAP_RIGHT ); - BIND_ENUM_CONSTANT( CUBEMAP_BOTTOM ); - BIND_ENUM_CONSTANT( CUBEMAP_TOP ); - BIND_ENUM_CONSTANT( CUBEMAP_FRONT ); - BIND_ENUM_CONSTANT( CUBEMAP_BACK ); -*/ -/////////////////////////// +/////////////////// void CurveTexture::_bind_methods() { @@ -1725,11 +1408,11 @@ void CurveTexture::ensure_default_setup(float p_min, float p_max) { void CurveTexture::set_curve(Ref<Curve> p_curve) { if (_curve != p_curve) { if (_curve.is_valid()) { - _curve->disconnect(CoreStringNames::get_singleton()->changed, this, "_update"); + _curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update)); } _curve = p_curve; if (_curve.is_valid()) { - _curve->connect(CoreStringNames::get_singleton()->changed, this, "_update"); + _curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update)); } _update(); } @@ -1737,13 +1420,13 @@ void CurveTexture::set_curve(Ref<Curve> p_curve) { void CurveTexture::_update() { - PoolVector<uint8_t> data; + Vector<uint8_t> data; data.resize(_width * sizeof(float)); // The array is locked in that scope { - PoolVector<uint8_t>::Write wd8 = data.write(); - float *wd = (float *)wd8.ptr(); + uint8_t *wd8 = data.ptrw(); + float *wd = (float *)wd8; if (_curve.is_valid()) { Curve &curve = **_curve; @@ -1761,8 +1444,12 @@ void CurveTexture::_update() { Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RF, data)); - VS::get_singleton()->texture_allocate(_texture, _width, 1, 0, Image::FORMAT_RF, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER); - VS::get_singleton()->texture_set_data(_texture, image); + if (_texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(image); + VS::get_singleton()->texture_replace(_texture, new_texture); + } else { + _texture = VS::get_singleton()->texture_2d_create(image); + } emit_changed(); } @@ -1774,15 +1461,19 @@ Ref<Curve> CurveTexture::get_curve() const { RID CurveTexture::get_rid() const { + if (!_texture.is_valid()) { + _texture = VS::get_singleton()->texture_2d_placeholder_create(); + } return _texture; } CurveTexture::CurveTexture() { _width = 2048; - _texture = VS::get_singleton()->texture_create(); } CurveTexture::~CurveTexture() { - VS::get_singleton()->free(_texture); + if (_texture.is_valid()) { + VS::get_singleton()->free(_texture); + } } ////////////////// @@ -1796,12 +1487,13 @@ GradientTexture::GradientTexture() { update_pending = false; width = 2048; - texture = VS::get_singleton()->texture_create(); _queue_update(); } GradientTexture::~GradientTexture() { - VS::get_singleton()->free(texture); + if (texture.is_valid()) { + VS::get_singleton()->free(texture); + } } void GradientTexture::_bind_methods() { @@ -1821,11 +1513,11 @@ void GradientTexture::set_gradient(Ref<Gradient> p_gradient) { if (p_gradient == gradient) return; if (gradient.is_valid()) { - gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_update"); + gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture::_update)); } gradient = p_gradient; if (gradient.is_valid()) { - gradient->connect(CoreStringNames::get_singleton()->changed, this, "_update"); + gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture::_update)); } _update(); emit_changed(); @@ -1851,10 +1543,10 @@ void GradientTexture::_update() { if (gradient.is_null()) return; - PoolVector<uint8_t> data; + Vector<uint8_t> data; data.resize(width * 4); { - PoolVector<uint8_t>::Write wd8 = data.write(); + uint8_t *wd8 = data.ptrw(); Gradient &g = **gradient; for (int i = 0; i < width; i++) { @@ -1871,8 +1563,12 @@ void GradientTexture::_update() { Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data)); - VS::get_singleton()->texture_allocate(texture, width, 1, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER); - VS::get_singleton()->texture_set_data(texture, image); + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(image); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_create(image); + } emit_changed(); } @@ -1888,7 +1584,10 @@ int GradientTexture::get_width() const { } Ref<Image> GradientTexture::get_data() const { - return VisualServer::get_singleton()->texture_get_data(texture); + if (!texture.is_valid()) { + return Ref<Image>(); + } + return VisualServer::get_singleton()->texture_2d_get(texture); } ////////////////////////////////////// @@ -1898,21 +1597,28 @@ void ProxyTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base); ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base", "get_base"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base", "get_base"); } -void ProxyTexture::set_base(const Ref<Texture> &p_texture) { +void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); + base = p_texture; if (base.is_valid()) { - VS::get_singleton()->texture_set_proxy(proxy, base->get_rid()); - } else { - VS::get_singleton()->texture_set_proxy(proxy, RID()); + if (proxy_ph.is_valid()) { + VS::get_singleton()->texture_proxy_update(proxy, base->get_rid()); + VS::get_singleton()->free(proxy_ph); + proxy_ph = RID(); + } else if (proxy.is_valid()) { + VS::get_singleton()->texture_proxy_update(proxy, base->get_rid()); + } else { + proxy = VS::get_singleton()->texture_proxy_create(base->get_rid()); + } } } -Ref<Texture> ProxyTexture::get_base() const { +Ref<Texture2D> ProxyTexture::get_base() const { return base; } @@ -1931,6 +1637,10 @@ int ProxyTexture::get_height() const { } RID ProxyTexture::get_rid() const { + if (proxy.is_null()) { + proxy_ph = VS::get_singleton()->texture_2d_placeholder_create(); + proxy = VS::get_singleton()->texture_proxy_create(proxy_ph); + } return proxy; } @@ -1941,24 +1651,19 @@ bool ProxyTexture::has_alpha() const { return false; } -void ProxyTexture::set_flags(uint32_t p_flags) { -} - -uint32_t ProxyTexture::get_flags() const { - - if (base.is_valid()) - return base->get_flags(); - return 0; -} - ProxyTexture::ProxyTexture() { - proxy = VS::get_singleton()->texture_create(); + //proxy = VS::get_singleton()->texture_create(); } ProxyTexture::~ProxyTexture() { - VS::get_singleton()->free(proxy); + if (proxy_ph.is_valid()) { + VS::get_singleton()->free(proxy_ph); + } + if (proxy.is_valid()) { + VS::get_singleton()->free(proxy); + } } ////////////////////////////////////////////// @@ -2003,7 +1708,7 @@ void AnimatedTexture::_update_proxy() { } if (frames[current_frame].texture.is_valid()) { - VisualServer::get_singleton()->texture_set_proxy(proxy, frames[current_frame].texture->get_rid()); + VisualServer::get_singleton()->texture_proxy_update(proxy, frames[current_frame].texture->get_rid()); } } @@ -2018,7 +1723,7 @@ int AnimatedTexture::get_frames() const { return frame_count; } -void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) { +void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(p_texture == this); ERR_FAIL_INDEX(p_frame, MAX_FRAMES); @@ -2027,8 +1732,8 @@ void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_textu frames[p_frame].texture = p_texture; } -Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const { - ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>()); +Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const { + ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>()); RWLockRead r(rw_lock); @@ -2113,19 +1818,6 @@ bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const { return true; } -void AnimatedTexture::set_flags(uint32_t p_flags) { -} -uint32_t AnimatedTexture::get_flags() const { - - RWLockRead r(rw_lock); - - if (!frames[current_frame].texture.is_valid()) { - return 0; - } - - return frames[current_frame].texture->get_flags(); -} - void AnimatedTexture::_validate_property(PropertyInfo &property) const { String prop = property.name; @@ -2150,28 +1842,29 @@ void AnimatedTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay); ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay); - ClassDB::bind_method(D_METHOD("_update_proxy"), &AnimatedTexture::_update_proxy); - ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); for (int i = 0; i < MAX_FRAMES; i++) { - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); } BIND_CONSTANT(MAX_FRAMES); } AnimatedTexture::AnimatedTexture() { - proxy = VS::get_singleton()->texture_create(); + //proxy = VS::get_singleton()->texture_create(); + proxy_ph = VS::get_singleton()->texture_2d_placeholder_create(); + proxy = VS::get_singleton()->texture_proxy_create(proxy_ph); + VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true); time = 0; frame_count = 1; fps = 4; prev_ticks = 0; current_frame = 0; - VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy"); + VisualServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy)); #ifndef NO_THREADS rw_lock = RWLock::create(); @@ -2182,24 +1875,13 @@ AnimatedTexture::AnimatedTexture() { AnimatedTexture::~AnimatedTexture() { VS::get_singleton()->free(proxy); + VS::get_singleton()->free(proxy_ph); if (rw_lock) { memdelete(rw_lock); } } /////////////////////////////// -void TextureLayered::set_flags(uint32_t p_flags) { - flags = p_flags; - - if (texture.is_valid()) { - VS::get_singleton()->texture_set_flags(texture, flags); - } -} - -uint32_t TextureLayered::get_flags() const { - return flags; -} - Image::Format TextureLayered::get_format() const { return format; } @@ -2212,82 +1894,93 @@ uint32_t TextureLayered::get_height() const { return height; } -uint32_t TextureLayered::get_depth() const { - return depth; +uint32_t TextureLayered::get_layers() const { + return layers; } -void TextureLayered::_set_data(const Dictionary &p_data) { - ERR_FAIL_COND(!p_data.has("width")); - ERR_FAIL_COND(!p_data.has("height")); - ERR_FAIL_COND(!p_data.has("depth")); - ERR_FAIL_COND(!p_data.has("format")); - ERR_FAIL_COND(!p_data.has("flags")); - ERR_FAIL_COND(!p_data.has("layers")); - int w = p_data["width"]; - int h = p_data["height"]; - int d = p_data["depth"]; - Image::Format format = Image::Format(int(p_data["format"])); - int flags = p_data["flags"]; - Array layers = p_data["layers"]; - ERR_FAIL_COND(layers.size() != d); +Error TextureLayered::_create_from_images(const Array &p_images) { + Vector<Ref<Image> > images; + for (int i = 0; i < p_images.size(); i++) { + Ref<Image> img = p_images[i]; + ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER); + images.push_back(img); + } - create(w, h, d, format, flags); + return create_from_images(images); +} - for (int i = 0; i < layers.size(); i++) { - Ref<Image> img = layers[i]; - ERR_CONTINUE(!img.is_valid()); - ERR_CONTINUE(img->get_format() != format); - ERR_CONTINUE(img->get_width() != w); - ERR_CONTINUE(img->get_height() != h); - set_layer_data(img, i); +Array TextureLayered::_get_images() const { + Array images; + for (int i = 0; i < layers; i++) { + images.push_back(get_layer_data(i)); } + return images; } -Dictionary TextureLayered::_get_data() const { - Dictionary d; - d["width"] = width; - d["height"] = height; - d["depth"] = depth; - d["flags"] = flags; - d["format"] = format; +Error TextureLayered::create_from_images(Vector<Ref<Image> > p_images) { - Array layers; - for (int i = 0; i < depth; i++) { - layers.push_back(get_layer_data(i)); + int new_layers = p_images.size(); + ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER); + if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP) { + ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER, + "Cubemaps require exactly 6 layers"); + } else if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) { + ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER, + "Cubemap array layers must be a multiple of 6"); } - d["layers"] = layers; - return d; -} -void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags) { - VS::get_singleton()->texture_allocate(texture, p_width, p_height, p_depth, p_format, is_3d ? VS::TEXTURE_TYPE_3D : VS::TEXTURE_TYPE_2D_ARRAY, p_flags); + ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->empty(), ERR_INVALID_PARAMETER); - width = p_width; - height = p_height; - depth = p_depth; - format = p_format; - flags = p_flags; -} + Image::Format new_format = p_images[0]->get_format(); + int new_width = p_images[0]->get_width(); + int new_height = p_images[0]->get_height(); + bool new_mipmaps = p_images[0]->has_mipmaps(); -void TextureLayered::set_layer_data(const Ref<Image> &p_image, int p_layer) { - ERR_FAIL_COND(!texture.is_valid()); - ERR_FAIL_COND(!p_image.is_valid()); - VS::get_singleton()->texture_set_data(texture, p_image, p_layer); -} + for (int i = 1; i < p_images.size(); i++) { + ERR_FAIL_COND_V_MSG(p_images[i]->get_format() != new_format, ERR_INVALID_PARAMETER, + "All images must share the same format"); + ERR_FAIL_COND_V_MSG(p_images[i]->get_width() != new_width || p_images[i]->get_height() != new_height, ERR_INVALID_PARAMETER, + "All images must share the same dimensions"); + ERR_FAIL_COND_V_MSG(p_images[i]->has_mipmaps() != new_mipmaps, ERR_INVALID_PARAMETER, + "All images must share the usage of mipmaps"); + } -Ref<Image> TextureLayered::get_layer_data(int p_layer) const { + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type); + ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type); + ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE); + } + + format = new_format; + width = new_width; + height = new_height; + layers = new_layers; + mipmaps = new_mipmaps; + return OK; +} - ERR_FAIL_COND_V(!texture.is_valid(), Ref<Image>()); - return VS::get_singleton()->texture_get_data(texture, p_layer); +void TextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) { + ERR_FAIL_COND(texture.is_valid()); + ERR_FAIL_COND(p_image.is_null()); + ERR_FAIL_COND(p_image->get_format() != format); + ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height); + ERR_FAIL_INDEX(p_layer, layers); + ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps); + VS::get_singleton()->texture_2d_update(texture, p_image, p_layer); } -void TextureLayered::set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap) { - ERR_FAIL_COND(!texture.is_valid()); - ERR_FAIL_COND(!p_image.is_valid()); - VS::get_singleton()->texture_set_data_partial(texture, p_image, 0, 0, p_image->get_width(), p_image->get_height(), p_x_ofs, p_y_ofs, p_mipmap, p_z); +Ref<Image> TextureLayered::get_layer_data(int p_layer) const { + ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>()); + return VS::get_singleton()->texture_2d_layer_get(texture, p_layer); } RID TextureLayered::get_rid() const { + if (texture.is_null()) { + texture = VS::get_singleton()->texture_2d_layered_placeholder_create(); + } return texture; } @@ -2300,42 +1993,29 @@ void TextureLayered::set_path(const String &p_path, bool p_take_over) { } void TextureLayered::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextureLayered::set_flags); - ClassDB::bind_method(D_METHOD("get_flags"), &TextureLayered::get_flags); ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format); ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width); ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height); - ClassDB::bind_method(D_METHOD("get_depth"), &TextureLayered::get_depth); + ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers); - ClassDB::bind_method(D_METHOD("create", "width", "height", "depth", "format", "flags"), &TextureLayered::create, DEFVAL(FLAGS_DEFAULT)); - ClassDB::bind_method(D_METHOD("set_layer_data", "image", "layer"), &TextureLayered::set_layer_data); + ClassDB::bind_method(D_METHOD("create_from_images", "images"), &TextureLayered::_create_from_images); + ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &TextureLayered::update_layer); ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data); - ClassDB::bind_method(D_METHOD("set_data_partial", "image", "x_offset", "y_offset", "layer", "mipmap"), &TextureLayered::set_data_partial, DEFVAL(0)); - ClassDB::bind_method(D_METHOD("_set_data", "data"), &TextureLayered::_set_data); - ClassDB::bind_method(D_METHOD("_get_data"), &TextureLayered::_get_data); + ClassDB::bind_method(D_METHOD("_get_images"), &TextureLayered::_get_images); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"), "set_flags", "get_flags"); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data"); - - BIND_ENUM_CONSTANT(FLAG_MIPMAPS); - BIND_ENUM_CONSTANT(FLAG_REPEAT); - BIND_ENUM_CONSTANT(FLAG_FILTER); - BIND_ENUM_CONSTANT(FLAGS_DEFAULT); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images"); } -TextureLayered::TextureLayered(bool p_3d) { - is_3d = p_3d; +TextureLayered::TextureLayered(VisualServer::TextureLayeredType p_layered_type) { + layered_type = p_layered_type; format = Image::FORMAT_MAX; - flags = FLAGS_DEFAULT; width = 0; height = 0; - depth = 0; - - texture = VS::get_singleton()->texture_create(); + layers = 0; } TextureLayered::~TextureLayered() { @@ -2344,22 +2024,26 @@ TextureLayered::~TextureLayered() { } } -RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) { *r_error = ERR_CANT_OPEN; } Ref<TextureLayered> lt; - Ref<Texture3D> tex3d; - Ref<TextureArray> texarr; - - if (p_path.ends_with("tex3d")) { - tex3d.instance(); - lt = tex3d; - } else if (p_path.ends_with("texarr")) { - texarr.instance(); - lt = texarr; + + if (p_path.ends_with("cube")) { + Ref<Cubemap> cube; + cube.instance(); + lt = cube; + } else if (p_path.ends_with("cubearr")) { + Ref<CubemapArray> cubearr; + cubearr.instance(); + lt = cubearr; + } else if (p_path.ends_with("tex2darr")) { + Ref<Texture2DArray> t2darr; + t2darr.instance(); + lt = t2darr; } else { ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension."); } @@ -2367,21 +2051,18 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'."); - uint8_t header[5] = { 0, 0, 0, 0, 0 }; - f->get_buffer(header, 4); + char header[5] = { 0, 0, 0, 0, 0 }; + f->get_buffer((uint8_t *)header, 4); - if (header[0] == 'G' && header[1] == 'D' && header[2] == '3' && header[3] == 'T') { - if (tex3d.is_null()) { - f->close(); - memdelete(f); - ERR_FAIL_COND_V(tex3d.is_null(), RES()); - } - } else if (header[0] == 'G' && header[1] == 'D' && header[2] == 'A' && header[3] == 'T') { - if (texarr.is_null()) { - f->close(); - memdelete(f); - ERR_FAIL_COND_V(texarr.is_null(), RES()); + if (String(header) != "GDLT") { + f->close(); + memdelete(f); + if (r_error) { + *r_error = ERR_FILE_CORRUPT; } + // FIXME: It's bogus that we fail in both branches. Seen while rebasing + // vulkan branch on master branch. + ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture."); } else { f->close(); @@ -2392,12 +2073,11 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String int tw = f->get_32(); int th = f->get_32(); int td = f->get_32(); - int flags = f->get_32(); //texture flags! + bool use_mipmaps = f->get_32() != 0; //texture flags (deprecated) Image::Format format = Image::Format(f->get_32()); uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed - lt->create(tw, th, td, format, flags); - + Vector<Ref<Image> > images; for (int layer = 0; layer < td; layer++) { Ref<Image> image; @@ -2412,11 +2092,11 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String for (int i = 0; i < mipmaps; i++) { uint32_t size = f->get_32(); - PoolVector<uint8_t> pv; + Vector<uint8_t> pv; pv.resize(size); { - PoolVector<uint8_t>::Write w = pv.write(); - f->get_buffer(w.ptr(), size); + uint8_t *w = pv.ptrw(); + f->get_buffer(w, size); } Ref<Image> img = Image::lossless_unpacker(pv); @@ -2439,19 +2119,19 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String } else { int total_size = Image::get_image_data_size(tw, th, format, true); - PoolVector<uint8_t> img_data; + Vector<uint8_t> img_data; img_data.resize(total_size); { - PoolVector<uint8_t>::Write w = img_data.write(); + uint8_t *w = img_data.ptrw(); int ofs = 0; for (int i = 0; i < mipmap_images.size(); i++) { - PoolVector<uint8_t> id = mipmap_images[i]->get_data(); + Vector<uint8_t> id = mipmap_images[i]->get_data(); int len = id.size(); - PoolVector<uint8_t>::Read r = id.read(); - copymem(&w[ofs], r.ptr(), len); + const uint8_t *r = id.ptr(); + copymem(&w[ofs], r, len); ofs += len; } } @@ -2470,15 +2150,15 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String } else { //look for regular format - bool mipmaps = (flags & Texture::FLAG_MIPMAPS); - int total_size = Image::get_image_data_size(tw, th, format, mipmaps); - PoolVector<uint8_t> img_data; + int total_size = Image::get_image_data_size(tw, th, format, use_mipmaps); + + Vector<uint8_t> img_data; img_data.resize(total_size); { - PoolVector<uint8_t>::Write w = img_data.write(); - int bytes = f->get_buffer(w.ptr(), total_size); + uint8_t *w = img_data.ptrw(); + int bytes = f->get_buffer(w, total_size); if (bytes != total_size) { if (r_error) { *r_error = ERR_FILE_CORRUPT; @@ -2489,35 +2169,47 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String } } - image->create(tw, th, mipmaps, format, img_data); + image->create(tw, th, use_mipmaps, format, img_data); } - lt->set_layer_data(image, layer); + images.push_back(image); } - if (r_error) - *r_error = OK; + Error err = lt->create_from_images(images); + if (err != OK) { + *r_error = err; + return RES(); + } else { + + if (r_error) + *r_error = OK; + } return lt; } void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const { - p_extensions->push_back("tex3d"); - p_extensions->push_back("texarr"); + p_extensions->push_back("cube"); + p_extensions->push_back("cubearr"); + p_extensions->push_back("tex2darr"); } bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const { - return p_type == "Texture3D" || p_type == "TextureArray"; + return p_type == "Texture2DArray" || p_type == "Cubemap" || p_type == "CubemapArray"; } String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const { - if (p_path.get_extension().to_lower() == "tex3d") - return "Texture3D"; - if (p_path.get_extension().to_lower() == "texarr") - return "TextureArray"; + if (p_path.get_extension().to_lower() == "cube") + return "Cubemap"; + if (p_path.get_extension().to_lower() == "cubearr") + return "CubemapArray"; + if (p_path.get_extension().to_lower() == "tex2darr") + return "Texture2DArray"; return ""; } +/////////////////////////////// + void CameraTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id); ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index fa698d387b..237c02a8cd 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -33,6 +33,7 @@ #include "core/io/resource_loader.h" #include "core/math/rect2.h" +#include "core/os/file_access.h" #include "core/os/mutex.h" #include "core/os/rw_lock.h" #include "core/os/thread_safe.h" @@ -43,25 +44,21 @@ #include "servers/visual_server.h" class Texture : public Resource { - GDCLASS(Texture, Resource); - OBJ_SAVE_TYPE(Texture); // Saves derived classes with common type so they can be interchanged. + +public: + Texture() {} +}; + +class Texture2D : public Texture { + + GDCLASS(Texture2D, Texture); + OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged. protected: static void _bind_methods(); public: - enum Flags { - FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS, - FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT, - FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER, - FLAG_ANISOTROPIC_FILTER = VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER, - FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR, - FLAG_VIDEO_SURFACE = VisualServer::TEXTURE_FLAG_USED_FOR_STREAMING, - FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER, - FLAG_MIRRORED_REPEAT = VisualServer::TEXTURE_FLAG_MIRRORED_REPEAT - }; - virtual int get_width() const = 0; virtual int get_height() const = 0; virtual Size2 get_size() const; @@ -71,43 +68,28 @@ public: virtual bool has_alpha() const = 0; - virtual void set_flags(uint32_t p_flags) = 0; - virtual uint32_t get_flags() const = 0; - - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; virtual Ref<Image> get_data() const { return Ref<Image>(); } - Texture(); + Texture2D(); }; -VARIANT_ENUM_CAST(Texture::Flags); - class BitMap; -class ImageTexture : public Texture { +class ImageTexture : public Texture2D { - GDCLASS(ImageTexture, Texture); + GDCLASS(ImageTexture, Texture2D); RES_BASE_EXTENSION("tex"); -public: - enum Storage { - STORAGE_RAW, - STORAGE_COMPRESS_LOSSY, - STORAGE_COMPRESS_LOSSLESS - }; - -private: - RID texture; + mutable RID texture; Image::Format format; - uint32_t flags; + bool mipmaps; int w, h; - Storage storage; Size2 size_override; - float lossy_storage_quality; mutable Ref<BitMap> alpha_cache; bool image_stored; @@ -122,19 +104,12 @@ protected: virtual void _resource_path_changed(); static void _bind_methods(); - void _set_data(Dictionary p_data); - public: - void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); - void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT); + void create_from_image(const Ref<Image> &p_image); - void set_flags(uint32_t p_flags); - uint32_t get_flags() const; Image::Format get_format() const; -#ifndef DISABLE_DEPRECATED - Error load(const String &p_path); -#endif - void set_data(const Ref<Image> &p_image); + + void update(const Ref<Image> &p_image, bool p_immediate = false); Ref<Image> get_data() const; int get_width() const; @@ -143,17 +118,12 @@ public: virtual RID get_rid() const; bool has_alpha() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; - void set_storage(Storage p_storage); - Storage get_storage() const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; bool is_pixel_opaque(int p_x, int p_y) const; - void set_lossy_storage_quality(float p_lossy_storage_quality); - float get_lossy_storage_quality() const; - void set_size_override(const Size2 &p_size); virtual void set_path(const String &p_path, bool p_take_over = false); @@ -162,15 +132,20 @@ public: ~ImageTexture(); }; -class StreamTexture : public Texture { +class StreamTexture : public Texture2D { - GDCLASS(StreamTexture, Texture); + GDCLASS(StreamTexture, Texture2D); public: enum DataFormat { DATA_FORMAT_IMAGE, DATA_FORMAT_LOSSLESS, - DATA_FORMAT_LOSSY + DATA_FORMAT_LOSSY, + DATA_FORMAT_BASIS_UNIVERSAL, + }; + + enum { + FORMAT_VERSION = 1 }; enum FormatBits { @@ -180,23 +155,23 @@ public: FORMAT_BIT_STREAM = 1 << 22, FORMAT_BIT_HAS_MIPMAPS = 1 << 23, FORMAT_BIT_DETECT_3D = 1 << 24, - FORMAT_BIT_DETECT_SRGB = 1 << 25, + //FORMAT_BIT_DETECT_SRGB = 1 << 25, FORMAT_BIT_DETECT_NORMAL = 1 << 26, + FORMAT_BIT_DETECT_ROUGNESS = 1 << 27, }; private: - Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, int &flags, Ref<Image> &image, int p_size_limit = 0); + Error _load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit = 0); String path_to_file; - RID texture; + mutable RID texture; Image::Format format; - uint32_t flags; int w, h; mutable Ref<BitMap> alpha_cache; virtual void reload_from_file(); static void _requested_3d(void *p_ud); - static void _requested_srgb(void *p_ud); + static void _requested_roughness(void *p_ud, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel); static void _requested_normal(void *p_ud); protected: @@ -204,13 +179,15 @@ protected: void _validate_property(PropertyInfo &property) const; public: + static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit); + typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture> &); + typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture> &, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel); static TextureFormatRequestCallback request_3d_callback; - static TextureFormatRequestCallback request_srgb_callback; + static TextureFormatRoughnessRequestCallback request_roughness_callback; static TextureFormatRequestCallback request_normal_callback; - uint32_t get_flags() const; Image::Format get_format() const; Error load(const String &p_path); String get_load_path() const; @@ -221,12 +198,11 @@ public: virtual void set_path(const String &p_path, bool p_take_over); - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); bool is_pixel_opaque(int p_x, int p_y) const; virtual Ref<Image> get_data() const; @@ -237,21 +213,19 @@ public: class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; }; -VARIANT_ENUM_CAST(ImageTexture::Storage); - -class AtlasTexture : public Texture { +class AtlasTexture : public Texture2D { - GDCLASS(AtlasTexture, Texture); + GDCLASS(AtlasTexture, Texture2D); RES_BASE_EXTENSION("atlastex"); protected: - Ref<Texture> atlas; + Ref<Texture2D> atlas; Rect2 region; Rect2 margin; bool filter_clip; @@ -265,11 +239,8 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - - void set_atlas(const Ref<Texture> &p_atlas); - Ref<Texture> get_atlas() const; + void set_atlas(const Ref<Texture2D> &p_atlas); + Ref<Texture2D> get_atlas() const; void set_region(const Rect2 &p_region); Rect2 get_region() const; @@ -280,9 +251,9 @@ public: void set_filter_clip(const bool p_enable); bool has_filter_clip() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; bool is_pixel_opaque(int p_x, int p_y) const; @@ -292,12 +263,12 @@ public: class Mesh; -class MeshTexture : public Texture { +class MeshTexture : public Texture2D { - GDCLASS(MeshTexture, Texture); + GDCLASS(MeshTexture, Texture2D); RES_BASE_EXTENSION("meshtex"); - Ref<Texture> base_texture; + Ref<Texture2D> base_texture; Ref<Mesh> mesh; Size2i size; @@ -311,21 +282,18 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; void set_image_size(const Size2 &p_size); Size2 get_image_size() const; - void set_base_texture(const Ref<Texture> &p_texture); - Ref<Texture> get_base_texture() const; + void set_base_texture(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_base_texture() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; bool is_pixel_opaque(int p_x, int p_y) const; @@ -333,16 +301,16 @@ public: MeshTexture(); }; -class LargeTexture : public Texture { +class LargeTexture : public Texture2D { - GDCLASS(LargeTexture, Texture); + GDCLASS(LargeTexture, Texture2D); RES_BASE_EXTENSION("largetex"); protected: struct Piece { Point2 offset; - Ref<Texture> texture; + Ref<Texture2D> texture; }; Vector<Piece> pieces; @@ -359,179 +327,90 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - - int add_piece(const Point2 &p_offset, const Ref<Texture> &p_texture); + int add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture); void set_piece_offset(int p_idx, const Point2 &p_offset); - void set_piece_texture(int p_idx, const Ref<Texture> &p_texture); + void set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture); void set_size(const Size2 &p_size); void clear(); int get_piece_count() const; Vector2 get_piece_offset(int p_idx) const; - Ref<Texture> get_piece_texture(int p_idx) const; + Ref<Texture2D> get_piece_texture(int p_idx) const; Ref<Image> to_image() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture2D> &p_normal_map = Ref<Texture2D>(), const Ref<Texture2D> &p_specular_map = Ref<Texture2D>(), const Color &p_specular_color_shininess = Color(1, 1, 1, 1), VS::CanvasItemTextureFilter p_texture_filter = VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, VS::CanvasItemTextureRepeat p_texture_repeat = VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, bool p_clip_uv = true) const; bool is_pixel_opaque(int p_x, int p_y) const; LargeTexture(); }; -class CubeMap : public Resource { +class TextureLayered : public Texture { - GDCLASS(CubeMap, Resource); - RES_BASE_EXTENSION("cubemap"); + GDCLASS(TextureLayered, Texture); -public: - enum Storage { - STORAGE_RAW, - STORAGE_COMPRESS_LOSSY, - STORAGE_COMPRESS_LOSSLESS - }; - - enum Side { + VS::TextureLayeredType layered_type; - SIDE_LEFT, - SIDE_RIGHT, - SIDE_BOTTOM, - SIDE_TOP, - SIDE_FRONT, - SIDE_BACK - }; - - enum Flags { - FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS, - FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT, - FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER, - FLAGS_DEFAULT = FLAG_MIPMAPS | FLAG_REPEAT | FLAG_FILTER, - }; - -private: - bool valid[6]; - RID cubemap; + mutable RID texture; Image::Format format; - uint32_t flags; - int w, h; - Storage storage; - Size2 size_override; - float lossy_storage_quality; - - _FORCE_INLINE_ bool _is_valid() const { - for (int i = 0; i < 6; i++) { - if (valid[i]) return true; - } - return false; - } - -protected: - 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; - - static void _bind_methods(); - -public: - void set_flags(uint32_t p_flags); - uint32_t get_flags() const; - void set_side(Side p_side, const Ref<Image> &p_image); - Ref<Image> get_side(Side p_side) const; - - Image::Format get_format() const; - int get_width() const; - int get_height() const; - - virtual RID get_rid() const; - - void set_storage(Storage p_storage); - Storage get_storage() const; - - void set_lossy_storage_quality(float p_lossy_storage_quality); - float get_lossy_storage_quality() const; - - virtual void set_path(const String &p_path, bool p_take_over = false); - - CubeMap(); - ~CubeMap(); -}; - -VARIANT_ENUM_CAST(CubeMap::Flags) -VARIANT_ENUM_CAST(CubeMap::Side) -VARIANT_ENUM_CAST(CubeMap::Storage) - -class TextureLayered : public Resource { - - GDCLASS(TextureLayered, Resource); - -public: - enum Flags { - FLAG_MIPMAPS = VisualServer::TEXTURE_FLAG_MIPMAPS, - FLAG_REPEAT = VisualServer::TEXTURE_FLAG_REPEAT, - FLAG_FILTER = VisualServer::TEXTURE_FLAG_FILTER, - FLAG_CONVERT_TO_LINEAR = VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR, - FLAGS_DEFAULT = FLAG_FILTER, - }; - -private: - bool is_3d; - RID texture; - Image::Format format; - uint32_t flags; int width; int height; - int depth; + int layers; + bool mipmaps; - void _set_data(const Dictionary &p_data); - Dictionary _get_data() const; + Error _create_from_images(const Array &p_images); + + Array _get_images() const; protected: static void _bind_methods(); public: - void set_flags(uint32_t p_flags); - uint32_t get_flags() const; - Image::Format get_format() const; uint32_t get_width() const; uint32_t get_height() const; - uint32_t get_depth() const; + uint32_t get_layers() const; + bool has_mipmaps() const; - void create(uint32_t p_width, uint32_t p_height, uint32_t p_depth, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); - void set_layer_data(const Ref<Image> &p_image, int p_layer); + Error create_from_images(Vector<Ref<Image> > p_images); + void update_layer(const Ref<Image> &p_image, int p_layer); Ref<Image> get_layer_data(int p_layer) const; - void set_data_partial(const Ref<Image> &p_image, int p_x_ofs, int p_y_ofs, int p_z, int p_mipmap = 0); virtual RID get_rid() const; virtual void set_path(const String &p_path, bool p_take_over = false); - TextureLayered(bool p_3d = false); + TextureLayered(VS::TextureLayeredType p_layered_type); ~TextureLayered(); }; -VARIANT_ENUM_CAST(TextureLayered::Flags) +class Texture2DArray : public TextureLayered { -class Texture3D : public TextureLayered { + GDCLASS(Texture2DArray, TextureLayered) +public: + Texture2DArray() : + TextureLayered(VS::TEXTURE_LAYERED_2D_ARRAY) {} +}; + +class Cubemap : public TextureLayered { - GDCLASS(Texture3D, TextureLayered); + GDCLASS(Cubemap, TextureLayered); public: - Texture3D() : - TextureLayered(true) {} + Cubemap() : + TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP) {} }; -class TextureArray : public TextureLayered { +class CubemapArray : public TextureLayered { - GDCLASS(TextureArray, TextureLayered); + GDCLASS(CubemapArray, TextureLayered); public: - TextureArray() : - TextureLayered(false) {} + CubemapArray() : + TextureLayered(VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {} }; class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader { @@ -542,19 +421,19 @@ public: COMPRESSION_UNCOMPRESSED }; - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); 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; }; -class CurveTexture : public Texture { +class CurveTexture : public Texture2D { - GDCLASS(CurveTexture, Texture); + GDCLASS(CurveTexture, Texture2D); RES_BASE_EXTENSION("curvetex") private: - RID _texture; + mutable RID _texture; Ref<Curve> _curve; int _width; @@ -577,9 +456,6 @@ public: virtual int get_height() const { return 1; } virtual bool has_alpha() const { return false; } - virtual void set_flags(uint32_t p_flags) {} - virtual uint32_t get_flags() const { return FLAG_FILTER; } - CurveTexture(); ~CurveTexture(); }; @@ -597,8 +473,8 @@ public: */ //VARIANT_ENUM_CAST( Texture::CubeMapSide ); -class GradientTexture : public Texture { - GDCLASS(GradientTexture, Texture); +class GradientTexture : public Texture2D { + GDCLASS(GradientTexture, Texture2D); public: struct Point { @@ -633,28 +509,26 @@ public: virtual int get_height() const { return 1; } virtual bool has_alpha() const { return true; } - virtual void set_flags(uint32_t p_flags) {} - virtual uint32_t get_flags() const { return FLAG_FILTER; } - virtual Ref<Image> get_data() const; GradientTexture(); virtual ~GradientTexture(); }; -class ProxyTexture : public Texture { - GDCLASS(ProxyTexture, Texture); +class ProxyTexture : public Texture2D { + GDCLASS(ProxyTexture, Texture2D); private: - RID proxy; - Ref<Texture> base; + mutable RID proxy_ph; + mutable RID proxy; + Ref<Texture2D> base; protected: static void _bind_methods(); public: - void set_base(const Ref<Texture> &p_texture); - Ref<Texture> get_base() const; + void set_base(const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_base() const; virtual int get_width() const; virtual int get_height() const; @@ -662,15 +536,12 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - ProxyTexture(); ~ProxyTexture(); }; -class AnimatedTexture : public Texture { - GDCLASS(AnimatedTexture, Texture); +class AnimatedTexture : public Texture2D { + GDCLASS(AnimatedTexture, Texture2D); //use readers writers lock for this, since its far more times read than written to RWLock *rw_lock; @@ -680,11 +551,12 @@ private: MAX_FRAMES = 256 }; + RID proxy_ph; RID proxy; struct Frame { - Ref<Texture> texture; + Ref<Texture2D> texture; float delay_sec; Frame() { @@ -712,8 +584,8 @@ public: void set_frames(int p_frames); int get_frames() const; - void set_frame_texture(int p_frame, const Ref<Texture> &p_texture); - Ref<Texture> get_frame_texture(int p_frame) const; + void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture); + Ref<Texture2D> get_frame_texture(int p_frame) const; void set_frame_delay(int p_frame, float p_delay_sec); float get_frame_delay(int p_frame) const; @@ -727,9 +599,6 @@ public: virtual bool has_alpha() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - virtual Ref<Image> get_data() const; bool is_pixel_opaque(int p_x, int p_y) const; @@ -738,8 +607,8 @@ public: ~AnimatedTexture(); }; -class CameraTexture : public Texture { - GDCLASS(CameraTexture, Texture); +class CameraTexture : public Texture2D { + GDCLASS(CameraTexture, Texture2D); private: int camera_feed_id; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 1f2fa1d60b..d67f5f9ff2 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -37,112 +37,112 @@ void Theme::_emit_theme_changed() { emit_changed(); } -PoolVector<String> Theme::_get_icon_list(const String &p_type) const { +Vector<String> Theme::_get_icon_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_icon_list(p_type, &il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_stylebox_list(const String &p_type) const { +Vector<String> Theme::_get_stylebox_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_stylebox_list(p_type, &il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_stylebox_types(void) const { +Vector<String> Theme::_get_stylebox_types(void) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_stylebox_types(&il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_font_list(const String &p_type) const { +Vector<String> Theme::_get_font_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_font_list(p_type, &il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_color_list(const String &p_type) const { +Vector<String> Theme::_get_color_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_color_list(p_type, &il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_constant_list(const String &p_type) const { +Vector<String> Theme::_get_constant_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_constant_list(p_type, &il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } return ilret; } -PoolVector<String> Theme::_get_type_list(const String &p_type) const { +Vector<String> Theme::_get_type_list(const String &p_type) const { - PoolVector<String> ilret; + Vector<String> ilret; List<StringName> il; get_type_list(&il); ilret.resize(il.size()); int i = 0; - PoolVector<String>::Write w = ilret.write(); + String *w = ilret.ptrw(); for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { w[i] = E->get(); } @@ -196,7 +196,7 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const { if (type == "icons") { if (!has_icon(name, node_type)) - r_ret = Ref<Texture>(); + r_ret = Ref<Texture2D>(); else r_ret = get_icon(name, node_type); } else if (type == "styles") { @@ -238,7 +238,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const { while ((key2 = icon_map[*key].next(key2))) { - list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); + list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL)); } } @@ -302,13 +302,13 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { return; if (default_theme_font.is_valid()) { - default_theme_font->disconnect("changed", this, "_emit_theme_changed"); + default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } default_theme_font = p_default_font; if (default_theme_font.is_valid()) { - default_theme_font->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + default_theme_font->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } _change_notify(); @@ -322,7 +322,7 @@ Ref<Font> Theme::get_default_theme_font() const { Ref<Theme> Theme::project_default_theme; Ref<Theme> Theme::default_theme; -Ref<Texture> Theme::default_icon; +Ref<Texture2D> Theme::default_icon; Ref<StyleBox> Theme::default_style; Ref<Font> Theme::default_font; @@ -346,7 +346,7 @@ void Theme::set_project_default(const Ref<Theme> &p_project_default) { project_default_theme = p_project_default; } -void Theme::set_default_icon(const Ref<Texture> &p_icon) { +void Theme::set_default_icon(const Ref<Texture2D> &p_icon) { default_icon = p_icon; } @@ -359,20 +359,20 @@ void Theme::set_default_font(const Ref<Font> &p_font) { default_font = p_font; } -void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon) { +void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon) { //ERR_FAIL_COND(p_icon.is_null()); bool new_value = !icon_map.has(p_type) || !icon_map[p_type].has(p_name); if (icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) { - icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + icon_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } icon_map[p_type][p_name] = p_icon; if (p_icon.is_valid()) { - icon_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + icon_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -380,7 +380,7 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_type, const R emit_changed(); } } -Ref<Texture> Theme::get_icon(const StringName &p_name, const StringName &p_type) const { +Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_type) const { if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) { @@ -401,7 +401,7 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!icon_map[p_type].has(p_name)); if (icon_map[p_type][p_name].is_valid()) { - icon_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + icon_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } icon_map[p_type].erase(p_name); @@ -479,13 +479,13 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_type, con bool new_value = !style_map.has(p_type) || !style_map[p_type].has(p_name); if (style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) { - style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + style_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } style_map[p_type][p_name] = p_style; if (p_style.is_valid()) { - style_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + style_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) @@ -514,7 +514,7 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!style_map[p_type].has(p_name)); if (style_map[p_type][p_name].is_valid()) { - style_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + style_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } style_map[p_type].erase(p_name); @@ -554,13 +554,13 @@ void Theme::set_font(const StringName &p_name, const StringName &p_type, const R bool new_value = !font_map.has(p_type) || !font_map[p_type].has(p_name); if (font_map[p_type][p_name].is_valid()) { - font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + font_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } font_map[p_type][p_name] = p_font; if (p_font.is_valid()) { - font_map[p_type][p_name]->connect("changed", this, "_emit_theme_changed", varray(), CONNECT_REFERENCE_COUNTED); + font_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED); } if (new_value) { @@ -589,7 +589,7 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_type) { ERR_FAIL_COND(!font_map[p_type].has(p_name)); if (font_map[p_type][p_name].is_valid()) { - font_map[p_type][p_name]->disconnect("changed", this, "_emit_theme_changed"); + font_map[p_type][p_name]->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } font_map[p_type].erase(p_name); @@ -720,9 +720,9 @@ void Theme::clear() { while ((K = icon_map.next(K))) { const StringName *L = NULL; while ((L = icon_map[*K].next(L))) { - Ref<Texture> icon = icon_map[*K][*L]; + Ref<Texture2D> icon = icon_map[*K][*L]; if (icon.is_valid()) { - icon->disconnect("changed", this, "_emit_theme_changed"); + icon->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } } @@ -735,7 +735,7 @@ void Theme::clear() { while ((L = style_map[*K].next(L))) { Ref<StyleBox> style = style_map[*K][*L]; if (style.is_valid()) { - style->disconnect("changed", this, "_emit_theme_changed"); + style->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } } @@ -748,7 +748,7 @@ void Theme::clear() { while ((L = font_map[*K].next(L))) { Ref<Font> font = font_map[*K][*L]; if (font.is_valid()) { - font->disconnect("changed", this, "_emit_theme_changed"); + font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed)); } } } @@ -906,8 +906,6 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("get_type_list", "type"), &Theme::_get_type_list); - ClassDB::bind_method(D_METHOD("_emit_theme_changed"), &Theme::_emit_theme_changed); - ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme); ClassDB::bind_method(D_METHOD("copy_theme", "other"), &Theme::copy_theme); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 4bb614b24e..3d01f71ea0 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -45,20 +45,20 @@ class Theme : public Resource { void _emit_theme_changed(); - HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map; + HashMap<StringName, HashMap<StringName, Ref<Texture2D> > > icon_map; HashMap<StringName, HashMap<StringName, Ref<StyleBox> > > style_map; HashMap<StringName, HashMap<StringName, Ref<Font> > > font_map; HashMap<StringName, HashMap<StringName, Ref<Shader> > > shader_map; HashMap<StringName, HashMap<StringName, Color> > color_map; HashMap<StringName, HashMap<StringName, int> > constant_map; - PoolVector<String> _get_icon_list(const String &p_type) const; - PoolVector<String> _get_stylebox_list(const String &p_type) const; - PoolVector<String> _get_stylebox_types(void) const; - PoolVector<String> _get_font_list(const String &p_type) const; - PoolVector<String> _get_color_list(const String &p_type) const; - PoolVector<String> _get_constant_list(const String &p_type) const; - PoolVector<String> _get_type_list(const String &p_type) const; + Vector<String> _get_icon_list(const String &p_type) const; + Vector<String> _get_stylebox_list(const String &p_type) const; + Vector<String> _get_stylebox_types(void) const; + Vector<String> _get_font_list(const String &p_type) const; + Vector<String> _get_color_list(const String &p_type) const; + Vector<String> _get_constant_list(const String &p_type) const; + Vector<String> _get_type_list(const String &p_type) const; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -67,7 +67,7 @@ protected: static Ref<Theme> project_default_theme; static Ref<Theme> default_theme; - static Ref<Texture> default_icon; + static Ref<Texture2D> default_icon; static Ref<StyleBox> default_style; static Ref<Font> default_font; @@ -82,15 +82,15 @@ public: static Ref<Theme> get_project_default(); static void set_project_default(const Ref<Theme> &p_project_default); - static void set_default_icon(const Ref<Texture> &p_icon); + static void set_default_icon(const Ref<Texture2D> &p_icon); static void set_default_style(const Ref<StyleBox> &p_style); static void set_default_font(const Ref<Font> &p_font); void set_default_theme_font(const Ref<Font> &p_default_font); Ref<Font> get_default_theme_font() const; - void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture> &p_icon); - Ref<Texture> get_icon(const StringName &p_name, const StringName &p_type) const; + void set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_icon(const StringName &p_name, const StringName &p_type) const; bool has_icon(const StringName &p_name, const StringName &p_type) const; void clear_icon(const StringName &p_name, const StringName &p_type); void get_icon_list(StringName p_type, List<StringName> *p_list) const; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index db5037172e..f42b56bc83 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -326,8 +326,8 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { int id = E->key(); String pre = itos(id) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, pre + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "tex_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::COLOR, pre + "modulate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); @@ -360,7 +360,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::BOOL, pre + "shape_one_way", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::REAL, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::FLOAT, pre + "shape_one_way_margin", PROPERTY_HINT_RANGE, "0,128,0.01", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::INT, pre + "z_index", PROPERTY_HINT_RANGE, itos(VS::CANVAS_ITEM_Z_MIN) + "," + itos(VS::CANVAS_ITEM_Z_MAX) + ",1", PROPERTY_USAGE_NOEDITOR)); } @@ -387,7 +387,7 @@ TileSet::BitmaskMode TileSet::autotile_get_bitmask_mode(int p_id) const { return tile_map[p_id].autotile_data.bitmask_mode; } -void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) { +void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].texture = p_texture; @@ -395,22 +395,22 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture> &p_texture) { _change_notify("texture"); } -Ref<Texture> TileSet::tile_get_texture(int p_id) const { +Ref<Texture2D> TileSet::tile_get_texture(int p_id) const { - ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>()); + ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>()); return tile_map[p_id].texture; } -void TileSet::tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map) { +void TileSet::tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map) { ERR_FAIL_COND(!tile_map.has(p_id)); tile_map[p_id].normal_map = p_normal_map; emit_changed(); } -Ref<Texture> TileSet::tile_get_normal_map(int p_id) const { +Ref<Texture2D> TileSet::tile_get_normal_map(int p_id) const { - ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture>()); + ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>()); return tile_map[p_id].normal_map; } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index eab40ce467..8b540982a4 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -114,8 +114,8 @@ private: struct TileData { String name; - Ref<Texture> texture; - Ref<Texture> normal_map; + Ref<Texture2D> texture; + Ref<Texture2D> normal_map; Vector2 offset; Rect2i region; Vector<ShapeData> shapes_data; @@ -158,11 +158,11 @@ public: void tile_set_name(int p_id, const String &p_name); String tile_get_name(int p_id) const; - void tile_set_texture(int p_id, const Ref<Texture> &p_texture); - Ref<Texture> tile_get_texture(int p_id) const; + void tile_set_texture(int p_id, const Ref<Texture2D> &p_texture); + Ref<Texture2D> tile_get_texture(int p_id) const; - void tile_set_normal_map(int p_id, const Ref<Texture> &p_normal_map); - Ref<Texture> tile_get_normal_map(int p_id) const; + void tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map); + Ref<Texture2D> tile_get_normal_map(int p_id) const; void tile_set_texture_offset(int p_id, const Vector2 &p_offset); Vector2 tile_get_texture_offset(int p_id) const; diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index 444bb698ae..a9b96214c3 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -58,7 +58,8 @@ public: virtual void set_audio_track(int p_idx) = 0; - virtual Ref<Texture> get_texture() const = 0; + virtual Ref<Texture2D> get_texture() const = 0; + virtual void update(float p_delta) = 0; virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index b3a72ea7b6..407325c199 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -32,6 +32,7 @@ #include "core/vmap.h" #include "servers/visual/shader_types.h" +#include "visual_shader_nodes.h" bool VisualShaderNode::is_simple_decl() const { return simple_decl; @@ -127,6 +128,7 @@ void VisualShaderNode::_bind_methods() { ADD_SIGNAL(MethodInfo("editor_refresh_request")); BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR); + BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT); BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR); BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN); BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM); @@ -266,16 +268,16 @@ void VisualShaderNodeCustom::_bind_methods() { BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name")); BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description")); BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category")); - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory")); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type")); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count")); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port"))); - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_input_port_name", PropertyInfo(Variant::INT, "port"))); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count")); BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port"))); - BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_output_port_name", PropertyInfo(Variant::INT, "port"))); BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type"))); BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode"))); + BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_highend")); } VisualShaderNodeCustom::VisualShaderNodeCustom() { @@ -284,6 +286,49 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() { ///////////////////////////////////////////////////////// +void VisualShader::set_version(const String &p_version) { + version = p_version; +} + +String VisualShader::get_version() const { + return version; +} + +void VisualShader::update_version(const String &p_new_version) { + if (version == "") { + for (int i = 0; i < TYPE_MAX; i++) { + for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { + Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()); + if (expression.is_valid()) { + for (int j = 0; j < expression->get_input_port_count(); j++) { + int type = expression->get_input_port_type(j); + if (type > 0) { // + PORT_TYPE_SCALAR_INT + type += 1; + } + expression->set_input_port_type(j, type); + } + for (int j = 0; j < expression->get_output_port_count(); j++) { + int type = expression->get_output_port_type(j); + if (type > 0) { // + PORT_TYPE_SCALAR_INT + type += 1; + } + expression->set_output_port_type(j, type); + } + } + Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr()); + if (compare.is_valid()) { + int ctype = int(compare->get_comparison_type()); + if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT + ctype += 1; + } + compare->set_comparison_type(VisualShaderNodeCompare::ComparisonType(ctype)); + } + } + } + } + set_version(p_new_version); +} + void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) { ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_id < 2); @@ -304,10 +349,10 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co if (input.is_valid()) { input->shader_mode = shader_mode; input->shader_type = p_type; - input->connect("input_type_changed", this, "_input_type_changed", varray(p_type, p_id)); + input->connect("input_type_changed", callable_mp(this, &VisualShader::_input_type_changed), varray(p_type, p_id)); } - n.node->connect("changed", this, "_queue_update"); + n.node->connect("changed", callable_mp(this, &VisualShader::_queue_update)); Ref<VisualShaderNodeCustom> custom = n.node; if (custom.is_valid()) { @@ -374,10 +419,10 @@ void VisualShader::remove_node(Type p_type, int p_id) { Ref<VisualShaderNodeInput> input = g->nodes[p_id].node; if (input.is_valid()) { - input->disconnect("input_type_changed", this, "_input_type_changed"); + input->disconnect("input_type_changed", callable_mp(this, &VisualShader::_input_type_changed)); } - g->nodes[p_id].node->disconnect("changed", this, "_queue_update"); + g->nodes[p_id].node->disconnect("changed", callable_mp(this, &VisualShader::_queue_update)); g->nodes.erase(p_id); @@ -469,7 +514,7 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po } bool VisualShader::is_port_types_compatible(int p_a, int p_b) const { - return MAX(0, p_a - 2) == (MAX(0, p_b - 2)); + return MAX(0, p_a - 3) == (MAX(0, p_b - 3)); } void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { @@ -697,9 +742,11 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port ERR_FAIL_COND_V(err != OK, String()); if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) { - code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " );\n"; + code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n"; + } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + code += "\tCOLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n"; } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) { - code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0 );\n"; + code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n"; } else { code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n"; } @@ -984,8 +1031,8 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { } return false; } -void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { +void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { //mode p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Spatial,CanvasItem,Particles")); //render modes @@ -994,7 +1041,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { Set<String> toggles; for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) { - String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i]; int idx = 0; bool in_enum = false; @@ -1019,7 +1065,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get())); } @@ -1049,7 +1094,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::STRING, prop_name + "/expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } - p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "nodes/" + String(type_string[i]) + "/connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -1112,24 +1157,40 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui inputs[i] = src_var; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { + inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))"; } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { inputs[i] = "vec3(" + src_var + ")"; + } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = "vec3(float(" + src_var + "))"; } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { inputs[i] = "all(bvec3(" + src_var + "))"; } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { inputs[i] = src_var + " > 0.0 ? true : false"; + } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = src_var + " > 0 ? true : false"; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { inputs[i] = src_var + " ? 1.0 : 0.0"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { + inputs[i] = src_var + " ? 1 : 0"; } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = "float(" + src_var + ")"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { + inputs[i] = "int(" + src_var + ")"; } } else { Variant defval = vsnode->get_input_port_default_value(i); - if (defval.get_type() == Variant::REAL || defval.get_type() == Variant::INT) { + if (defval.get_type() == Variant::FLOAT) { float val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n"; + } else if (defval.get_type() == Variant::INT) { + int val = defval; + inputs[i] = "n_in" + itos(node) + "p" + itos(i); + code += "\tint " + inputs[i] + " = " + itos(val) + ";\n"; } else if (defval.get_type() == Variant::BOOL) { bool val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); @@ -1169,6 +1230,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui String var_name = "n_out" + itos(node) + "p" + itos(i); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: outputs[i] = "int " + var_name; break; case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break; case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break; @@ -1182,6 +1244,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui outputs[i] = "n_out" + itos(node) + "p" + itos(i); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: code += String() + "\tint " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break; @@ -1411,15 +1474,16 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_connections", "type"), &VisualShader::_get_node_connections); + ClassDB::bind_method(D_METHOD("set_version", "version"), &VisualShader::set_version); + ClassDB::bind_method(D_METHOD("get_version"), &VisualShader::get_version); + ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset); - ClassDB::bind_method(D_METHOD("_queue_update"), &VisualShader::_queue_update); ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader); - ClassDB::bind_method(D_METHOD("_input_type_changed"), &VisualShader::_input_type_changed); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version"); BIND_ENUM_CONSTANT(TYPE_VERTEX); BIND_ENUM_CONSTANT(TYPE_FRAGMENT); @@ -1575,7 +1639,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "index", "float(INDEX)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, @@ -1683,17 +1747,20 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T switch (get_output_port_type(0)) { case PORT_TYPE_SCALAR: { code = "\t" + p_output_vars[0] + " = 0.0;\n"; - } break; //default (none found) is scalar + } break; + case PORT_TYPE_SCALAR_INT: { + code = "\t" + p_output_vars[0] + " = 0;\n"; + } break; case PORT_TYPE_VECTOR: { code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; - } break; //default (none found) is scalar + } break; case PORT_TYPE_TRANSFORM: { code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n"; - } break; //default (none found) is scalar + } break; case PORT_TYPE_BOOLEAN: { code = "\t" + p_output_vars[0] + " = false;\n"; } break; - default: + default: //default (none found) is scalar break; } } @@ -1846,7 +1913,7 @@ void VisualShaderNodeInput::_bind_methods() { ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name); ClassDB::bind_method(D_METHOD("get_input_real_name"), &VisualShaderNodeInput::get_input_real_name); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name"); ADD_SIGNAL(MethodInfo("input_type_changed")); } VisualShaderNodeInput::VisualShaderNodeInput() { @@ -2046,7 +2113,7 @@ void VisualShaderNodeUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name); ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name"); } VisualShaderNodeUniform::VisualShaderNodeUniform() { @@ -2625,6 +2692,9 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad case PORT_TYPE_SCALAR: tk = "0.0"; break; + case PORT_TYPE_SCALAR_INT: + tk = "0"; + break; case PORT_TYPE_VECTOR: tk = "vec3(0.0, 0.0, 0.0)"; break; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index f35318e090..450dcfa081 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -41,6 +41,10 @@ class VisualShaderNode; class VisualShader : public Shader { GDCLASS(VisualShader, Shader); + friend class VisualShaderNodeVersionChecker; + + String version = ""; + public: enum Type { TYPE_VERTEX, @@ -58,7 +62,7 @@ public: struct DefaultTextureParam { StringName name; - Ref<Texture> param; + Ref<Texture2D> param; }; private: @@ -118,6 +122,11 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; public: + void set_version(const String &p_version); + String get_version() const; + + void update_version(const String &p_new_version); + enum { NODE_ID_INVALID = -1, NODE_ID_OUTPUT = 0, @@ -182,6 +191,7 @@ protected: public: enum PortType { PORT_TYPE_SCALAR, + PORT_TYPE_SCALAR_INT, PORT_TYPE_VECTOR, PORT_TYPE_BOOLEAN, PORT_TYPE_TRANSFORM, diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 8f0e0058ea..2064ca10f3 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -30,66 +30,127 @@ #include "visual_shader_nodes.h" -////////////// Scalar +////////////// Scalar(Float) -String VisualShaderNodeScalarConstant::get_caption() const { - return "Scalar"; +String VisualShaderNodeFloatConstant::get_caption() const { + return "ScalarFloat"; } -int VisualShaderNodeScalarConstant::get_input_port_count() const { +int VisualShaderNodeFloatConstant::get_input_port_count() const { return 0; } -VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const { +VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatConstant::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeScalarConstant::get_output_port_count() const { +int VisualShaderNodeFloatConstant::get_output_port_count() const { return 1; } -VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const { +VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatConstant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarConstant::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) const { +String VisualShaderNodeFloatConstant::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) const { return "\t" + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n"; } -void VisualShaderNodeScalarConstant::set_constant(float p_value) { +void VisualShaderNodeFloatConstant::set_constant(float p_value) { constant = p_value; emit_changed(); } -float VisualShaderNodeScalarConstant::get_constant() const { +float VisualShaderNodeFloatConstant::get_constant() const { return constant; } -Vector<StringName> VisualShaderNodeScalarConstant::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatConstant::get_editable_properties() const { Vector<StringName> props; props.push_back("constant"); return props; } -void VisualShaderNodeScalarConstant::_bind_methods() { +void VisualShaderNodeFloatConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeScalarConstant::set_constant); - ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeScalarConstant::get_constant); + ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeFloatConstant::set_constant); + ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeFloatConstant::get_constant); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant"), "set_constant", "get_constant"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant"), "set_constant", "get_constant"); } -VisualShaderNodeScalarConstant::VisualShaderNodeScalarConstant() { +VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() { + constant = 0.0; +} + +////////////// Scalar(Int) + +String VisualShaderNodeIntConstant::get_caption() const { + return "ScalarInt"; +} + +int VisualShaderNodeIntConstant::get_input_port_count() const { + return 0; +} + +VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntConstant::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeIntConstant::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntConstant::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntConstant::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) const { + return "\t" + p_output_vars[0] + " = " + itos(constant) + ";\n"; +} + +void VisualShaderNodeIntConstant::set_constant(int p_value) { + constant = p_value; + emit_changed(); +} + +int VisualShaderNodeIntConstant::get_constant() const { + return constant; +} + +Vector<StringName> VisualShaderNodeIntConstant::get_editable_properties() const { + Vector<StringName> props; + props.push_back("constant"); + return props; +} + +void VisualShaderNodeIntConstant::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeIntConstant::set_constant); + ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeIntConstant::get_constant); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant"), "set_constant", "get_constant"); +} + +VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() { constant = 0; } @@ -357,7 +418,7 @@ VisualShaderNodeTransformConstant::VisualShaderNodeTransformConstant() { ////////////// Texture String VisualShaderNodeTexture::get_caption() const { - return "Texture"; + return "Texture2D"; } int VisualShaderNodeTexture::get_input_port_count() const { @@ -649,13 +710,13 @@ VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const { return source; } -void VisualShaderNodeTexture::set_texture(Ref<Texture> p_value) { +void VisualShaderNodeTexture::set_texture(Ref<Texture2D> p_value) { texture = p_value; emit_changed(); } -Ref<Texture> VisualShaderNodeTexture::get_texture() const { +Ref<Texture2D> VisualShaderNodeTexture::get_texture() const { return texture; } @@ -727,7 +788,7 @@ void VisualShaderNodeTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); @@ -746,17 +807,17 @@ VisualShaderNodeTexture::VisualShaderNodeTexture() { source = SOURCE_TEXTURE; } -////////////// CubeMap +////////////// Cubemap -String VisualShaderNodeCubeMap::get_caption() const { - return "CubeMap"; +String VisualShaderNodeCubemap::get_caption() const { + return "Cubemap"; } -int VisualShaderNodeCubeMap::get_input_port_count() const { +int VisualShaderNodeCubemap::get_input_port_count() const { return 3; } -VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const { +VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_input_port_type(int p_port) const { switch (p_port) { case 0: return PORT_TYPE_VECTOR; @@ -769,7 +830,7 @@ VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(i } } -String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { +String VisualShaderNodeCubemap::get_input_port_name(int p_port) const { switch (p_port) { case 0: return "uv"; @@ -782,19 +843,19 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { } } -int VisualShaderNodeCubeMap::get_output_port_count() const { +int VisualShaderNodeCubemap::get_output_port_count() const { return 2; } -VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const { +VisualShaderNodeCubemap::PortType VisualShaderNodeCubemap::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } -String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const { +String VisualShaderNodeCubemap::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } -Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { VisualShader::DefaultTextureParam dtp; dtp.name = make_unique_id(p_type, p_id, "cube"); dtp.param = cube_map; @@ -803,7 +864,7 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_t return ret; } -String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { if (source == SOURCE_TEXTURE) { String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube"); @@ -817,7 +878,7 @@ String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShade return String(); } -String VisualShaderNodeCubeMap::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) const { +String VisualShaderNodeCubemap::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) const { String code; String id; @@ -860,44 +921,44 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: return code; } -String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const { +String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const { if (p_port == 0) { return "vec3(UV, 0.0)"; } return ""; } -void VisualShaderNodeCubeMap::set_source(Source p_source) { +void VisualShaderNodeCubemap::set_source(Source p_source) { source = p_source; emit_changed(); emit_signal("editor_refresh_request"); } -VisualShaderNodeCubeMap::Source VisualShaderNodeCubeMap::get_source() const { +VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const { return source; } -void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) { +void VisualShaderNodeCubemap::set_cube_map(Ref<Cubemap> p_value) { cube_map = p_value; emit_changed(); } -Ref<CubeMap> VisualShaderNodeCubeMap::get_cube_map() const { +Ref<Cubemap> VisualShaderNodeCubemap::get_cube_map() const { return cube_map; } -void VisualShaderNodeCubeMap::set_texture_type(TextureType p_type) { +void VisualShaderNodeCubemap::set_texture_type(TextureType p_type) { texture_type = p_type; emit_changed(); } -VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() const { +VisualShaderNodeCubemap::TextureType VisualShaderNodeCubemap::get_texture_type() const { return texture_type; } -Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const { +Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const { Vector<StringName> props; props.push_back("source"); if (source == SOURCE_TEXTURE) { @@ -907,19 +968,19 @@ Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const { return props; } -void VisualShaderNodeCubeMap::_bind_methods() { +void VisualShaderNodeCubemap::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubeMap::set_source); - ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubeMap::get_source); + ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source); + ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source); - ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map); - ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map); + ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubemap::set_cube_map); + ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubemap::get_cube_map); - ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type); - ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type); + ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubemap::set_texture_type); + ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubemap::get_texture_type); ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); @@ -930,43 +991,43 @@ void VisualShaderNodeCubeMap::_bind_methods() { BIND_ENUM_CONSTANT(TYPE_NORMALMAP); } -VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() { +VisualShaderNodeCubemap::VisualShaderNodeCubemap() { texture_type = TYPE_DATA; source = SOURCE_TEXTURE; simple_decl = false; } -////////////// Scalar Op +////////////// Float Op -String VisualShaderNodeScalarOp::get_caption() const { - return "ScalarOp"; +String VisualShaderNodeFloatOp::get_caption() const { + return "FloatOp"; } -int VisualShaderNodeScalarOp::get_input_port_count() const { +int VisualShaderNodeFloatOp::get_input_port_count() const { return 2; } -VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const { +VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } -int VisualShaderNodeScalarOp::get_output_port_count() const { +int VisualShaderNodeFloatOp::get_output_port_count() const { return 1; } -VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const { +VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } -String VisualShaderNodeScalarOp::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) const { +String VisualShaderNodeFloatOp::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) const { String code = "\t" + p_output_vars[0] + " = "; switch (op) { @@ -986,27 +1047,27 @@ String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader return code; } -void VisualShaderNodeScalarOp::set_operator(Operator p_op) { +void VisualShaderNodeFloatOp::set_operator(Operator p_op) { op = p_op; emit_changed(); } -VisualShaderNodeScalarOp::Operator VisualShaderNodeScalarOp::get_operator() const { +VisualShaderNodeFloatOp::Operator VisualShaderNodeFloatOp::get_operator() const { return op; } -Vector<StringName> VisualShaderNodeScalarOp::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatOp::get_editable_properties() const { Vector<StringName> props; props.push_back("operator"); return props; } -void VisualShaderNodeScalarOp::_bind_methods() { +void VisualShaderNodeFloatOp::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeScalarOp::set_operator); - ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeScalarOp::get_operator); + ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator); + ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator); ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator"); @@ -1022,12 +1083,97 @@ void VisualShaderNodeScalarOp::_bind_methods() { BIND_ENUM_CONSTANT(OP_STEP); } -VisualShaderNodeScalarOp::VisualShaderNodeScalarOp() { +VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() { op = OP_ADD; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); } +////////////// Integer Op + +String VisualShaderNodeIntOp::get_caption() const { + return "IntOp"; +} + +int VisualShaderNodeIntOp::get_input_port_count() const { + return 2; +} + +VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntOp::get_input_port_name(int p_port) const { + return p_port == 0 ? "a" : "b"; +} + +int VisualShaderNodeIntOp::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntOp::get_output_port_name(int p_port) const { + return "op"; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntOp::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) const { + + String code = "\t" + p_output_vars[0] + " = "; + switch (op) { + + case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break; + case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break; + case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break; + case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break; + case OP_MOD: code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n"; break; + case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + } + + return code; +} + +void VisualShaderNodeIntOp::set_operator(Operator p_op) { + + op = p_op; + emit_changed(); +} + +VisualShaderNodeIntOp::Operator VisualShaderNodeIntOp::get_operator() const { + return op; +} + +Vector<StringName> VisualShaderNodeIntOp::get_editable_properties() const { + Vector<StringName> props; + props.push_back("operator"); + return props; +} + +void VisualShaderNodeIntOp::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); + ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + + BIND_ENUM_CONSTANT(OP_ADD); + BIND_ENUM_CONSTANT(OP_SUB); + BIND_ENUM_CONSTANT(OP_MUL); + BIND_ENUM_CONSTANT(OP_DIV); + BIND_ENUM_CONSTANT(OP_MOD); + BIND_ENUM_CONSTANT(OP_MAX); + BIND_ENUM_CONSTANT(OP_MIN); +} + +VisualShaderNodeIntOp::VisualShaderNodeIntOp() { + op = OP_ADD; + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); +} + ////////////// Vector Op String VisualShaderNodeVectorOp::get_caption() const { @@ -1462,37 +1608,37 @@ VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() { set_input_port_default_value(1, Vector3()); } -////////////// Scalar Func +////////////// Float Func -String VisualShaderNodeScalarFunc::get_caption() const { - return "ScalarFunc"; +String VisualShaderNodeFloatFunc::get_caption() const { + return "FloatFunc"; } -int VisualShaderNodeScalarFunc::get_input_port_count() const { +int VisualShaderNodeFloatFunc::get_input_port_count() const { return 1; } -VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const { +VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatFunc::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeScalarFunc::get_output_port_count() const { +int VisualShaderNodeFloatFunc::get_output_port_count() const { return 1; } -VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const { +VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarFunc::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) const { +String VisualShaderNodeFloatFunc::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) const { static const char *scalar_func_id[FUNC_ONEMINUS + 1] = { "sin($)", @@ -1532,27 +1678,27 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad return "\t" + p_output_vars[0] + " = " + String(scalar_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; } -void VisualShaderNodeScalarFunc::set_function(Function p_func) { +void VisualShaderNodeFloatFunc::set_function(Function p_func) { func = p_func; emit_changed(); } -VisualShaderNodeScalarFunc::Function VisualShaderNodeScalarFunc::get_function() const { +VisualShaderNodeFloatFunc::Function VisualShaderNodeFloatFunc::get_function() const { return func; } -Vector<StringName> VisualShaderNodeScalarFunc::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatFunc::get_editable_properties() const { Vector<StringName> props; props.push_back("function"); return props; } -void VisualShaderNodeScalarFunc::_bind_methods() { +void VisualShaderNodeFloatFunc::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarFunc::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarFunc::get_function); + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Frac,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function"); @@ -1590,11 +1736,108 @@ void VisualShaderNodeScalarFunc::_bind_methods() { BIND_ENUM_CONSTANT(FUNC_ONEMINUS); } -VisualShaderNodeScalarFunc::VisualShaderNodeScalarFunc() { +VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() { func = FUNC_SIGN; set_input_port_default_value(0, 0.0); } +////////////// Int Func + +String VisualShaderNodeIntFunc::get_caption() const { + return "IntFunc"; +} + +int VisualShaderNodeIntFunc::get_input_port_count() const { + if (func == FUNC_CLAMP) { + return 3; + } + return 1; +} + +VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const { + if (func == FUNC_CLAMP) { + if (p_port == 0) { + return ""; + } else if (p_port == 1) { + return "min"; + } else if (p_port == 2) { + return "max"; + } + } + return ""; +} + +int VisualShaderNodeIntFunc::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntFunc::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) const { + if (func == FUNC_CLAMP) { + return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + } + + static const char *int_func_id[FUNC_SIGN + 1] = { + "abs($)", + "", + "-($)", + "sign($)" + }; + + return "\t" + p_output_vars[0] + " = " + String(int_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; +} + +void VisualShaderNodeIntFunc::set_function(Function p_func) { + if (func != p_func) { + if (p_func == FUNC_CLAMP) { + set_input_port_default_value(1, 0); + set_input_port_default_value(2, 0); + } + } + func = p_func; + emit_changed(); +} + +VisualShaderNodeIntFunc::Function VisualShaderNodeIntFunc::get_function() const { + + return func; +} + +Vector<StringName> VisualShaderNodeIntFunc::get_editable_properties() const { + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeIntFunc::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_ABS); + BIND_ENUM_CONSTANT(FUNC_CLAMP); + BIND_ENUM_CONSTANT(FUNC_NEGATE); + BIND_ENUM_CONSTANT(FUNC_SIGN); +} + +VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() { + func = FUNC_SIGN; + set_input_port_default_value(0, 0); +} + ////////////// Vector Func String VisualShaderNodeVectorFunc::get_caption() const { @@ -3008,37 +3251,37 @@ VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() { set_input_port_default_value(0, Transform()); } -////////////// Scalar Uniform +////////////// Float Uniform -String VisualShaderNodeScalarUniform::get_caption() const { - return "ScalarUniform"; +String VisualShaderNodeFloatUniform::get_caption() const { + return "FloatUniform"; } -int VisualShaderNodeScalarUniform::get_input_port_count() const { +int VisualShaderNodeFloatUniform::get_input_port_count() const { return 0; } -VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const { +VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatUniform::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeScalarUniform::get_output_port_count() const { +int VisualShaderNodeFloatUniform::get_output_port_count() const { return 1; } -VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const { +VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { if (hint == HINT_RANGE) { return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; } else if (hint == HINT_RANGE_STEP) { @@ -3047,70 +3290,70 @@ String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, Visua return "uniform float " + get_uniform_name() + ";\n"; } -String VisualShaderNodeScalarUniform::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) const { +String VisualShaderNodeFloatUniform::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) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } -void VisualShaderNodeScalarUniform::set_hint(Hint p_hint) { +void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { hint = p_hint; emit_changed(); } -VisualShaderNodeScalarUniform::Hint VisualShaderNodeScalarUniform::get_hint() const { +VisualShaderNodeFloatUniform::Hint VisualShaderNodeFloatUniform::get_hint() const { return hint; } -void VisualShaderNodeScalarUniform::set_min(float p_value) { +void VisualShaderNodeFloatUniform::set_min(float p_value) { hint_range_min = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_min() const { +float VisualShaderNodeFloatUniform::get_min() const { return hint_range_min; } -void VisualShaderNodeScalarUniform::set_max(float p_value) { +void VisualShaderNodeFloatUniform::set_max(float p_value) { hint_range_max = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_max() const { +float VisualShaderNodeFloatUniform::get_max() const { return hint_range_max; } -void VisualShaderNodeScalarUniform::set_step(float p_value) { +void VisualShaderNodeFloatUniform::set_step(float p_value) { hint_range_step = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_step() const { +float VisualShaderNodeFloatUniform::get_step() const { return hint_range_step; } -void VisualShaderNodeScalarUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeScalarUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeScalarUniform::get_hint); +void VisualShaderNodeFloatUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeScalarUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeScalarUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatUniform::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatUniform::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeScalarUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeScalarUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatUniform::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatUniform::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeScalarUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeScalarUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "min"), "set_min", "get_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "max"), "set_max", "get_max"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "step"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max"), "set_max", "get_max"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step"), "set_step", "get_step"); BIND_ENUM_CONSTANT(HINT_NONE); BIND_ENUM_CONSTANT(HINT_RANGE); BIND_ENUM_CONSTANT(HINT_RANGE_STEP); } -Vector<StringName> VisualShaderNodeScalarUniform::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const { Vector<StringName> props; props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { @@ -3123,13 +3366,135 @@ Vector<StringName> VisualShaderNodeScalarUniform::get_editable_properties() cons return props; } -VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() { +VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() { hint = HINT_NONE; hint_range_min = 0.0; hint_range_max = 1.0; hint_range_step = 0.1; } +////////////// Integer Uniform + +String VisualShaderNodeIntUniform::get_caption() const { + return "IntUniform"; +} + +int VisualShaderNodeIntUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntUniform::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeIntUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + if (hint == HINT_RANGE) { + return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; + } else if (hint == HINT_RANGE_STEP) { + return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n"; + } + return "uniform int " + get_uniform_name() + ";\n"; +} + +String VisualShaderNodeIntUniform::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) const { + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +} + +void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { + hint = p_hint; + emit_changed(); +} + +VisualShaderNodeIntUniform::Hint VisualShaderNodeIntUniform::get_hint() const { + return hint; +} + +void VisualShaderNodeIntUniform::set_min(int p_value) { + hint_range_min = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_min() const { + return hint_range_min; +} + +void VisualShaderNodeIntUniform::set_max(int p_value) { + hint_range_max = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_max() const { + return hint_range_max; +} + +void VisualShaderNodeIntUniform::set_step(int p_value) { + hint_range_step = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_step() const { + return hint_range_step; +} + +void VisualShaderNodeIntUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint); + + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntUniform::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntUniform::get_min); + + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntUniform::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntUniform::get_max); + + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); + + BIND_ENUM_CONSTANT(HINT_NONE); + BIND_ENUM_CONSTANT(HINT_RANGE); + BIND_ENUM_CONSTANT(HINT_RANGE_STEP); +} + +Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { + Vector<StringName> props; + props.push_back("hint"); + if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { + props.push_back("min"); + props.push_back("max"); + } + if (hint == HINT_RANGE_STEP) { + props.push_back("step"); + } + return props; +} + +VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() { + hint = HINT_NONE; + hint_range_min = 0; + hint_range_max = 100; + hint_range_step = 1; +} + ////////////// Boolean Uniform String VisualShaderNodeBooleanUniform::get_caption() const { @@ -3552,41 +3917,41 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_default_hint(int VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { } -////////////// CubeMap Uniform +////////////// Cubemap Uniform -String VisualShaderNodeCubeMapUniform::get_caption() const { - return "CubeMapUniform"; +String VisualShaderNodeCubemapUniform::get_caption() const { + return "CubemapUniform"; } -int VisualShaderNodeCubeMapUniform::get_output_port_count() const { +int VisualShaderNodeCubemapUniform::get_output_port_count() const { return 1; } -VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const { +VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_output_port_type(int p_port) const { return PORT_TYPE_SAMPLER; } -String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeCubemapUniform::get_output_port_name(int p_port) const { return "samplerCube"; } -int VisualShaderNodeCubeMapUniform::get_input_port_count() const { +int VisualShaderNodeCubemapUniform::get_input_port_count() const { return 0; } -VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const { +VisualShaderNodeCubemapUniform::PortType VisualShaderNodeCubemapUniform::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeCubemapUniform::get_input_port_name(int p_port) const { return ""; } -String VisualShaderNodeCubeMapUniform::get_input_port_default_hint(int p_port) const { +String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) const { return ""; } -String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code = "uniform samplerCube " + get_uniform_name(); switch (texture_type) { @@ -3609,11 +3974,11 @@ String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, Visu return code; } -String VisualShaderNodeCubeMapUniform::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) const { +String VisualShaderNodeCubemapUniform::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) const { return String(); } -VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() { +VisualShaderNodeCubemapUniform::VisualShaderNodeCubemapUniform() { } ////////////// If @@ -3968,6 +4333,8 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i switch (ctype) { case CTYPE_SCALAR: return PORT_TYPE_SCALAR; + case CTYPE_SCALAR_INT: + return PORT_TYPE_SCALAR_INT; case CTYPE_VECTOR: return PORT_TYPE_VECTOR; case CTYPE_BOOLEAN: @@ -4046,10 +4413,14 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader: } else if (func == FUNC_NOT_EQUAL) { code += "\t" + p_output_vars[0] + " = !(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");"; } else { - code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; } break; + case CTYPE_SCALAR_INT: + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + case CTYPE_VECTOR: code += "\t{\n"; code += "\t\tbvec3 _bv = " + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; @@ -4085,6 +4456,11 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) { set_input_port_default_value(1, 0.0); simple_decl = true; break; + case CTYPE_SCALAR_INT: + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); + simple_decl = true; + break; case CTYPE_VECTOR: 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)); @@ -4151,11 +4527,12 @@ void VisualShaderNodeCompare::_bind_methods() { ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition); ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function"); ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition"); BIND_ENUM_CONSTANT(CTYPE_SCALAR); + BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT); BIND_ENUM_CONSTANT(CTYPE_VECTOR); BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 3d57fd0efc..035e39230c 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -37,8 +37,8 @@ /// CONSTANTS /////////////////////////////////////// -class VisualShaderNodeScalarConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarConstant, VisualShaderNode); +class VisualShaderNodeFloatConstant : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode); float constant; protected: @@ -62,7 +62,37 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarConstant(); + VisualShaderNodeFloatConstant(); +}; + +/////////////////////////////////////// + +class VisualShaderNodeIntConstant : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode); + int constant; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_constant(int p_value); + int get_constant() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntConstant(); }; /////////////////////////////////////// @@ -191,7 +221,7 @@ public: class VisualShaderNodeTexture : public VisualShaderNode { GDCLASS(VisualShaderNodeTexture, VisualShaderNode); - Ref<Texture> texture; + Ref<Texture2D> texture; public: enum Source { @@ -236,8 +266,8 @@ public: void set_source(Source p_source); Source get_source() const; - void set_texture(Ref<Texture> p_value); - Ref<Texture> get_texture() const; + void set_texture(Ref<Texture2D> p_value); + Ref<Texture2D> get_texture() const; void set_texture_type(TextureType p_type); TextureType get_texture_type() const; @@ -254,9 +284,9 @@ VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source) /////////////////////////////////////// -class VisualShaderNodeCubeMap : public VisualShaderNode { - GDCLASS(VisualShaderNodeCubeMap, VisualShaderNode); - Ref<CubeMap> cube_map; +class VisualShaderNodeCubemap : public VisualShaderNode { + GDCLASS(VisualShaderNodeCubemap, VisualShaderNode); + Ref<Cubemap> cube_map; public: enum Source { @@ -296,26 +326,26 @@ public: void set_source(Source p_source); Source get_source() const; - void set_cube_map(Ref<CubeMap> p_value); - Ref<CubeMap> get_cube_map() const; + void set_cube_map(Ref<Cubemap> p_value); + Ref<Cubemap> get_cube_map() const; void set_texture_type(TextureType p_type); TextureType get_texture_type() const; virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeCubeMap(); + VisualShaderNodeCubemap(); }; -VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType) -VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::Source) +VARIANT_ENUM_CAST(VisualShaderNodeCubemap::TextureType) +VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source) /////////////////////////////////////// /// OPS /////////////////////////////////////// -class VisualShaderNodeScalarOp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarOp, VisualShaderNode); +class VisualShaderNodeFloatOp : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatOp, VisualShaderNode); public: enum Operator { @@ -354,10 +384,52 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarOp(); + VisualShaderNodeFloatOp(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarOp::Operator) +VARIANT_ENUM_CAST(VisualShaderNodeFloatOp::Operator) + +class VisualShaderNodeIntOp : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntOp, VisualShaderNode); + +public: + enum Operator { + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_MAX, + OP_MIN, + }; + +protected: + Operator op; + + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_operator(Operator p_op); + Operator get_operator() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntOp(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeIntOp::Operator) class VisualShaderNodeVectorOp : public VisualShaderNode { GDCLASS(VisualShaderNodeVectorOp, VisualShaderNode); @@ -539,11 +611,11 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeTransformVecMult::Operator) /////////////////////////////////////// -/// SCALAR FUNC +/// FLOAT FUNC /////////////////////////////////////// -class VisualShaderNodeScalarFunc : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarFunc, VisualShaderNode); +class VisualShaderNodeFloatFunc : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatFunc, VisualShaderNode); public: enum Function { @@ -604,10 +676,53 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarFunc(); + VisualShaderNodeFloatFunc(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeFloatFunc::Function) + +/////////////////////////////////////// +/// INT FUNC +/////////////////////////////////////// + +class VisualShaderNodeIntFunc : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntFunc, VisualShaderNode); + +public: + enum Function { + FUNC_ABS, + FUNC_CLAMP, + FUNC_NEGATE, + FUNC_SIGN, + }; + +protected: + Function func; + + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_function(Function p_func); + Function get_function() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntFunc(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarFunc::Function) +VARIANT_ENUM_CAST(VisualShaderNodeIntFunc::Function) /////////////////////////////////////// /// VECTOR FUNC @@ -1297,8 +1412,8 @@ public: /// UNIFORMS /////////////////////////////////////// -class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform); +class VisualShaderNodeFloatUniform : public VisualShaderNodeUniform { + GDCLASS(VisualShaderNodeFloatUniform, VisualShaderNodeUniform); public: enum Hint { @@ -1344,10 +1459,62 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarUniform(); + VisualShaderNodeFloatUniform(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeFloatUniform::Hint) + +class VisualShaderNodeIntUniform : public VisualShaderNodeUniform { + GDCLASS(VisualShaderNodeIntUniform, VisualShaderNodeUniform); + +public: + enum Hint { + HINT_NONE, + HINT_RANGE, + HINT_RANGE_STEP, + }; + +private: + Hint hint; + int hint_range_min; + int hint_range_max; + int hint_range_step; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_hint(Hint p_hint); + Hint get_hint() const; + + void set_min(int p_value); + int get_min() const; + + void set_max(int p_value); + int get_max() const; + + void set_step(int p_value); + int get_step() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntUniform(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint) /////////////////////////////////////// @@ -1514,8 +1681,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeCubeMapUniform : public VisualShaderNodeTextureUniform { - GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNodeTextureUniform); +class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); public: virtual String get_caption() const; @@ -1532,7 +1699,7 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - VisualShaderNodeCubeMapUniform(); + VisualShaderNodeCubemapUniform(); }; /////////////////////////////////////// @@ -1669,9 +1836,10 @@ class VisualShaderNodeCompare : public VisualShaderNode { public: enum ComparisonType { CTYPE_SCALAR, + CTYPE_SCALAR_INT, CTYPE_VECTOR, CTYPE_BOOLEAN, - CTYPE_TRANSFORM + CTYPE_TRANSFORM, }; enum Function { diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index 1099852098..a7e519479f 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -262,6 +262,7 @@ RID World::get_space() const { return space; } + RID World::get_scenario() const { return scenario; @@ -305,6 +306,20 @@ Ref<Environment> World::get_fallback_environment() const { return fallback_environment; } +void World::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) { + + camera_effects = p_camera_effects; + if (camera_effects.is_valid()) + VS::get_singleton()->scenario_set_camera_effects(scenario, camera_effects->get_rid()); + else + VS::get_singleton()->scenario_set_camera_effects(scenario, RID()); +} + +Ref<CameraEffects> World::get_camera_effects() const { + + return camera_effects; +} + PhysicsDirectSpaceState *World::get_direct_space_state() { return PhysicsServer::get_singleton()->space_get_direct_state(space); @@ -325,9 +340,12 @@ void World::_bind_methods() { ClassDB::bind_method(D_METHOD("get_environment"), &World::get_environment); ClassDB::bind_method(D_METHOD("set_fallback_environment", "env"), &World::set_fallback_environment); ClassDB::bind_method(D_METHOD("get_fallback_environment"), &World::get_fallback_environment); + ClassDB::bind_method(D_METHOD("set_camera_effects", "env"), &World::set_camera_effects); + ClassDB::bind_method(D_METHOD("get_camera_effects"), &World::get_camera_effects); ClassDB::bind_method(D_METHOD("get_direct_space_state"), &World::get_direct_space_state); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "camera_effects", PROPERTY_HINT_RESOURCE_TYPE, "CameraEffects"), "set_camera_effects", "get_camera_effects"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "space", PROPERTY_HINT_NONE, "", 0), "", "get_space"); ADD_PROPERTY(PropertyInfo(Variant::_RID, "scenario", PROPERTY_HINT_NONE, "", 0), "", "get_scenario"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "direct_space_state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectSpaceState", 0), "", "get_direct_space_state"); @@ -342,9 +360,9 @@ World::World() { PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8)); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0))); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/3d/default_linear_damp", 0.1)); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1)); - ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); #ifdef _3D_DISABLED indexer = NULL; diff --git a/scene/resources/world.h b/scene/resources/world.h index b6248b28c8..6fd79abaaf 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -50,6 +50,7 @@ private: SpatialIndexer *indexer; Ref<Environment> environment; Ref<Environment> fallback_environment; + Ref<CameraEffects> camera_effects; protected: static void _bind_methods(); @@ -77,6 +78,9 @@ public: void set_fallback_environment(const Ref<Environment> &p_environment); Ref<Environment> get_fallback_environment() const; + void set_camera_effects(const Ref<CameraEffects> &p_camera_effects); + Ref<CameraEffects> get_camera_effects() const; + void get_camera_list(List<Camera *> *r_cameras); PhysicsDirectSpaceState *get_direct_space_state(); diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 5cc809d8e3..6bdc4cf6f0 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -394,9 +394,9 @@ World2D::World2D() { Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98)); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1))); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1)); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0)); - ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::FLOAT, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); indexer = memnew(SpatialIndexer2D); } diff --git a/scene/resources/plane_shape.cpp b/scene/resources/world_margin_shape.cpp index ddc820233e..b5b701327c 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/world_margin_shape.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* plane_shape.cpp */ +/* world_margin_shape.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "plane_shape.h" +#include "world_margin_shape.h" #include "servers/physics_server.h" -Vector<Vector3> PlaneShape::get_debug_mesh_lines() { +Vector<Vector3> WorldMarginShape::get_debug_mesh_lines() { Plane p = get_plane(); Vector<Vector3> points; @@ -61,13 +61,13 @@ Vector<Vector3> PlaneShape::get_debug_mesh_lines() { return points; } -void PlaneShape::_update_shape() { +void WorldMarginShape::_update_shape() { PhysicsServer::get_singleton()->shape_set_data(get_shape(), plane); Shape::_update_shape(); } -void PlaneShape::set_plane(Plane p_plane) { +void WorldMarginShape::set_plane(Plane p_plane) { plane = p_plane; _update_shape(); @@ -75,20 +75,20 @@ void PlaneShape::set_plane(Plane p_plane) { _change_notify("plane"); } -Plane PlaneShape::get_plane() const { +Plane WorldMarginShape::get_plane() const { return plane; } -void PlaneShape::_bind_methods() { +void WorldMarginShape::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_plane", "plane"), &PlaneShape::set_plane); - ClassDB::bind_method(D_METHOD("get_plane"), &PlaneShape::get_plane); + ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldMarginShape::set_plane); + ClassDB::bind_method(D_METHOD("get_plane"), &WorldMarginShape::get_plane); ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane"); } -PlaneShape::PlaneShape() : +WorldMarginShape::WorldMarginShape() : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) { set_plane(Plane(0, 1, 0, 0)); diff --git a/scene/resources/plane_shape.h b/scene/resources/world_margin_shape.h index 8bea1268e5..78ea570212 100644 --- a/scene/resources/plane_shape.h +++ b/scene/resources/world_margin_shape.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* plane_shape.h */ +/* world_margin_shape.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PLANE_SHAPE_H -#define PLANE_SHAPE_H +#ifndef WORLD_MARGIN_SHAPE_H +#define WORLD_MARGIN_SHAPE_H #include "scene/resources/shape.h" -class PlaneShape : public Shape { +class WorldMarginShape : public Shape { - GDCLASS(PlaneShape, Shape); + GDCLASS(WorldMarginShape, Shape); Plane plane; protected: @@ -47,7 +47,11 @@ public: Plane get_plane() const; virtual Vector<Vector3> get_debug_mesh_lines(); + virtual real_t get_enclosing_radius() const { + // Should be infinite? + return 0; + } - PlaneShape(); + WorldMarginShape(); }; -#endif // PLANE_SHAPE_H +#endif // WORLD_MARGIN_SHAPE_H diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 6299c3a801..d3c5a87cae 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -119,12 +119,6 @@ SceneStringNames::SceneStringNames() { camera_entered = StaticCString::create("camera_entered"); camera_exited = StaticCString::create("camera_exited"); - _body_enter_tree = StaticCString::create("_body_enter_tree"); - _body_exit_tree = StaticCString::create("_body_exit_tree"); - - _area_enter_tree = StaticCString::create("_area_enter_tree"); - _area_exit_tree = StaticCString::create("_area_exit_tree"); - _input = StaticCString::create("_input"); _input_event = StaticCString::create("_input_event"); @@ -167,8 +161,7 @@ SceneStringNames::SceneStringNames() { drop_data = StaticCString::create("drop_data"); can_drop_data = StaticCString::create("can_drop_data"); - _im_update = StaticCString::create("_im_update"); - _queue_update = StaticCString::create("_queue_update"); + _im_update = StaticCString::create("_im_update"); // Sprite3D baked_light_changed = StaticCString::create("baked_light_changed"); _baked_light_changed = StaticCString::create("_baked_light_changed"); @@ -200,8 +193,6 @@ SceneStringNames::SceneStringNames() { mesh_materials[i] = "material/" + itos(i); } - _mesh_changed = StaticCString::create("_mesh_changed"); - parameters_base_path = "parameters/"; tracks_changed = "tracks_changed"; diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index eeeaf22b01..7976a2072c 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -33,6 +33,7 @@ #include "core/node_path.h" #include "core/string_name.h" + class SceneStringNames { friend void register_scene_types(); @@ -147,12 +148,6 @@ public: StringName camera_entered; StringName camera_exited; - StringName _body_enter_tree; - StringName _body_exit_tree; - - StringName _area_enter_tree; - StringName _area_exit_tree; - StringName changed; StringName _shader_changed; @@ -179,7 +174,6 @@ public: StringName _get_minimum_size; StringName _im_update; - StringName _queue_update; StringName baked_light_changed; StringName _baked_light_changed; @@ -211,7 +205,6 @@ public: MAX_MATERIALS = 32 }; StringName mesh_materials[MAX_MATERIALS]; - StringName _mesh_changed; }; #endif // SCENE_STRING_NAMES_H |