diff options
Diffstat (limited to 'scene')
105 files changed, 3097 insertions, 1884 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index 177f587f4f..4565462247 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -115,14 +115,17 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &p_property) const { names.sort_custom<StringName::AlphCompare>(); bool current_found = false; + bool is_first_element = true; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (E->prev()) { + for (const StringName &E : names) { + if (!is_first_element) { p_property.hint_string += ","; + } else { + is_first_element = false; } - p_property.hint_string += String(E->get()); - if (animation == E->get()) { + p_property.hint_string += String(E); + if (animation == E) { current_found = true; } } diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index fa49552085..fc019b6cf9 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -185,7 +185,7 @@ void AudioStreamPlayer2D::_update_panning() { } float multiplier = Math::pow(1.0f - dist / max_distance, attenuation); - multiplier *= Math::db2linear(volume_db); //also apply player volume! + multiplier *= Math::db_to_linear(volume_db); //also apply player volume! float pan = relative_to_listener.x / screen_size.x; // Don't let the panning effect extend (too far) beyond the screen. diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 85de1fedee..a79c81e8bd 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -612,6 +612,10 @@ void CollisionObject2D::_bind_methods() { ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject2D::shape_find_owner); GDVIRTUAL_BIND(_input_event, "viewport", "event", "shape_idx"); + GDVIRTUAL_BIND(_mouse_enter); + GDVIRTUAL_BIND(_mouse_exit); + GDVIRTUAL_BIND(_mouse_shape_enter, "shape_idx"); + GDVIRTUAL_BIND(_mouse_shape_exit, "shape_idx"); ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "viewport", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx"))); ADD_SIGNAL(MethodInfo("mouse_entered")); diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h index af216edc98..48ea59e040 100644 --- a/scene/2d/collision_object_2d.h +++ b/scene/2d/collision_object_2d.h @@ -103,6 +103,10 @@ protected: void set_body_mode(PhysicsServer2D::BodyMode p_mode); GDVIRTUAL3(_input_event, Viewport *, Ref<InputEvent>, int) + GDVIRTUAL0(_mouse_enter) + GDVIRTUAL0(_mouse_exit) + GDVIRTUAL1(_mouse_shape_enter, int) + GDVIRTUAL1(_mouse_shape_exit, int) public: void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 8df29851e5..04cd999982 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -239,7 +239,7 @@ TypedArray<String> CollisionPolygon2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject2D>(get_parent())) { - warnings.push_back(RTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidDynamicBody2D, CharacterBody2D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape.")); } int polygon_count = polygon.size(); diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 9c0c26f6d9..cbecf28877 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -172,7 +172,7 @@ TypedArray<String> CollisionShape2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject2D>(get_parent())) { - warnings.push_back(RTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidDynamicBody2D, CharacterBody2D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, CharacterBody2D, etc. to give them a shape.")); } if (!shape.is_valid()) { warnings.push_back(RTR("A shape must be provided for CollisionShape2D to function. Please create a shape resource for it!")); diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 40f74d3f50..1929475c8f 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -32,7 +32,7 @@ #include "core/core_string_names.h" #include "scene/2d/gpu_particles_2d.h" -#include "scene/resources/particles_material.h" +#include "scene/resources/particle_process_material.h" void CPUParticles2D::set_emitting(bool p_emitting) { if (emitting == p_emitting) { @@ -745,12 +745,12 @@ void CPUParticles2D::_particles_process(double p_delta) { p.start_color_rand = Color(1, 1, 1, 1); } - real_t angle1_rad = direction.angle() + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + real_t angle1_rad = direction.angle() + Math::deg_to_rad((Math::randf() * 2.0 - 1.0) * spread); Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad)); p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf()); real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); - p.rotation = Math::deg2rad(base_angle); + p.rotation = Math::deg_to_rad(base_angle); p.custom[0] = 0.0; // unused p.custom[1] = 0.0; // phase [0..1] @@ -890,7 +890,7 @@ void CPUParticles2D::_particles_process(double p_delta) { real_t orbit_amount = tex_orbit_velocity * Math::lerp(parameters_min[PARAM_ORBIT_VELOCITY], parameters_max[PARAM_ORBIT_VELOCITY], rand_from_seed(alt_seed)); if (orbit_amount != 0.0) { real_t ang = orbit_amount * local_delta * Math_TAU; - // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, + // Not sure why the ParticleProcessMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); p.transform[2] -= diff; @@ -912,7 +912,7 @@ void CPUParticles2D::_particles_process(double p_delta) { } real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed)); - p.rotation = Math::deg2rad(base_angle); //angle + p.rotation = Math::deg_to_rad(base_angle); //angle p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); } //apply color @@ -1184,7 +1184,7 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_material(mat); } - Ref<ParticlesMaterial> material = particles->get_process_material(); + Ref<ParticleProcessMaterial> material = particles->get_process_material(); if (material.is_null()) { return; } @@ -1205,14 +1205,14 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_color_initial_ramp(gti->get_gradient()); } - set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); Vector2 rect_extents = Vector2(material->get_emission_box_extents().x, material->get_emission_box_extents().y); set_emission_rect_extents(rect_extents); - Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticlesMaterial::PARAM_SCALE); + Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticleProcessMaterial::PARAM_SCALE); if (scale3D.is_valid()) { split_scale = true; scale_curve_x = scale3D->get_curve_x(); @@ -1222,14 +1222,14 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { set_gravity(gravity); set_lifetime_randomness(material->get_lifetime_randomness()); -#define CONVERT_PARAM(m_param) \ - set_param_min(m_param, material->get_param_min(ParticlesMaterial::m_param)); \ - { \ - Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \ - if (ctex.is_valid()) \ - set_param_curve(m_param, ctex->get_curve()); \ - } \ - set_param_max(m_param, material->get_param_max(ParticlesMaterial::m_param)); +#define CONVERT_PARAM(m_param) \ + set_param_min(m_param, material->get_param_min(ParticleProcessMaterial::m_param)); \ + { \ + Ref<CurveTexture> ctex = material->get_param_texture(ParticleProcessMaterial::m_param); \ + if (ctex.is_valid()) \ + set_param_curve(m_param, ctex->get_curve()); \ + } \ + set_param_max(m_param, material->get_param_max(ParticleProcessMaterial::m_param)); CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY); CONVERT_PARAM(PARAM_ANGULAR_VELOCITY); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index e4354a69e2..65ead7afbc 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -30,7 +30,7 @@ #include "gpu_particles_2d.h" -#include "scene/resources/particles_material.h" +#include "scene/resources/particle_process_material.h" #ifdef TOOLS_ENABLED #include "core/config/engine.h" @@ -123,10 +123,10 @@ void GPUParticles2D::_update_particle_emission_transform() { void GPUParticles2D::set_process_material(const Ref<Material> &p_material) { process_material = p_material; - Ref<ParticlesMaterial> pm = p_material; - if (pm.is_valid() && !pm->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { + Ref<ParticleProcessMaterial> pm = p_material; + if (pm.is_valid() && !pm->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) { // Likely a new (3D) material, modify it to match 2D space - pm->set_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z, true); + pm->set_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z, true); pm->set_gravity(Vector3(0, 98, 0)); } RID material_rid; @@ -308,10 +308,10 @@ TypedArray<String> GPUParticles2D::get_configuration_warnings() const { CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); if (get_material().is_null() || (mat && !mat->get_particles_animation())) { - const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr()); + const ParticleProcessMaterial *process = Object::cast_to<ParticleProcessMaterial>(process_material.ptr()); if (process && - (process->get_param_max(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || - process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { + (process->get_param_max(ParticleProcessMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticleProcessMaterial::PARAM_ANIM_OFFSET) != 0.0 || + process->get_param_texture(ParticleProcessMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticleProcessMaterial::PARAM_ANIM_OFFSET).is_valid())) { warnings.push_back(RTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.")); } } @@ -625,7 +625,7 @@ void GPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_sections", PROPERTY_HINT_RANGE, "2,128,1"), "set_trail_sections", "get_trail_sections"); ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_section_subdivisions", PROPERTY_HINT_RANGE, "1,1024,1"), "set_trail_section_subdivisions", "get_trail_section_subdivisions"); 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_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticleProcessMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Textures", ""); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index c5966bedd2..a592d20cba 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -127,7 +127,7 @@ TypedArray<String> NavigationObstacle2D::get_configuration_warnings() const { } if (Object::cast_to<StaticBody2D>(get_parent())) { - warnings.push_back(RTR("The NavigationObstacle2D is intended for constantly moving bodies like CharacterBody2D or RigidDynamicBody2D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." + warnings.push_back(RTR("The NavigationObstacle2D is intended for constantly moving bodies like CharacterBody2D or RigidBody2D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." "\nNot constantly moving or complete static objects should be captured with a refreshed NavigationPolygon so agents can not only avoid them but also move along those objects outline at high detail")); } diff --git a/scene/2d/physical_bone_2d.cpp b/scene/2d/physical_bone_2d.cpp index 62f4d855ef..e6933b8a40 100644 --- a/scene/2d/physical_bone_2d.cpp +++ b/scene/2d/physical_bone_2d.cpp @@ -35,7 +35,7 @@ void PhysicalBone2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - // Position the RigidDynamicBody in the correct position. + // Position the RigidBody in the correct position. if (follow_bone_when_simulating) { _position_at_bone2d(); } @@ -287,7 +287,7 @@ void PhysicalBone2D::_bind_methods() { } PhysicalBone2D::PhysicalBone2D() { - // Stop the RigidDynamicBody from executing its force integration. + // Stop the RigidBody from executing its force integration. PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), 0); PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), 0); PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BodyMode::BODY_MODE_STATIC); diff --git a/scene/2d/physical_bone_2d.h b/scene/2d/physical_bone_2d.h index 22d329c320..9fbfa04100 100644 --- a/scene/2d/physical_bone_2d.h +++ b/scene/2d/physical_bone_2d.h @@ -36,8 +36,8 @@ class Joint2D; -class PhysicalBone2D : public RigidDynamicBody2D { - GDCLASS(PhysicalBone2D, RigidDynamicBody2D); +class PhysicalBone2D : public RigidBody2D { + GDCLASS(PhysicalBone2D, RigidBody2D); protected: void _notification(int p_what); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a317285a1b..43158344b4 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -325,7 +325,7 @@ AnimatableBody2D::AnimatableBody2D() : StaticBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) { } -void RigidDynamicBody2D::_body_enter_tree(ObjectID p_id) { +void RigidBody2D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -347,7 +347,7 @@ void RigidDynamicBody2D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = false; } -void RigidDynamicBody2D::_body_exit_tree(ObjectID p_id) { +void RigidBody2D::_body_exit_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -368,7 +368,7 @@ void RigidDynamicBody2D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = false; } -void RigidDynamicBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { +void RigidBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -387,8 +387,8 @@ void RigidDynamicBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p //E->value.rc=0; E->value.in_scene = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody2D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody2D::_body_exit_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree).bind(objid)); if (E->value.in_scene) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -416,8 +416,8 @@ void RigidDynamicBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody2D::_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); } @@ -431,19 +431,19 @@ void RigidDynamicBody2D::_body_inout(int p_status, const RID &p_body, ObjectID p } } -struct _RigidDynamicBody2DInOut { +struct _RigidBody2DInOut { RID rid; ObjectID id; int shape = 0; int local_shape = 0; }; -void RigidDynamicBody2D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState2D *p_state) { - RigidDynamicBody2D *body = static_cast<RigidDynamicBody2D *>(p_instance); +void RigidBody2D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState2D *p_state) { + RigidBody2D *body = static_cast<RigidBody2D *>(p_instance); body->_body_state_changed(p_state); } -void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) { +void RigidBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) { set_block_transform_notify(true); // don't want notify (would feedback loop) if (!freeze || freeze_mode != FREEZE_MODE_KINEMATIC) { set_global_transform(p_state->get_transform()); @@ -473,9 +473,9 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) } } - _RigidDynamicBody2DInOut *toadd = (_RigidDynamicBody2DInOut *)alloca(p_state->get_contact_count() * sizeof(_RigidDynamicBody2DInOut)); + _RigidBody2DInOut *toadd = (_RigidBody2DInOut *)alloca(p_state->get_contact_count() * sizeof(_RigidBody2DInOut)); int toadd_count = 0; //state->get_contact_count(); - RigidDynamicBody2D_RemoveAction *toremove = (RigidDynamicBody2D_RemoveAction *)alloca(rc * sizeof(RigidDynamicBody2D_RemoveAction)); + RigidBody2D_RemoveAction *toremove = (RigidBody2D_RemoveAction *)alloca(rc * sizeof(RigidBody2D_RemoveAction)); int toremove_count = 0; //put the ones to add @@ -539,7 +539,7 @@ void RigidDynamicBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) } } -void RigidDynamicBody2D::_apply_body_mode() { +void RigidBody2D::_apply_body_mode() { if (freeze) { switch (freeze_mode) { case FREEZE_MODE_STATIC: { @@ -550,13 +550,13 @@ void RigidDynamicBody2D::_apply_body_mode() { } break; } } else if (lock_rotation) { - set_body_mode(PhysicsServer2D::BODY_MODE_DYNAMIC_LINEAR); + set_body_mode(PhysicsServer2D::BODY_MODE_RIGID_LINEAR); } else { - set_body_mode(PhysicsServer2D::BODY_MODE_DYNAMIC); + set_body_mode(PhysicsServer2D::BODY_MODE_RIGID); } } -void RigidDynamicBody2D::set_lock_rotation_enabled(bool p_lock_rotation) { +void RigidBody2D::set_lock_rotation_enabled(bool p_lock_rotation) { if (p_lock_rotation == lock_rotation) { return; } @@ -565,11 +565,11 @@ void RigidDynamicBody2D::set_lock_rotation_enabled(bool p_lock_rotation) { _apply_body_mode(); } -bool RigidDynamicBody2D::is_lock_rotation_enabled() const { +bool RigidBody2D::is_lock_rotation_enabled() const { return lock_rotation; } -void RigidDynamicBody2D::set_freeze_enabled(bool p_freeze) { +void RigidBody2D::set_freeze_enabled(bool p_freeze) { if (p_freeze == freeze) { return; } @@ -578,11 +578,11 @@ void RigidDynamicBody2D::set_freeze_enabled(bool p_freeze) { _apply_body_mode(); } -bool RigidDynamicBody2D::is_freeze_enabled() const { +bool RigidBody2D::is_freeze_enabled() const { return freeze; } -void RigidDynamicBody2D::set_freeze_mode(FreezeMode p_freeze_mode) { +void RigidBody2D::set_freeze_mode(FreezeMode p_freeze_mode) { if (p_freeze_mode == freeze_mode) { return; } @@ -591,31 +591,31 @@ void RigidDynamicBody2D::set_freeze_mode(FreezeMode p_freeze_mode) { _apply_body_mode(); } -RigidDynamicBody2D::FreezeMode RigidDynamicBody2D::get_freeze_mode() const { +RigidBody2D::FreezeMode RigidBody2D::get_freeze_mode() const { return freeze_mode; } -void RigidDynamicBody2D::set_mass(real_t p_mass) { +void RigidBody2D::set_mass(real_t p_mass) { ERR_FAIL_COND(p_mass <= 0); mass = p_mass; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_MASS, mass); } -real_t RigidDynamicBody2D::get_mass() const { +real_t RigidBody2D::get_mass() const { return mass; } -void RigidDynamicBody2D::set_inertia(real_t p_inertia) { +void RigidBody2D::set_inertia(real_t p_inertia) { ERR_FAIL_COND(p_inertia < 0); inertia = p_inertia; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA, inertia); } -real_t RigidDynamicBody2D::get_inertia() const { +real_t RigidBody2D::get_inertia() const { return inertia; } -void RigidDynamicBody2D::set_center_of_mass_mode(CenterOfMassMode p_mode) { +void RigidBody2D::set_center_of_mass_mode(CenterOfMassMode p_mode) { if (center_of_mass_mode == p_mode) { return; } @@ -637,11 +637,11 @@ void RigidDynamicBody2D::set_center_of_mass_mode(CenterOfMassMode p_mode) { } } -RigidDynamicBody2D::CenterOfMassMode RigidDynamicBody2D::get_center_of_mass_mode() const { +RigidBody2D::CenterOfMassMode RigidBody2D::get_center_of_mass_mode() const { return center_of_mass_mode; } -void RigidDynamicBody2D::set_center_of_mass(const Vector2 &p_center_of_mass) { +void RigidBody2D::set_center_of_mass(const Vector2 &p_center_of_mass) { if (center_of_mass == p_center_of_mass) { return; } @@ -652,102 +652,102 @@ void RigidDynamicBody2D::set_center_of_mass(const Vector2 &p_center_of_mass) { PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_CENTER_OF_MASS, center_of_mass); } -const Vector2 &RigidDynamicBody2D::get_center_of_mass() const { +const Vector2 &RigidBody2D::get_center_of_mass() const { return center_of_mass; } -void RigidDynamicBody2D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { +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, callable_mp(this, &RigidDynamicBody2D::_reload_physics_characteristics))) { - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidDynamicBody2D::_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, callable_mp(this, &RigidDynamicBody2D::_reload_physics_characteristics)); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody2D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } -Ref<PhysicsMaterial> RigidDynamicBody2D::get_physics_material_override() const { +Ref<PhysicsMaterial> RigidBody2D::get_physics_material_override() const { return physics_material_override; } -void RigidDynamicBody2D::set_gravity_scale(real_t p_gravity_scale) { +void RigidBody2D::set_gravity_scale(real_t p_gravity_scale) { gravity_scale = p_gravity_scale; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE, gravity_scale); } -real_t RigidDynamicBody2D::get_gravity_scale() const { +real_t RigidBody2D::get_gravity_scale() const { return gravity_scale; } -void RigidDynamicBody2D::set_linear_damp_mode(DampMode p_mode) { +void RigidBody2D::set_linear_damp_mode(DampMode p_mode) { linear_damp_mode = p_mode; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_LINEAR_DAMP_MODE, linear_damp_mode); } -RigidDynamicBody2D::DampMode RigidDynamicBody2D::get_linear_damp_mode() const { +RigidBody2D::DampMode RigidBody2D::get_linear_damp_mode() const { return linear_damp_mode; } -void RigidDynamicBody2D::set_angular_damp_mode(DampMode p_mode) { +void RigidBody2D::set_angular_damp_mode(DampMode p_mode) { angular_damp_mode = p_mode; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP_MODE, angular_damp_mode); } -RigidDynamicBody2D::DampMode RigidDynamicBody2D::get_angular_damp_mode() const { +RigidBody2D::DampMode RigidBody2D::get_angular_damp_mode() const { return angular_damp_mode; } -void RigidDynamicBody2D::set_linear_damp(real_t p_linear_damp) { +void RigidBody2D::set_linear_damp(real_t p_linear_damp) { ERR_FAIL_COND(p_linear_damp < -1); linear_damp = p_linear_damp; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_LINEAR_DAMP, linear_damp); } -real_t RigidDynamicBody2D::get_linear_damp() const { +real_t RigidBody2D::get_linear_damp() const { return linear_damp; } -void RigidDynamicBody2D::set_angular_damp(real_t p_angular_damp) { +void RigidBody2D::set_angular_damp(real_t p_angular_damp) { ERR_FAIL_COND(p_angular_damp < -1); angular_damp = p_angular_damp; PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP, angular_damp); } -real_t RigidDynamicBody2D::get_angular_damp() const { +real_t RigidBody2D::get_angular_damp() const { return angular_damp; } -void RigidDynamicBody2D::set_axis_velocity(const Vector2 &p_axis) { +void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) { Vector2 axis = p_axis.normalized(); linear_velocity -= axis * axis.dot(linear_velocity); linear_velocity += p_axis; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); } -void RigidDynamicBody2D::set_linear_velocity(const Vector2 &p_velocity) { +void RigidBody2D::set_linear_velocity(const Vector2 &p_velocity) { linear_velocity = p_velocity; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); } -Vector2 RigidDynamicBody2D::get_linear_velocity() const { +Vector2 RigidBody2D::get_linear_velocity() const { return linear_velocity; } -void RigidDynamicBody2D::set_angular_velocity(real_t p_velocity) { +void RigidBody2D::set_angular_velocity(real_t p_velocity) { angular_velocity = p_velocity; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); } -real_t RigidDynamicBody2D::get_angular_velocity() const { +real_t RigidBody2D::get_angular_velocity() const { return angular_velocity; } -void RigidDynamicBody2D::set_use_custom_integrator(bool p_enable) { +void RigidBody2D::set_use_custom_integrator(bool p_enable) { if (custom_integrator == p_enable) { return; } @@ -756,105 +756,105 @@ void RigidDynamicBody2D::set_use_custom_integrator(bool p_enable) { PhysicsServer2D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable); } -bool RigidDynamicBody2D::is_using_custom_integrator() { +bool RigidBody2D::is_using_custom_integrator() { return custom_integrator; } -void RigidDynamicBody2D::set_sleeping(bool p_sleeping) { +void RigidBody2D::set_sleeping(bool p_sleeping) { sleeping = p_sleeping; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_SLEEPING, sleeping); } -void RigidDynamicBody2D::set_can_sleep(bool p_active) { +void RigidBody2D::set_can_sleep(bool p_active) { can_sleep = p_active; PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_CAN_SLEEP, p_active); } -bool RigidDynamicBody2D::is_able_to_sleep() const { +bool RigidBody2D::is_able_to_sleep() const { return can_sleep; } -bool RigidDynamicBody2D::is_sleeping() const { +bool RigidBody2D::is_sleeping() const { return sleeping; } -void RigidDynamicBody2D::set_max_contacts_reported(int p_amount) { +void RigidBody2D::set_max_contacts_reported(int p_amount) { max_contacts_reported = p_amount; PhysicsServer2D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount); } -int RigidDynamicBody2D::get_max_contacts_reported() const { +int RigidBody2D::get_max_contacts_reported() const { return max_contacts_reported; } -int RigidDynamicBody2D::get_contact_count() const { +int RigidBody2D::get_contact_count() const { PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(get_rid()); ERR_FAIL_NULL_V(bs, 0); return bs->get_contact_count(); } -void RigidDynamicBody2D::apply_central_impulse(const Vector2 &p_impulse) { +void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) { PhysicsServer2D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); } -void RigidDynamicBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) { +void RigidBody2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) { PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position); } -void RigidDynamicBody2D::apply_torque_impulse(real_t p_torque) { +void RigidBody2D::apply_torque_impulse(real_t p_torque) { PhysicsServer2D::get_singleton()->body_apply_torque_impulse(get_rid(), p_torque); } -void RigidDynamicBody2D::apply_central_force(const Vector2 &p_force) { +void RigidBody2D::apply_central_force(const Vector2 &p_force) { PhysicsServer2D::get_singleton()->body_apply_central_force(get_rid(), p_force); } -void RigidDynamicBody2D::apply_force(const Vector2 &p_force, const Vector2 &p_position) { +void RigidBody2D::apply_force(const Vector2 &p_force, const Vector2 &p_position) { PhysicsServer2D::get_singleton()->body_apply_force(get_rid(), p_force, p_position); } -void RigidDynamicBody2D::apply_torque(real_t p_torque) { +void RigidBody2D::apply_torque(real_t p_torque) { PhysicsServer2D::get_singleton()->body_apply_torque(get_rid(), p_torque); } -void RigidDynamicBody2D::add_constant_central_force(const Vector2 &p_force) { +void RigidBody2D::add_constant_central_force(const Vector2 &p_force) { PhysicsServer2D::get_singleton()->body_add_constant_central_force(get_rid(), p_force); } -void RigidDynamicBody2D::add_constant_force(const Vector2 &p_force, const Vector2 &p_position) { +void RigidBody2D::add_constant_force(const Vector2 &p_force, const Vector2 &p_position) { PhysicsServer2D::get_singleton()->body_add_constant_force(get_rid(), p_force, p_position); } -void RigidDynamicBody2D::add_constant_torque(const real_t p_torque) { +void RigidBody2D::add_constant_torque(const real_t p_torque) { PhysicsServer2D::get_singleton()->body_add_constant_torque(get_rid(), p_torque); } -void RigidDynamicBody2D::set_constant_force(const Vector2 &p_force) { +void RigidBody2D::set_constant_force(const Vector2 &p_force) { PhysicsServer2D::get_singleton()->body_set_constant_force(get_rid(), p_force); } -Vector2 RigidDynamicBody2D::get_constant_force() const { +Vector2 RigidBody2D::get_constant_force() const { return PhysicsServer2D::get_singleton()->body_get_constant_force(get_rid()); } -void RigidDynamicBody2D::set_constant_torque(real_t p_torque) { +void RigidBody2D::set_constant_torque(real_t p_torque) { PhysicsServer2D::get_singleton()->body_set_constant_torque(get_rid(), p_torque); } -real_t RigidDynamicBody2D::get_constant_torque() const { +real_t RigidBody2D::get_constant_torque() const { return PhysicsServer2D::get_singleton()->body_get_constant_torque(get_rid()); } -void RigidDynamicBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) { +void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) { ccd_mode = p_mode; PhysicsServer2D::get_singleton()->body_set_continuous_collision_detection_mode(get_rid(), PhysicsServer2D::CCDMode(p_mode)); } -RigidDynamicBody2D::CCDMode RigidDynamicBody2D::get_continuous_collision_detection_mode() const { +RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() const { return ccd_mode; } -TypedArray<Node2D> RigidDynamicBody2D::get_colliding_bodies() const { +TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, TypedArray<Node2D>()); TypedArray<Node2D> ret; @@ -872,7 +872,7 @@ TypedArray<Node2D> RigidDynamicBody2D::get_colliding_bodies() const { return ret; } -void RigidDynamicBody2D::set_contact_monitor(bool p_enabled) { +void RigidBody2D::set_contact_monitor(bool p_enabled) { if (p_enabled == is_contact_monitor_enabled()) { return; } @@ -886,8 +886,8 @@ void RigidDynamicBody2D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody2D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody2D::_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)); } } @@ -899,11 +899,11 @@ void RigidDynamicBody2D::set_contact_monitor(bool p_enabled) { } } -bool RigidDynamicBody2D::is_contact_monitor_enabled() const { +bool RigidBody2D::is_contact_monitor_enabled() const { return contact_monitor != nullptr; } -void RigidDynamicBody2D::_notification(int p_what) { +void RigidBody2D::_notification(int p_what) { #ifdef TOOLS_ENABLED switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -921,103 +921,103 @@ void RigidDynamicBody2D::_notification(int p_what) { #endif } -TypedArray<String> RigidDynamicBody2D::get_configuration_warnings() const { +TypedArray<String> RigidBody2D::get_configuration_warnings() const { Transform2D t = get_transform(); TypedArray<String> warnings = CollisionObject2D::get_configuration_warnings(); if (ABS(t.columns[0].length() - 1.0) > 0.05 || ABS(t.columns[1].length() - 1.0) > 0.05) { - warnings.push_back(RTR("Size changes to RigidDynamicBody2D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + warnings.push_back(RTR("Size changes to RigidBody2D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; } -void RigidDynamicBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidDynamicBody2D::set_mass); - ClassDB::bind_method(D_METHOD("get_mass"), &RigidDynamicBody2D::get_mass); +void RigidBody2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidBody2D::set_mass); + ClassDB::bind_method(D_METHOD("get_mass"), &RigidBody2D::get_mass); - ClassDB::bind_method(D_METHOD("get_inertia"), &RigidDynamicBody2D::get_inertia); - ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &RigidDynamicBody2D::set_inertia); + ClassDB::bind_method(D_METHOD("get_inertia"), &RigidBody2D::get_inertia); + ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &RigidBody2D::set_inertia); - ClassDB::bind_method(D_METHOD("set_center_of_mass_mode", "mode"), &RigidDynamicBody2D::set_center_of_mass_mode); - ClassDB::bind_method(D_METHOD("get_center_of_mass_mode"), &RigidDynamicBody2D::get_center_of_mass_mode); + ClassDB::bind_method(D_METHOD("set_center_of_mass_mode", "mode"), &RigidBody2D::set_center_of_mass_mode); + ClassDB::bind_method(D_METHOD("get_center_of_mass_mode"), &RigidBody2D::get_center_of_mass_mode); - ClassDB::bind_method(D_METHOD("set_center_of_mass", "center_of_mass"), &RigidDynamicBody2D::set_center_of_mass); - ClassDB::bind_method(D_METHOD("get_center_of_mass"), &RigidDynamicBody2D::get_center_of_mass); + ClassDB::bind_method(D_METHOD("set_center_of_mass", "center_of_mass"), &RigidBody2D::set_center_of_mass); + ClassDB::bind_method(D_METHOD("get_center_of_mass"), &RigidBody2D::get_center_of_mass); - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidDynamicBody2D::set_physics_material_override); - ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidDynamicBody2D::get_physics_material_override); + 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("set_gravity_scale", "gravity_scale"), &RigidDynamicBody2D::set_gravity_scale); - ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidDynamicBody2D::get_gravity_scale); + 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); - ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidDynamicBody2D::set_linear_damp_mode); - ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidDynamicBody2D::get_linear_damp_mode); + ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidBody2D::set_linear_damp_mode); + ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidBody2D::get_linear_damp_mode); - ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidDynamicBody2D::set_angular_damp_mode); - ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidDynamicBody2D::get_angular_damp_mode); + ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidBody2D::set_angular_damp_mode); + ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidBody2D::get_angular_damp_mode); - ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidDynamicBody2D::set_linear_damp); - ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidDynamicBody2D::get_linear_damp); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidBody2D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidBody2D::get_linear_damp); - ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &RigidDynamicBody2D::set_angular_damp); - ClassDB::bind_method(D_METHOD("get_angular_damp"), &RigidDynamicBody2D::get_angular_damp); + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &RigidBody2D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &RigidBody2D::get_angular_damp); - ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidDynamicBody2D::set_linear_velocity); - ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidDynamicBody2D::get_linear_velocity); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidBody2D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidBody2D::get_linear_velocity); - ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidDynamicBody2D::set_angular_velocity); - ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidDynamicBody2D::get_angular_velocity); + ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidBody2D::set_angular_velocity); + ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidBody2D::get_angular_velocity); - ClassDB::bind_method(D_METHOD("set_max_contacts_reported", "amount"), &RigidDynamicBody2D::set_max_contacts_reported); - ClassDB::bind_method(D_METHOD("get_max_contacts_reported"), &RigidDynamicBody2D::get_max_contacts_reported); - ClassDB::bind_method(D_METHOD("get_contact_count"), &RigidDynamicBody2D::get_contact_count); + ClassDB::bind_method(D_METHOD("set_max_contacts_reported", "amount"), &RigidBody2D::set_max_contacts_reported); + ClassDB::bind_method(D_METHOD("get_max_contacts_reported"), &RigidBody2D::get_max_contacts_reported); + ClassDB::bind_method(D_METHOD("get_contact_count"), &RigidBody2D::get_contact_count); - ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &RigidDynamicBody2D::set_use_custom_integrator); - ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &RigidDynamicBody2D::is_using_custom_integrator); + ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &RigidBody2D::set_use_custom_integrator); + ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &RigidBody2D::is_using_custom_integrator); - ClassDB::bind_method(D_METHOD("set_contact_monitor", "enabled"), &RigidDynamicBody2D::set_contact_monitor); - ClassDB::bind_method(D_METHOD("is_contact_monitor_enabled"), &RigidDynamicBody2D::is_contact_monitor_enabled); + ClassDB::bind_method(D_METHOD("set_contact_monitor", "enabled"), &RigidBody2D::set_contact_monitor); + ClassDB::bind_method(D_METHOD("is_contact_monitor_enabled"), &RigidBody2D::is_contact_monitor_enabled); - ClassDB::bind_method(D_METHOD("set_continuous_collision_detection_mode", "mode"), &RigidDynamicBody2D::set_continuous_collision_detection_mode); - ClassDB::bind_method(D_METHOD("get_continuous_collision_detection_mode"), &RigidDynamicBody2D::get_continuous_collision_detection_mode); + ClassDB::bind_method(D_METHOD("set_continuous_collision_detection_mode", "mode"), &RigidBody2D::set_continuous_collision_detection_mode); + ClassDB::bind_method(D_METHOD("get_continuous_collision_detection_mode"), &RigidBody2D::get_continuous_collision_detection_mode); - ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidDynamicBody2D::set_axis_velocity); - ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidDynamicBody2D::apply_central_impulse, Vector2()); - ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidDynamicBody2D::apply_impulse, Vector2()); - ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidDynamicBody2D::apply_torque_impulse); + ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody2D::set_axis_velocity); + ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody2D::apply_central_impulse, Vector2()); + ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidBody2D::apply_impulse, Vector2()); + ClassDB::bind_method(D_METHOD("apply_torque_impulse", "torque"), &RigidBody2D::apply_torque_impulse); - ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidDynamicBody2D::apply_central_force); - ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidDynamicBody2D::apply_force, Vector2()); - ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidDynamicBody2D::apply_torque); + ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidBody2D::apply_central_force); + ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidBody2D::apply_force, Vector2()); + ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidBody2D::apply_torque); - ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidDynamicBody2D::add_constant_central_force); - ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidDynamicBody2D::add_constant_force, Vector2()); - ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidDynamicBody2D::add_constant_torque); + ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidBody2D::add_constant_central_force); + ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidBody2D::add_constant_force, Vector2()); + ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidBody2D::add_constant_torque); - ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidDynamicBody2D::set_constant_force); - ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidDynamicBody2D::get_constant_force); + ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidBody2D::set_constant_force); + ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidBody2D::get_constant_force); - ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidDynamicBody2D::set_constant_torque); - ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidDynamicBody2D::get_constant_torque); + ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidBody2D::set_constant_torque); + ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidBody2D::get_constant_torque); - ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidDynamicBody2D::set_sleeping); - ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidDynamicBody2D::is_sleeping); + ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody2D::set_sleeping); + ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidBody2D::is_sleeping); - ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidDynamicBody2D::set_can_sleep); - ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidDynamicBody2D::is_able_to_sleep); + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody2D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody2D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_lock_rotation_enabled", "lock_rotation"), &RigidDynamicBody2D::set_lock_rotation_enabled); - ClassDB::bind_method(D_METHOD("is_lock_rotation_enabled"), &RigidDynamicBody2D::is_lock_rotation_enabled); + ClassDB::bind_method(D_METHOD("set_lock_rotation_enabled", "lock_rotation"), &RigidBody2D::set_lock_rotation_enabled); + ClassDB::bind_method(D_METHOD("is_lock_rotation_enabled"), &RigidBody2D::is_lock_rotation_enabled); - ClassDB::bind_method(D_METHOD("set_freeze_enabled", "freeze_mode"), &RigidDynamicBody2D::set_freeze_enabled); - ClassDB::bind_method(D_METHOD("is_freeze_enabled"), &RigidDynamicBody2D::is_freeze_enabled); + ClassDB::bind_method(D_METHOD("set_freeze_enabled", "freeze_mode"), &RigidBody2D::set_freeze_enabled); + ClassDB::bind_method(D_METHOD("is_freeze_enabled"), &RigidBody2D::is_freeze_enabled); - ClassDB::bind_method(D_METHOD("set_freeze_mode", "freeze_mode"), &RigidDynamicBody2D::set_freeze_mode); - ClassDB::bind_method(D_METHOD("get_freeze_mode"), &RigidDynamicBody2D::get_freeze_mode); + ClassDB::bind_method(D_METHOD("set_freeze_mode", "freeze_mode"), &RigidBody2D::set_freeze_mode); + ClassDB::bind_method(D_METHOD("get_freeze_mode"), &RigidBody2D::get_freeze_mode); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidDynamicBody2D::get_colliding_bodies); + ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies); GDVIRTUAL_BIND(_integrate_forces, "state"); @@ -1069,7 +1069,7 @@ void RigidDynamicBody2D::_bind_methods() { BIND_ENUM_CONSTANT(CCD_MODE_CAST_SHAPE); } -void RigidDynamicBody2D::_validate_property(PropertyInfo &p_property) const { +void RigidBody2D::_validate_property(PropertyInfo &p_property) const { if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) { if (p_property.name == "center_of_mass") { p_property.usage = PROPERTY_USAGE_NO_EDITOR; @@ -1077,18 +1077,18 @@ void RigidDynamicBody2D::_validate_property(PropertyInfo &p_property) const { } } -RigidDynamicBody2D::RigidDynamicBody2D() : - PhysicsBody2D(PhysicsServer2D::BODY_MODE_DYNAMIC) { +RigidBody2D::RigidBody2D() : + PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) { PhysicsServer2D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); } -RigidDynamicBody2D::~RigidDynamicBody2D() { +RigidBody2D::~RigidBody2D() { if (contact_monitor) { memdelete(contact_monitor); } } -void RigidDynamicBody2D::_reload_physics_characteristics() { +void RigidBody2D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_BOUNCE, 0); PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_FRICTION, 1); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index fe64c087c6..eaba9aadad 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -113,8 +113,8 @@ private: bool is_sync_to_physics_enabled() const; }; -class RigidDynamicBody2D : public PhysicsBody2D { - GDCLASS(RigidDynamicBody2D, PhysicsBody2D); +class RigidBody2D : public PhysicsBody2D { + GDCLASS(RigidBody2D, PhysicsBody2D); public: enum FreezeMode { @@ -186,7 +186,7 @@ private: local_shape = p_ls; } }; - struct RigidDynamicBody2D_RemoveAction { + struct RigidBody2D_RemoveAction { RID rid; ObjectID body_id; ShapePair pair; @@ -311,17 +311,17 @@ public: virtual TypedArray<String> get_configuration_warnings() const override; - RigidDynamicBody2D(); - ~RigidDynamicBody2D(); + RigidBody2D(); + ~RigidBody2D(); private: void _reload_physics_characteristics(); }; -VARIANT_ENUM_CAST(RigidDynamicBody2D::FreezeMode); -VARIANT_ENUM_CAST(RigidDynamicBody2D::CenterOfMassMode); -VARIANT_ENUM_CAST(RigidDynamicBody2D::DampMode); -VARIANT_ENUM_CAST(RigidDynamicBody2D::CCDMode); +VARIANT_ENUM_CAST(RigidBody2D::FreezeMode); +VARIANT_ENUM_CAST(RigidBody2D::CenterOfMassMode); +VARIANT_ENUM_CAST(RigidBody2D::DampMode); +VARIANT_ENUM_CAST(RigidBody2D::CCDMode); class CharacterBody2D : public PhysicsBody2D { GDCLASS(CharacterBody2D, PhysicsBody2D); @@ -373,9 +373,9 @@ private: bool slide_on_ceiling = true; int max_slides = 4; int platform_layer = 0; - real_t floor_max_angle = Math::deg2rad((real_t)45.0); + real_t floor_max_angle = Math::deg_to_rad((real_t)45.0); real_t floor_snap_length = 1; - real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); + real_t wall_min_slide_angle = Math::deg_to_rad((real_t)15.0); Vector2 up_direction = Vector2(0.0, -1.0); uint32_t platform_floor_layers = UINT32_MAX; uint32_t platform_wall_layers = 0; diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index cbacb7f579..13a32fbfd4 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -44,7 +44,7 @@ bool Bone2D::_set(const StringName &p_path, const Variant &p_value) { } else if (path.begins_with("length")) { set_length(p_value); } else if (path.begins_with("bone_angle")) { - set_bone_angle(Math::deg2rad(real_t(p_value))); + set_bone_angle(Math::deg_to_rad(real_t(p_value))); } else if (path.begins_with("default_length")) { set_length(p_value); } @@ -66,7 +66,7 @@ bool Bone2D::_get(const StringName &p_path, Variant &r_ret) const { } else if (path.begins_with("length")) { r_ret = get_length(); } else if (path.begins_with("bone_angle")) { - r_ret = Math::rad2deg(get_bone_angle()); + r_ret = Math::rad_to_deg(get_bone_angle()); } else if (path.begins_with("default_length")) { r_ret = get_length(); } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 13bdd2bd5f..129cce93fa 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -553,7 +553,7 @@ int TileMap::get_layers_count() const { void TileMap::add_layer(int p_to_pos) { if (p_to_pos < 0) { - p_to_pos = layers.size(); + p_to_pos = layers.size() + p_to_pos + 1; } ERR_FAIL_INDEX(p_to_pos, (int)layers.size() + 1); @@ -612,6 +612,9 @@ void TileMap::remove_layer(int p_layer) { } void TileMap::set_layer_name(int p_layer, String p_name) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].name = p_name; emit_signal(SNAME("changed")); @@ -623,6 +626,9 @@ String TileMap::get_layer_name(int p_layer) const { } void TileMap::set_layer_enabled(int p_layer, bool p_enabled) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].enabled = p_enabled; _clear_layer_internals(p_layer); @@ -638,6 +644,9 @@ bool TileMap::is_layer_enabled(int p_layer) const { } void TileMap::set_layer_modulate(int p_layer, Color p_modulate) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].modulate = p_modulate; _clear_layer_internals(p_layer); @@ -651,6 +660,9 @@ Color TileMap::get_layer_modulate(int p_layer) const { } void TileMap::set_layer_y_sort_enabled(int p_layer, bool p_y_sort_enabled) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].y_sort_enabled = p_y_sort_enabled; _clear_layer_internals(p_layer); @@ -666,6 +678,9 @@ bool TileMap::is_layer_y_sort_enabled(int p_layer) const { } void TileMap::set_layer_y_sort_origin(int p_layer, int p_y_sort_origin) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].y_sort_origin = p_y_sort_origin; _clear_layer_internals(p_layer); @@ -679,6 +694,9 @@ int TileMap::get_layer_y_sort_origin(int p_layer) const { } void TileMap::set_layer_z_index(int p_layer, int p_z_index) { + if (p_layer < 0) { + p_layer = layers.size() + p_layer; + } ERR_FAIL_INDEX(p_layer, (int)layers.size()); layers[p_layer].z_index = p_z_index; _clear_layer_internals(p_layer); @@ -3839,7 +3857,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("get_layer_name", "layer"), &TileMap::get_layer_name); ClassDB::bind_method(D_METHOD("set_layer_enabled", "layer", "enabled"), &TileMap::set_layer_enabled); ClassDB::bind_method(D_METHOD("is_layer_enabled", "layer"), &TileMap::is_layer_enabled); - ClassDB::bind_method(D_METHOD("set_layer_modulate", "layer", "enabled"), &TileMap::set_layer_modulate); + ClassDB::bind_method(D_METHOD("set_layer_modulate", "layer", "modulate"), &TileMap::set_layer_modulate); ClassDB::bind_method(D_METHOD("get_layer_modulate", "layer"), &TileMap::get_layer_modulate); ClassDB::bind_method(D_METHOD("set_layer_y_sort_enabled", "layer", "y_sort_enabled"), &TileMap::set_layer_y_sort_enabled); ClassDB::bind_method(D_METHOD("is_layer_y_sort_enabled", "layer"), &TileMap::is_layer_y_sort_enabled); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 93e91f9b5b..0e7b71f74a 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -149,7 +149,7 @@ void AudioStreamPlayer3D::_calc_reverb_vol(Area3D *area, Vector3 listener_area_p if (uniformity > 0.0) { float distance = listener_area_pos.length(); - float attenuation = Math::db2linear(_get_attenuation_db(distance)); + float attenuation = Math::db_to_linear(_get_attenuation_db(distance)); // Determine the fraction of sound that would come from each speaker if they were all driven uniformly. float center_val[3] = { 0.5f, 0.25f, 0.16666f }; @@ -213,12 +213,12 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { float att = 0; switch (attenuation_model) { case ATTENUATION_INVERSE_DISTANCE: { - att = Math::linear2db(1.0 / ((p_distance / unit_size) + CMP_EPSILON)); + att = Math::linear_to_db(1.0 / ((p_distance / unit_size) + CMP_EPSILON)); } break; case ATTENUATION_INVERSE_SQUARE_DISTANCE: { float d = (p_distance / unit_size); d *= d; - att = Math::linear2db(1.0 / (d + CMP_EPSILON)); + att = Math::linear_to_db(1.0 / (d + CMP_EPSILON)); } break; case ATTENUATION_LOGARITHMIC: { att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON); @@ -443,7 +443,7 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() { } } - float multiplier = Math::db2linear(_get_attenuation_db(dist)); + float multiplier = Math::db_to_linear(_get_attenuation_db(dist)); if (max_distance > 0) { multiplier *= MAX(0, 1.0 - (dist / max_distance)); } @@ -453,13 +453,13 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() { if (emission_angle_enabled) { Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; float c = listenertopos.normalized().dot(get_global_transform().basis.get_column(2).normalized()); //it's z negative - float angle = Math::rad2deg(Math::acos(c)); + float angle = Math::rad_to_deg(Math::acos(c)); if (angle > emission_angle) { db_att -= -emission_angle_filter_attenuation_db; } } - linear_attenuation = Math::db2linear(db_att); + linear_attenuation = Math::db_to_linear(db_att); for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { AudioServer::get_singleton()->set_playback_highshelf_params(playback, linear_attenuation, attenuation_filter_cutoff_hz); } diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 48eb2a66b1..f5e3e8b015 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -469,6 +469,8 @@ void CollisionObject3D::_bind_methods() { ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner); GDVIRTUAL_BIND(_input_event, "camera", "event", "position", "normal", "shape_idx"); + GDVIRTUAL_BIND(_mouse_enter); + GDVIRTUAL_BIND(_mouse_exit); ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "position"), PropertyInfo(Variant::VECTOR3, "normal"), PropertyInfo(Variant::INT, "shape_idx"))); ADD_SIGNAL(MethodInfo("mouse_entered")); diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 51c31da79f..c638be9d90 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -113,6 +113,8 @@ protected: bool is_only_update_transform_changes_enabled() const; GDVIRTUAL5(_input_event, Camera3D *, Ref<InputEvent>, Vector3, Vector3, int) + GDVIRTUAL0(_mouse_enter) + GDVIRTUAL0(_mouse_exit) public: void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index bd6a70e566..90099d787b 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -171,7 +171,7 @@ TypedArray<String> CollisionPolygon3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(RTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (polygon.is_empty()) { diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 759997de7b..a9bc28b464 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -118,7 +118,7 @@ TypedArray<String> CollisionShape3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(RTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (!shape.is_valid()) { @@ -126,9 +126,9 @@ TypedArray<String> CollisionShape3D::get_configuration_warnings() const { } if (shape.is_valid() && - Object::cast_to<RigidDynamicBody3D>(get_parent()) && + Object::cast_to<RigidBody3D>(get_parent()) && Object::cast_to<ConcavePolygonShape3D>(*shape)) { - warnings.push_back(RTR("ConcavePolygonShape3D doesn't support RigidDynamicBody3D in another mode than static.")); + warnings.push_back(RTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static.")); } return warnings; diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index a79fd15b1a..9dc61b35af 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -33,7 +33,7 @@ #include "scene/3d/camera_3d.h" #include "scene/3d/gpu_particles_3d.h" #include "scene/main/viewport.h" -#include "scene/resources/particles_material.h" +#include "scene/resources/particle_process_material.h" AABB CPUParticles3D::get_aabb() const { return AABB(); @@ -766,13 +766,13 @@ void CPUParticles3D::_particles_process(double p_delta) { } if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { - real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread); + real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg_to_rad((Math::randf() * 2.0 - 1.0) * spread); Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0); p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], (real_t)Math::randf()); } else { //initiate velocity spread in 3D - real_t angle1_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread); - real_t angle2_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * ((real_t)1.0 - flatness) * spread); + real_t angle1_rad = Math::deg_to_rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread); + real_t angle2_rad = Math::deg_to_rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * ((real_t)1.0 - flatness) * spread); Vector3 direction_xz = Vector3(Math::sin(angle1_rad), 0, Math::cos(angle1_rad)); Vector3 direction_yz = Vector3(0, Math::sin(angle2_rad), Math::cos(angle2_rad)); @@ -796,7 +796,7 @@ void CPUParticles3D::_particles_process(double p_delta) { } real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); - p.custom[0] = Math::deg2rad(base_angle); //angle + p.custom[0] = Math::deg_to_rad(base_angle); //angle p.custom[1] = 0.0; //phase p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand); //animation offset (0-1) p.transform = Transform3D(); @@ -983,7 +983,7 @@ void CPUParticles3D::_particles_process(double p_delta) { real_t orbit_amount = tex_orbit_velocity * Math::lerp(parameters_min[PARAM_ORBIT_VELOCITY], parameters_max[PARAM_ORBIT_VELOCITY], rand_from_seed(alt_seed)); if (orbit_amount != 0.0) { real_t ang = orbit_amount * local_delta * Math_TAU; - // Not sure why the ParticlesMaterial code uses a clockwise rotation matrix, + // Not sure why the ParticleProcessMaterial code uses a clockwise rotation matrix, // but we use -ang here to reproduce its behavior. Transform2D rot = Transform2D(-ang, Vector2()); Vector2 rotv = rot.basis_xform(Vector2(diff.x, diff.y)); @@ -1007,7 +1007,7 @@ void CPUParticles3D::_particles_process(double p_delta) { } real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand); base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed)); - p.custom[0] = Math::deg2rad(base_angle); //angle + p.custom[0] = Math::deg_to_rad(base_angle); //angle p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle } //apply color @@ -1343,7 +1343,7 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_draw_order(DrawOrder(particles->get_draw_order())); set_mesh(particles->get_draw_pass_mesh(0)); - Ref<ParticlesMaterial> material = particles->get_process_material(); + Ref<ParticleProcessMaterial> material = particles->get_process_material(); if (material.is_null()) { return; } @@ -1364,14 +1364,14 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_color_initial_ramp(gti->get_gradient()); } - set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); - set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_ROTATE_Y)); - set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticlesMaterial::PARTICLE_FLAG_DISABLE_Z)); + set_particle_flag(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY)); + set_particle_flag(PARTICLE_FLAG_ROTATE_Y, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_ROTATE_Y)); + set_particle_flag(PARTICLE_FLAG_DISABLE_Z, material->get_particle_flag(ParticleProcessMaterial::PARTICLE_FLAG_DISABLE_Z)); set_emission_shape(EmissionShape(material->get_emission_shape())); set_emission_sphere_radius(material->get_emission_sphere_radius()); set_emission_box_extents(material->get_emission_box_extents()); - Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticlesMaterial::PARAM_SCALE); + Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticleProcessMaterial::PARAM_SCALE); if (scale3D.is_valid()) { split_scale = true; scale_curve_x = scale3D->get_curve_x(); @@ -1382,14 +1382,14 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) { set_gravity(material->get_gravity()); set_lifetime_randomness(material->get_lifetime_randomness()); -#define CONVERT_PARAM(m_param) \ - set_param_min(m_param, material->get_param_min(ParticlesMaterial::m_param)); \ - { \ - Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \ - if (ctex.is_valid()) \ - set_param_curve(m_param, ctex->get_curve()); \ - } \ - set_param_max(m_param, material->get_param_max(ParticlesMaterial::m_param)); +#define CONVERT_PARAM(m_param) \ + set_param_min(m_param, material->get_param_min(ParticleProcessMaterial::m_param)); \ + { \ + Ref<CurveTexture> ctex = material->get_param_texture(ParticleProcessMaterial::m_param); \ + if (ctex.is_valid()) \ + set_param_curve(m_param, ctex->get_curve()); \ + } \ + set_param_max(m_param, material->get_param_max(ParticleProcessMaterial::m_param)); CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY); CONVERT_PARAM(PARAM_ANGULAR_VELOCITY); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index b46e6a8b71..bd63939d74 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -30,7 +30,7 @@ #include "gpu_particles_3d.h" -#include "scene/resources/particles_material.h" +#include "scene/resources/particle_process_material.h" AABB GPUParticles3D::get_aabb() const { return AABB(); @@ -306,10 +306,10 @@ TypedArray<String> GPUParticles3D::get_configuration_warnings() const { if (process_material.is_null()) { warnings.push_back(RTR("A material to process the particles is not assigned, so no behavior is imprinted.")); } else { - const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr()); + const ParticleProcessMaterial *process = Object::cast_to<ParticleProcessMaterial>(process_material.ptr()); if (!anim_material_found && process && - (process->get_param_max(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || - process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { + (process->get_param_max(ParticleProcessMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticleProcessMaterial::PARAM_ANIM_OFFSET) != 0.0 || + process->get_param_texture(ParticleProcessMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticleProcessMaterial::PARAM_ANIM_OFFSET).is_valid())) { warnings.push_back(RTR("Particles animation requires the usage of a BaseMaterial3D whose Billboard Mode is set to \"Particle Billboard\".")); } } @@ -585,7 +585,7 @@ void GPUParticles3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trail_enabled"), "set_trail_enabled", "is_trail_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_length_secs", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_trail_length", "get_trail_length"); ADD_GROUP("Process Material", ""); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticlesMaterial"), "set_process_material", "get_process_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticleProcessMaterial"), "set_process_material", "get_process_material"); ADD_GROUP("Draw Passes", "draw_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_passes", PROPERTY_HINT_RANGE, "0," + itos(MAX_DRAW_PASSES) + ",1"), "set_draw_passes", "get_draw_passes"); for (int i = 0; i < MAX_DRAW_PASSES; i++) { diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 35036b70d8..e4a7cf6ee5 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -31,8 +31,10 @@ #include "label_3d.h" #include "core/core_string_names.h" +#include "scene/main/viewport.h" #include "scene/resources/theme.h" #include "scene/scene_string_names.h" +#include "scene/theme/theme_db.h" void Label3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &Label3D::set_horizontal_alignment); @@ -184,6 +186,14 @@ void Label3D::_notification(int p_what) { if (!pending_update) { _im_update(); } + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->connect("size_changed", callable_mp(this, &Label3D::_font_changed)); + } break; + case NOTIFICATION_EXIT_TREE: { + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->disconnect("size_changed", callable_mp(this, &Label3D::_font_changed)); } break; case NOTIFICATION_TRANSLATION_CHANGED: { String new_text = tr(text); @@ -725,13 +735,13 @@ Ref<Font> Label3D::_get_font_or_default() const { } // Check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { List<StringName> theme_types; - Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed")); @@ -744,11 +754,11 @@ Ref<Font> Label3D::_get_font_or_default() const { // Lastly, fall back on the items defined in the default Theme, if they exist. { List<StringName> theme_types; - Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed")); @@ -759,7 +769,7 @@ Ref<Font> Label3D::_get_font_or_default() const { } // If they don't exist, use any type to return the default/empty value. - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed")); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 0581544e07..8d96d13f0c 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -149,7 +149,7 @@ AABB Light3D::get_aabb() const { } else if (type == RenderingServer::LIGHT_SPOT) { real_t len = param[PARAM_RANGE]; - real_t size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len; + real_t size = Math::tan(Math::deg_to_rad(param[PARAM_SPOT_ANGLE])) * len; return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); } diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index ef9e191f69..953e52e591 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -133,7 +133,7 @@ TypedArray<String> NavigationObstacle3D::get_configuration_warnings() const { } if (Object::cast_to<StaticBody3D>(get_parent())) { - warnings.push_back(RTR("The NavigationObstacle3D is intended for constantly moving bodies like CharacterBody3D or RigidDynamicBody3D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." + warnings.push_back(RTR("The NavigationObstacle3D is intended for constantly moving bodies like CharacterBody3D or RigidBody3D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." "\nNot constantly moving or complete static objects should be (re)baked to a NavigationMesh so agents can not only avoid them but also move along those objects outline at high detail")); } diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index c690b5d6ff..5534bc28f1 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -376,7 +376,7 @@ AnimatableBody3D::AnimatableBody3D() : PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); } -void RigidDynamicBody3D::_body_enter_tree(ObjectID p_id) { +void RigidBody3D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -399,7 +399,7 @@ void RigidDynamicBody3D::_body_enter_tree(ObjectID p_id) { contact_monitor->locked = false; } -void RigidDynamicBody3D::_body_exit_tree(ObjectID p_id) { +void RigidBody3D::_body_exit_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); ERR_FAIL_COND(!node); @@ -420,7 +420,7 @@ void RigidDynamicBody3D::_body_exit_tree(ObjectID p_id) { contact_monitor->locked = false; } -void RigidDynamicBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { +void RigidBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_local_shape) { bool body_in = p_status == 1; ObjectID objid = p_instance; @@ -439,8 +439,8 @@ void RigidDynamicBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p //E->value.rc=0; E->value.in_tree = node && node->is_inside_tree(); if (node) { - node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody3D::_body_enter_tree).bind(objid)); - node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody3D::_body_exit_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree).bind(objid)); + node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree).bind(objid)); if (E->value.in_tree) { emit_signal(SceneStringNames::get_singleton()->body_entered, node); } @@ -466,8 +466,8 @@ void RigidDynamicBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p if (E->value.shapes.is_empty()) { if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody3D::_body_exit_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); if (in_tree) { emit_signal(SceneStringNames::get_singleton()->body_exited, node); } @@ -481,19 +481,19 @@ void RigidDynamicBody3D::_body_inout(int p_status, const RID &p_body, ObjectID p } } -struct _RigidDynamicBodyInOut { +struct _RigidBodyInOut { RID rid; ObjectID id; int shape = 0; int local_shape = 0; }; -void RigidDynamicBody3D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state) { - RigidDynamicBody3D *body = (RigidDynamicBody3D *)p_instance; +void RigidBody3D::_body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state) { + RigidBody3D *body = (RigidBody3D *)p_instance; body->_body_state_changed(p_state); } -void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { +void RigidBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { set_ignore_transform_notification(true); set_global_transform(p_state->get_transform()); @@ -524,9 +524,9 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) } } - _RigidDynamicBodyInOut *toadd = (_RigidDynamicBodyInOut *)alloca(p_state->get_contact_count() * sizeof(_RigidDynamicBodyInOut)); + _RigidBodyInOut *toadd = (_RigidBodyInOut *)alloca(p_state->get_contact_count() * sizeof(_RigidBodyInOut)); int toadd_count = 0; - RigidDynamicBody3D_RemoveAction *toremove = (RigidDynamicBody3D_RemoveAction *)alloca(rc * sizeof(RigidDynamicBody3D_RemoveAction)); + RigidBody3D_RemoveAction *toremove = (RigidBody3D_RemoveAction *)alloca(rc * sizeof(RigidBody3D_RemoveAction)); int toremove_count = 0; //put the ones to add @@ -590,7 +590,7 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) } } -void RigidDynamicBody3D::_notification(int p_what) { +void RigidBody3D::_notification(int p_what) { #ifdef TOOLS_ENABLED switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -608,7 +608,7 @@ void RigidDynamicBody3D::_notification(int p_what) { #endif } -void RigidDynamicBody3D::_apply_body_mode() { +void RigidBody3D::_apply_body_mode() { if (freeze) { switch (freeze_mode) { case FREEZE_MODE_STATIC: { @@ -619,13 +619,13 @@ void RigidDynamicBody3D::_apply_body_mode() { } break; } } else if (lock_rotation) { - set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC_LINEAR); + set_body_mode(PhysicsServer3D::BODY_MODE_RIGID_LINEAR); } else { - set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC); + set_body_mode(PhysicsServer3D::BODY_MODE_RIGID); } } -void RigidDynamicBody3D::set_lock_rotation_enabled(bool p_lock_rotation) { +void RigidBody3D::set_lock_rotation_enabled(bool p_lock_rotation) { if (p_lock_rotation == lock_rotation) { return; } @@ -634,11 +634,11 @@ void RigidDynamicBody3D::set_lock_rotation_enabled(bool p_lock_rotation) { _apply_body_mode(); } -bool RigidDynamicBody3D::is_lock_rotation_enabled() const { +bool RigidBody3D::is_lock_rotation_enabled() const { return lock_rotation; } -void RigidDynamicBody3D::set_freeze_enabled(bool p_freeze) { +void RigidBody3D::set_freeze_enabled(bool p_freeze) { if (p_freeze == freeze) { return; } @@ -647,11 +647,11 @@ void RigidDynamicBody3D::set_freeze_enabled(bool p_freeze) { _apply_body_mode(); } -bool RigidDynamicBody3D::is_freeze_enabled() const { +bool RigidBody3D::is_freeze_enabled() const { return freeze; } -void RigidDynamicBody3D::set_freeze_mode(FreezeMode p_freeze_mode) { +void RigidBody3D::set_freeze_mode(FreezeMode p_freeze_mode) { if (p_freeze_mode == freeze_mode) { return; } @@ -660,21 +660,21 @@ void RigidDynamicBody3D::set_freeze_mode(FreezeMode p_freeze_mode) { _apply_body_mode(); } -RigidDynamicBody3D::FreezeMode RigidDynamicBody3D::get_freeze_mode() const { +RigidBody3D::FreezeMode RigidBody3D::get_freeze_mode() const { return freeze_mode; } -void RigidDynamicBody3D::set_mass(real_t p_mass) { +void RigidBody3D::set_mass(real_t p_mass) { ERR_FAIL_COND(p_mass <= 0); mass = p_mass; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass); } -real_t RigidDynamicBody3D::get_mass() const { +real_t RigidBody3D::get_mass() const { return mass; } -void RigidDynamicBody3D::set_inertia(const Vector3 &p_inertia) { +void RigidBody3D::set_inertia(const Vector3 &p_inertia) { ERR_FAIL_COND(p_inertia.x < 0); ERR_FAIL_COND(p_inertia.y < 0); ERR_FAIL_COND(p_inertia.z < 0); @@ -683,11 +683,11 @@ void RigidDynamicBody3D::set_inertia(const Vector3 &p_inertia) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_INERTIA, inertia); } -const Vector3 &RigidDynamicBody3D::get_inertia() const { +const Vector3 &RigidBody3D::get_inertia() const { return inertia; } -void RigidDynamicBody3D::set_center_of_mass_mode(CenterOfMassMode p_mode) { +void RigidBody3D::set_center_of_mass_mode(CenterOfMassMode p_mode) { if (center_of_mass_mode == p_mode) { return; } @@ -709,11 +709,11 @@ void RigidDynamicBody3D::set_center_of_mass_mode(CenterOfMassMode p_mode) { } } -RigidDynamicBody3D::CenterOfMassMode RigidDynamicBody3D::get_center_of_mass_mode() const { +RigidBody3D::CenterOfMassMode RigidBody3D::get_center_of_mass_mode() const { return center_of_mass_mode; } -void RigidDynamicBody3D::set_center_of_mass(const Vector3 &p_center_of_mass) { +void RigidBody3D::set_center_of_mass(const Vector3 &p_center_of_mass) { if (center_of_mass == p_center_of_mass) { return; } @@ -724,106 +724,106 @@ void RigidDynamicBody3D::set_center_of_mass(const Vector3 &p_center_of_mass) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_CENTER_OF_MASS, center_of_mass); } -const Vector3 &RigidDynamicBody3D::get_center_of_mass() const { +const Vector3 &RigidBody3D::get_center_of_mass() const { return center_of_mass; } -void RigidDynamicBody3D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { +void RigidBody3D::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, callable_mp(this, &RigidDynamicBody3D::_reload_physics_characteristics))) { - physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidDynamicBody3D::_reload_physics_characteristics)); + if (physics_material_override->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody3D::_reload_physics_characteristics))) { + physics_material_override->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody3D::_reload_physics_characteristics)); } } physics_material_override = p_physics_material_override; if (physics_material_override.is_valid()) { - physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidDynamicBody3D::_reload_physics_characteristics)); + physics_material_override->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &RigidBody3D::_reload_physics_characteristics)); } _reload_physics_characteristics(); } -Ref<PhysicsMaterial> RigidDynamicBody3D::get_physics_material_override() const { +Ref<PhysicsMaterial> RigidBody3D::get_physics_material_override() const { return physics_material_override; } -void RigidDynamicBody3D::set_gravity_scale(real_t p_gravity_scale) { +void RigidBody3D::set_gravity_scale(real_t p_gravity_scale) { gravity_scale = p_gravity_scale; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, gravity_scale); } -real_t RigidDynamicBody3D::get_gravity_scale() const { +real_t RigidBody3D::get_gravity_scale() const { return gravity_scale; } -void RigidDynamicBody3D::set_linear_damp_mode(DampMode p_mode) { +void RigidBody3D::set_linear_damp_mode(DampMode p_mode) { linear_damp_mode = p_mode; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP_MODE, linear_damp_mode); } -RigidDynamicBody3D::DampMode RigidDynamicBody3D::get_linear_damp_mode() const { +RigidBody3D::DampMode RigidBody3D::get_linear_damp_mode() const { return linear_damp_mode; } -void RigidDynamicBody3D::set_angular_damp_mode(DampMode p_mode) { +void RigidBody3D::set_angular_damp_mode(DampMode p_mode) { angular_damp_mode = p_mode; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP_MODE, angular_damp_mode); } -RigidDynamicBody3D::DampMode RigidDynamicBody3D::get_angular_damp_mode() const { +RigidBody3D::DampMode RigidBody3D::get_angular_damp_mode() const { return angular_damp_mode; } -void RigidDynamicBody3D::set_linear_damp(real_t p_linear_damp) { +void RigidBody3D::set_linear_damp(real_t p_linear_damp) { ERR_FAIL_COND(p_linear_damp < 0.0); linear_damp = p_linear_damp; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp); } -real_t RigidDynamicBody3D::get_linear_damp() const { +real_t RigidBody3D::get_linear_damp() const { return linear_damp; } -void RigidDynamicBody3D::set_angular_damp(real_t p_angular_damp) { +void RigidBody3D::set_angular_damp(real_t p_angular_damp) { ERR_FAIL_COND(p_angular_damp < 0.0); angular_damp = p_angular_damp; PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp); } -real_t RigidDynamicBody3D::get_angular_damp() const { +real_t RigidBody3D::get_angular_damp() const { return angular_damp; } -void RigidDynamicBody3D::set_axis_velocity(const Vector3 &p_axis) { +void RigidBody3D::set_axis_velocity(const Vector3 &p_axis) { Vector3 axis = p_axis.normalized(); linear_velocity -= axis * axis.dot(linear_velocity); linear_velocity += p_axis; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); } -void RigidDynamicBody3D::set_linear_velocity(const Vector3 &p_velocity) { +void RigidBody3D::set_linear_velocity(const Vector3 &p_velocity) { linear_velocity = p_velocity; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); } -Vector3 RigidDynamicBody3D::get_linear_velocity() const { +Vector3 RigidBody3D::get_linear_velocity() const { return linear_velocity; } -void RigidDynamicBody3D::set_angular_velocity(const Vector3 &p_velocity) { +void RigidBody3D::set_angular_velocity(const Vector3 &p_velocity) { angular_velocity = p_velocity; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); } -Vector3 RigidDynamicBody3D::get_angular_velocity() const { +Vector3 RigidBody3D::get_angular_velocity() const { return angular_velocity; } -Basis RigidDynamicBody3D::get_inverse_inertia_tensor() const { +Basis RigidBody3D::get_inverse_inertia_tensor() const { return inverse_inertia_tensor; } -void RigidDynamicBody3D::set_use_custom_integrator(bool p_enable) { +void RigidBody3D::set_use_custom_integrator(bool p_enable) { if (custom_integrator == p_enable) { return; } @@ -832,108 +832,108 @@ void RigidDynamicBody3D::set_use_custom_integrator(bool p_enable) { PhysicsServer3D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable); } -bool RigidDynamicBody3D::is_using_custom_integrator() { +bool RigidBody3D::is_using_custom_integrator() { return custom_integrator; } -void RigidDynamicBody3D::set_sleeping(bool p_sleeping) { +void RigidBody3D::set_sleeping(bool p_sleeping) { sleeping = p_sleeping; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_SLEEPING, sleeping); } -void RigidDynamicBody3D::set_can_sleep(bool p_active) { +void RigidBody3D::set_can_sleep(bool p_active) { can_sleep = p_active; PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active); } -bool RigidDynamicBody3D::is_able_to_sleep() const { +bool RigidBody3D::is_able_to_sleep() const { return can_sleep; } -bool RigidDynamicBody3D::is_sleeping() const { +bool RigidBody3D::is_sleeping() const { return sleeping; } -void RigidDynamicBody3D::set_max_contacts_reported(int p_amount) { +void RigidBody3D::set_max_contacts_reported(int p_amount) { max_contacts_reported = p_amount; PhysicsServer3D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount); } -int RigidDynamicBody3D::get_max_contacts_reported() const { +int RigidBody3D::get_max_contacts_reported() const { return max_contacts_reported; } -int RigidDynamicBody3D::get_contact_count() const { +int RigidBody3D::get_contact_count() const { PhysicsDirectBodyState3D *bs = PhysicsServer3D::get_singleton()->body_get_direct_state(get_rid()); ERR_FAIL_NULL_V(bs, 0); return bs->get_contact_count(); } -void RigidDynamicBody3D::apply_central_impulse(const Vector3 &p_impulse) { +void RigidBody3D::apply_central_impulse(const Vector3 &p_impulse) { PhysicsServer3D::get_singleton()->body_apply_central_impulse(get_rid(), p_impulse); } -void RigidDynamicBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { +void RigidBody3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) { PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); singleton->body_apply_impulse(get_rid(), p_impulse, p_position); } -void RigidDynamicBody3D::apply_torque_impulse(const Vector3 &p_impulse) { +void RigidBody3D::apply_torque_impulse(const Vector3 &p_impulse) { PhysicsServer3D::get_singleton()->body_apply_torque_impulse(get_rid(), p_impulse); } -void RigidDynamicBody3D::apply_central_force(const Vector3 &p_force) { +void RigidBody3D::apply_central_force(const Vector3 &p_force) { PhysicsServer3D::get_singleton()->body_apply_central_force(get_rid(), p_force); } -void RigidDynamicBody3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) { +void RigidBody3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) { PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); singleton->body_apply_force(get_rid(), p_force, p_position); } -void RigidDynamicBody3D::apply_torque(const Vector3 &p_torque) { +void RigidBody3D::apply_torque(const Vector3 &p_torque) { PhysicsServer3D::get_singleton()->body_apply_torque(get_rid(), p_torque); } -void RigidDynamicBody3D::add_constant_central_force(const Vector3 &p_force) { +void RigidBody3D::add_constant_central_force(const Vector3 &p_force) { PhysicsServer3D::get_singleton()->body_add_constant_central_force(get_rid(), p_force); } -void RigidDynamicBody3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) { +void RigidBody3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) { PhysicsServer3D *singleton = PhysicsServer3D::get_singleton(); singleton->body_add_constant_force(get_rid(), p_force, p_position); } -void RigidDynamicBody3D::add_constant_torque(const Vector3 &p_torque) { +void RigidBody3D::add_constant_torque(const Vector3 &p_torque) { PhysicsServer3D::get_singleton()->body_add_constant_torque(get_rid(), p_torque); } -void RigidDynamicBody3D::set_constant_force(const Vector3 &p_force) { +void RigidBody3D::set_constant_force(const Vector3 &p_force) { PhysicsServer3D::get_singleton()->body_set_constant_force(get_rid(), p_force); } -Vector3 RigidDynamicBody3D::get_constant_force() const { +Vector3 RigidBody3D::get_constant_force() const { return PhysicsServer3D::get_singleton()->body_get_constant_force(get_rid()); } -void RigidDynamicBody3D::set_constant_torque(const Vector3 &p_torque) { +void RigidBody3D::set_constant_torque(const Vector3 &p_torque) { PhysicsServer3D::get_singleton()->body_set_constant_torque(get_rid(), p_torque); } -Vector3 RigidDynamicBody3D::get_constant_torque() const { +Vector3 RigidBody3D::get_constant_torque() const { return PhysicsServer3D::get_singleton()->body_get_constant_torque(get_rid()); } -void RigidDynamicBody3D::set_use_continuous_collision_detection(bool p_enable) { +void RigidBody3D::set_use_continuous_collision_detection(bool p_enable) { ccd = p_enable; PhysicsServer3D::get_singleton()->body_set_enable_continuous_collision_detection(get_rid(), p_enable); } -bool RigidDynamicBody3D::is_using_continuous_collision_detection() const { +bool RigidBody3D::is_using_continuous_collision_detection() const { return ccd; } -void RigidDynamicBody3D::set_contact_monitor(bool p_enabled) { +void RigidBody3D::set_contact_monitor(bool p_enabled) { if (p_enabled == is_contact_monitor_enabled()) { return; } @@ -947,8 +947,8 @@ void RigidDynamicBody3D::set_contact_monitor(bool p_enabled) { Node *node = Object::cast_to<Node>(obj); if (node) { - node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidDynamicBody3D::_body_enter_tree)); - node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidDynamicBody3D::_body_exit_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree)); + node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree)); } } @@ -960,11 +960,11 @@ void RigidDynamicBody3D::set_contact_monitor(bool p_enabled) { } } -bool RigidDynamicBody3D::is_contact_monitor_enabled() const { +bool RigidBody3D::is_contact_monitor_enabled() const { return contact_monitor != nullptr; } -TypedArray<Node3D> RigidDynamicBody3D::get_colliding_bodies() const { +TypedArray<Node3D> RigidBody3D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, TypedArray<Node3D>()); TypedArray<Node3D> ret; @@ -982,106 +982,106 @@ TypedArray<Node3D> RigidDynamicBody3D::get_colliding_bodies() const { return ret; } -TypedArray<String> RigidDynamicBody3D::get_configuration_warnings() const { +TypedArray<String> RigidBody3D::get_configuration_warnings() const { Transform3D t = get_transform(); TypedArray<String> warnings = Node::get_configuration_warnings(); if (ABS(t.basis.get_column(0).length() - 1.0) > 0.05 || ABS(t.basis.get_column(1).length() - 1.0) > 0.05 || ABS(t.basis.get_column(2).length() - 1.0) > 0.05) { - warnings.push_back(RTR("Size changes to RigidDynamicBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + warnings.push_back(RTR("Size changes to RigidBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; } -void RigidDynamicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidDynamicBody3D::set_mass); - ClassDB::bind_method(D_METHOD("get_mass"), &RigidDynamicBody3D::get_mass); +void RigidBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_mass", "mass"), &RigidBody3D::set_mass); + ClassDB::bind_method(D_METHOD("get_mass"), &RigidBody3D::get_mass); - ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &RigidDynamicBody3D::set_inertia); - ClassDB::bind_method(D_METHOD("get_inertia"), &RigidDynamicBody3D::get_inertia); + ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &RigidBody3D::set_inertia); + ClassDB::bind_method(D_METHOD("get_inertia"), &RigidBody3D::get_inertia); - ClassDB::bind_method(D_METHOD("set_center_of_mass_mode", "mode"), &RigidDynamicBody3D::set_center_of_mass_mode); - ClassDB::bind_method(D_METHOD("get_center_of_mass_mode"), &RigidDynamicBody3D::get_center_of_mass_mode); + ClassDB::bind_method(D_METHOD("set_center_of_mass_mode", "mode"), &RigidBody3D::set_center_of_mass_mode); + ClassDB::bind_method(D_METHOD("get_center_of_mass_mode"), &RigidBody3D::get_center_of_mass_mode); - ClassDB::bind_method(D_METHOD("set_center_of_mass", "center_of_mass"), &RigidDynamicBody3D::set_center_of_mass); - ClassDB::bind_method(D_METHOD("get_center_of_mass"), &RigidDynamicBody3D::get_center_of_mass); + ClassDB::bind_method(D_METHOD("set_center_of_mass", "center_of_mass"), &RigidBody3D::set_center_of_mass); + ClassDB::bind_method(D_METHOD("get_center_of_mass"), &RigidBody3D::get_center_of_mass); - ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidDynamicBody3D::set_physics_material_override); - ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidDynamicBody3D::get_physics_material_override); + ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &RigidBody3D::set_physics_material_override); + ClassDB::bind_method(D_METHOD("get_physics_material_override"), &RigidBody3D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidDynamicBody3D::set_linear_velocity); - ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidDynamicBody3D::get_linear_velocity); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &RigidBody3D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &RigidBody3D::get_linear_velocity); - ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidDynamicBody3D::set_angular_velocity); - ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidDynamicBody3D::get_angular_velocity); + ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &RigidBody3D::set_angular_velocity); + ClassDB::bind_method(D_METHOD("get_angular_velocity"), &RigidBody3D::get_angular_velocity); - ClassDB::bind_method(D_METHOD("get_inverse_inertia_tensor"), &RigidDynamicBody3D::get_inverse_inertia_tensor); + ClassDB::bind_method(D_METHOD("get_inverse_inertia_tensor"), &RigidBody3D::get_inverse_inertia_tensor); - ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidDynamicBody3D::set_gravity_scale); - ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidDynamicBody3D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidBody3D::set_gravity_scale); + ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidBody3D::get_gravity_scale); - ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidDynamicBody3D::set_linear_damp_mode); - ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidDynamicBody3D::get_linear_damp_mode); + ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidBody3D::set_linear_damp_mode); + ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidBody3D::get_linear_damp_mode); - ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidDynamicBody3D::set_angular_damp_mode); - ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidDynamicBody3D::get_angular_damp_mode); + ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidBody3D::set_angular_damp_mode); + ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidBody3D::get_angular_damp_mode); - ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidDynamicBody3D::set_linear_damp); - ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidDynamicBody3D::get_linear_damp); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidBody3D::set_linear_damp); + ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidBody3D::get_linear_damp); - ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &RigidDynamicBody3D::set_angular_damp); - ClassDB::bind_method(D_METHOD("get_angular_damp"), &RigidDynamicBody3D::get_angular_damp); + ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &RigidBody3D::set_angular_damp); + ClassDB::bind_method(D_METHOD("get_angular_damp"), &RigidBody3D::get_angular_damp); - ClassDB::bind_method(D_METHOD("set_max_contacts_reported", "amount"), &RigidDynamicBody3D::set_max_contacts_reported); - ClassDB::bind_method(D_METHOD("get_max_contacts_reported"), &RigidDynamicBody3D::get_max_contacts_reported); - ClassDB::bind_method(D_METHOD("get_contact_count"), &RigidDynamicBody3D::get_contact_count); + ClassDB::bind_method(D_METHOD("set_max_contacts_reported", "amount"), &RigidBody3D::set_max_contacts_reported); + ClassDB::bind_method(D_METHOD("get_max_contacts_reported"), &RigidBody3D::get_max_contacts_reported); + ClassDB::bind_method(D_METHOD("get_contact_count"), &RigidBody3D::get_contact_count); - ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &RigidDynamicBody3D::set_use_custom_integrator); - ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &RigidDynamicBody3D::is_using_custom_integrator); + ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &RigidBody3D::set_use_custom_integrator); + ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &RigidBody3D::is_using_custom_integrator); - ClassDB::bind_method(D_METHOD("set_contact_monitor", "enabled"), &RigidDynamicBody3D::set_contact_monitor); - ClassDB::bind_method(D_METHOD("is_contact_monitor_enabled"), &RigidDynamicBody3D::is_contact_monitor_enabled); + ClassDB::bind_method(D_METHOD("set_contact_monitor", "enabled"), &RigidBody3D::set_contact_monitor); + ClassDB::bind_method(D_METHOD("is_contact_monitor_enabled"), &RigidBody3D::is_contact_monitor_enabled); - ClassDB::bind_method(D_METHOD("set_use_continuous_collision_detection", "enable"), &RigidDynamicBody3D::set_use_continuous_collision_detection); - ClassDB::bind_method(D_METHOD("is_using_continuous_collision_detection"), &RigidDynamicBody3D::is_using_continuous_collision_detection); + ClassDB::bind_method(D_METHOD("set_use_continuous_collision_detection", "enable"), &RigidBody3D::set_use_continuous_collision_detection); + ClassDB::bind_method(D_METHOD("is_using_continuous_collision_detection"), &RigidBody3D::is_using_continuous_collision_detection); - ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidDynamicBody3D::set_axis_velocity); + ClassDB::bind_method(D_METHOD("set_axis_velocity", "axis_velocity"), &RigidBody3D::set_axis_velocity); - ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidDynamicBody3D::apply_central_impulse); - ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidDynamicBody3D::apply_impulse, Vector3()); - ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidDynamicBody3D::apply_torque_impulse); + ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &RigidBody3D::apply_central_impulse); + ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &RigidBody3D::apply_impulse, Vector3()); + ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &RigidBody3D::apply_torque_impulse); - ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidDynamicBody3D::apply_central_force); - ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidDynamicBody3D::apply_force, Vector3()); - ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidDynamicBody3D::apply_torque); + ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &RigidBody3D::apply_central_force); + ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &RigidBody3D::apply_force, Vector3()); + ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &RigidBody3D::apply_torque); - ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidDynamicBody3D::add_constant_central_force); - ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidDynamicBody3D::add_constant_force, Vector3()); - ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidDynamicBody3D::add_constant_torque); + ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &RigidBody3D::add_constant_central_force); + ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &RigidBody3D::add_constant_force, Vector3()); + ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &RigidBody3D::add_constant_torque); - ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidDynamicBody3D::set_constant_force); - ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidDynamicBody3D::get_constant_force); + ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &RigidBody3D::set_constant_force); + ClassDB::bind_method(D_METHOD("get_constant_force"), &RigidBody3D::get_constant_force); - ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidDynamicBody3D::set_constant_torque); - ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidDynamicBody3D::get_constant_torque); + ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &RigidBody3D::set_constant_torque); + ClassDB::bind_method(D_METHOD("get_constant_torque"), &RigidBody3D::get_constant_torque); - ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidDynamicBody3D::set_sleeping); - ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidDynamicBody3D::is_sleeping); + ClassDB::bind_method(D_METHOD("set_sleeping", "sleeping"), &RigidBody3D::set_sleeping); + ClassDB::bind_method(D_METHOD("is_sleeping"), &RigidBody3D::is_sleeping); - ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidDynamicBody3D::set_can_sleep); - ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidDynamicBody3D::is_able_to_sleep); + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody3D::set_can_sleep); + ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_lock_rotation_enabled", "lock_rotation"), &RigidDynamicBody3D::set_lock_rotation_enabled); - ClassDB::bind_method(D_METHOD("is_lock_rotation_enabled"), &RigidDynamicBody3D::is_lock_rotation_enabled); + ClassDB::bind_method(D_METHOD("set_lock_rotation_enabled", "lock_rotation"), &RigidBody3D::set_lock_rotation_enabled); + ClassDB::bind_method(D_METHOD("is_lock_rotation_enabled"), &RigidBody3D::is_lock_rotation_enabled); - ClassDB::bind_method(D_METHOD("set_freeze_enabled", "freeze_mode"), &RigidDynamicBody3D::set_freeze_enabled); - ClassDB::bind_method(D_METHOD("is_freeze_enabled"), &RigidDynamicBody3D::is_freeze_enabled); + ClassDB::bind_method(D_METHOD("set_freeze_enabled", "freeze_mode"), &RigidBody3D::set_freeze_enabled); + ClassDB::bind_method(D_METHOD("is_freeze_enabled"), &RigidBody3D::is_freeze_enabled); - ClassDB::bind_method(D_METHOD("set_freeze_mode", "freeze_mode"), &RigidDynamicBody3D::set_freeze_mode); - ClassDB::bind_method(D_METHOD("get_freeze_mode"), &RigidDynamicBody3D::get_freeze_mode); + ClassDB::bind_method(D_METHOD("set_freeze_mode", "freeze_mode"), &RigidBody3D::set_freeze_mode); + ClassDB::bind_method(D_METHOD("get_freeze_mode"), &RigidBody3D::get_freeze_mode); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidDynamicBody3D::get_colliding_bodies); + ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody3D::get_colliding_bodies); GDVIRTUAL_BIND(_integrate_forces, "state"); @@ -1129,7 +1129,7 @@ void RigidDynamicBody3D::_bind_methods() { BIND_ENUM_CONSTANT(DAMP_MODE_REPLACE); } -void RigidDynamicBody3D::_validate_property(PropertyInfo &p_property) const { +void RigidBody3D::_validate_property(PropertyInfo &p_property) const { if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) { if (p_property.name == "center_of_mass") { p_property.usage = PROPERTY_USAGE_NO_EDITOR; @@ -1137,18 +1137,18 @@ void RigidDynamicBody3D::_validate_property(PropertyInfo &p_property) const { } } -RigidDynamicBody3D::RigidDynamicBody3D() : - PhysicsBody3D(PhysicsServer3D::BODY_MODE_DYNAMIC) { +RigidBody3D::RigidBody3D() : + PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { PhysicsServer3D::get_singleton()->body_set_state_sync_callback(get_rid(), this, _body_state_changed_callback); } -RigidDynamicBody3D::~RigidDynamicBody3D() { +RigidBody3D::~RigidBody3D() { if (contact_monitor) { memdelete(contact_monitor); } } -void RigidDynamicBody3D::_reload_physics_characteristics() { +void RigidBody3D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_BOUNCE, 0); PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_FRICTION, 1); @@ -2284,13 +2284,13 @@ bool PhysicalBone3D::ConeJointData::_set(const StringName &p_name, const Variant } if ("joint_constraints/swing_span" == p_name) { - swing_span = Math::deg2rad(real_t(p_value)); + swing_span = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, swing_span); } } else if ("joint_constraints/twist_span" == p_name) { - twist_span = Math::deg2rad(real_t(p_value)); + twist_span = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, twist_span); } @@ -2326,9 +2326,9 @@ bool PhysicalBone3D::ConeJointData::_get(const StringName &p_name, Variant &r_re } if ("joint_constraints/swing_span" == p_name) { - r_ret = Math::rad2deg(swing_span); + r_ret = Math::rad_to_deg(swing_span); } else if ("joint_constraints/twist_span" == p_name) { - r_ret = Math::rad2deg(twist_span); + r_ret = Math::rad_to_deg(twist_span); } else if ("joint_constraints/bias" == p_name) { r_ret = bias; } else if ("joint_constraints/softness" == p_name) { @@ -2364,13 +2364,13 @@ bool PhysicalBone3D::HingeJointData::_set(const StringName &p_name, const Varian } } else if ("joint_constraints/angular_limit_upper" == p_name) { - angular_limit_upper = Math::deg2rad(real_t(p_value)); + angular_limit_upper = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, angular_limit_upper); } } else if ("joint_constraints/angular_limit_lower" == p_name) { - angular_limit_lower = Math::deg2rad(real_t(p_value)); + angular_limit_lower = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER, angular_limit_lower); } @@ -2408,9 +2408,9 @@ bool PhysicalBone3D::HingeJointData::_get(const StringName &p_name, Variant &r_r if ("joint_constraints/angular_limit_enabled" == p_name) { r_ret = angular_limit_enabled; } else if ("joint_constraints/angular_limit_upper" == p_name) { - r_ret = Math::rad2deg(angular_limit_upper); + r_ret = Math::rad_to_deg(angular_limit_upper); } else if ("joint_constraints/angular_limit_lower" == p_name) { - r_ret = Math::rad2deg(angular_limit_lower); + r_ret = Math::rad_to_deg(angular_limit_lower); } else if ("joint_constraints/angular_limit_bias" == p_name) { r_ret = angular_limit_bias; } else if ("joint_constraints/angular_limit_softness" == p_name) { @@ -2471,13 +2471,13 @@ bool PhysicalBone3D::SliderJointData::_set(const StringName &p_name, const Varia } } else if ("joint_constraints/angular_limit_upper" == p_name) { - angular_limit_upper = Math::deg2rad(real_t(p_value)); + angular_limit_upper = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER, angular_limit_upper); } } else if ("joint_constraints/angular_limit_lower" == p_name) { - angular_limit_lower = Math::deg2rad(real_t(p_value)); + angular_limit_lower = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER, angular_limit_lower); } @@ -2523,9 +2523,9 @@ bool PhysicalBone3D::SliderJointData::_get(const StringName &p_name, Variant &r_ } else if ("joint_constraints/linear_limit_damping" == p_name) { r_ret = linear_limit_damping; } else if ("joint_constraints/angular_limit_upper" == p_name) { - r_ret = Math::rad2deg(angular_limit_upper); + r_ret = Math::rad_to_deg(angular_limit_upper); } else if ("joint_constraints/angular_limit_lower" == p_name) { - r_ret = Math::rad2deg(angular_limit_lower); + r_ret = Math::rad_to_deg(angular_limit_lower); } else if ("joint_constraints/angular_limit_softness" == p_name) { r_ret = angular_limit_softness; } else if ("joint_constraints/angular_limit_restitution" == p_name) { @@ -2649,13 +2649,13 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia } } else if ("angular_limit_upper" == var_name) { - axis_data[axis].angular_limit_upper = Math::deg2rad(real_t(p_value)); + axis_data[axis].angular_limit_upper = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, axis_data[axis].angular_limit_upper); } } else if ("angular_limit_lower" == var_name) { - axis_data[axis].angular_limit_lower = Math::deg2rad(real_t(p_value)); + axis_data[axis].angular_limit_lower = Math::deg_to_rad(real_t(p_value)); if (j.is_valid()) { PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, axis_data[axis].angular_limit_lower); } @@ -2765,9 +2765,9 @@ bool PhysicalBone3D::SixDOFJointData::_get(const StringName &p_name, Variant &r_ } else if ("angular_limit_enabled" == var_name) { r_ret = axis_data[axis].angular_limit_enabled; } else if ("angular_limit_upper" == var_name) { - r_ret = Math::rad2deg(axis_data[axis].angular_limit_upper); + r_ret = Math::rad_to_deg(axis_data[axis].angular_limit_upper); } else if ("angular_limit_lower" == var_name) { - r_ret = Math::rad2deg(axis_data[axis].angular_limit_lower); + r_ret = Math::rad_to_deg(axis_data[axis].angular_limit_lower); } else if ("angular_limit_softness" == var_name) { r_ret = axis_data[axis].angular_limit_softness; } else if ("angular_restitution" == var_name) { @@ -3421,7 +3421,7 @@ void PhysicalBone3D::_start_physics_simulation() { return; } reset_to_rest_position(); - set_body_mode(PhysicsServer3D::BODY_MODE_DYNAMIC); + set_body_mode(PhysicsServer3D::BODY_MODE_RIGID); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); PhysicsServer3D::get_singleton()->body_set_collision_priority(get_rid(), get_collision_priority()); diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 14a1cf7228..184d8b00d0 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -129,8 +129,8 @@ private: bool is_sync_to_physics_enabled() const; }; -class RigidDynamicBody3D : public PhysicsBody3D { - GDCLASS(RigidDynamicBody3D, PhysicsBody3D); +class RigidBody3D : public PhysicsBody3D { + GDCLASS(RigidBody3D, PhysicsBody3D); public: enum FreezeMode { @@ -198,7 +198,7 @@ private: tagged = false; } }; - struct RigidDynamicBody3D_RemoveAction { + struct RigidBody3D_RemoveAction { RID rid; ObjectID body_id; ShapePair pair; @@ -327,16 +327,16 @@ public: virtual TypedArray<String> get_configuration_warnings() const override; - RigidDynamicBody3D(); - ~RigidDynamicBody3D(); + RigidBody3D(); + ~RigidBody3D(); private: void _reload_physics_characteristics(); }; -VARIANT_ENUM_CAST(RigidDynamicBody3D::FreezeMode); -VARIANT_ENUM_CAST(RigidDynamicBody3D::CenterOfMassMode); -VARIANT_ENUM_CAST(RigidDynamicBody3D::DampMode); +VARIANT_ENUM_CAST(RigidBody3D::FreezeMode); +VARIANT_ENUM_CAST(RigidBody3D::CenterOfMassMode); +VARIANT_ENUM_CAST(RigidBody3D::DampMode); class KinematicCollision3D; @@ -414,8 +414,8 @@ private: uint32_t platform_floor_layers = UINT32_MAX; uint32_t platform_wall_layers = 0; real_t floor_snap_length = 0.1; - real_t floor_max_angle = Math::deg2rad((real_t)45.0); - real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); + real_t floor_max_angle = Math::deg_to_rad((real_t)45.0); + real_t wall_min_slide_angle = Math::deg_to_rad((real_t)15.0); Vector3 up_direction = Vector3(0.0, 1.0, 0.0); Vector3 velocity; Vector3 floor_normal; diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 2650d62fa4..47858b372c 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* soft_dynamic_body_3d.cpp */ +/* soft_body_3d.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "soft_dynamic_body_3d.h" +#include "soft_body_3d.h" #include "scene/3d/physics_body_3d.h" -SoftDynamicBodyRenderingServerHandler::SoftDynamicBodyRenderingServerHandler() {} +SoftBodyRenderingServerHandler::SoftBodyRenderingServerHandler() {} -void SoftDynamicBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) { +void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) { clear(); ERR_FAIL_COND(!p_mesh.is_valid()); @@ -56,7 +56,7 @@ void SoftDynamicBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) { offset_normal = surface_offsets[RS::ARRAY_NORMAL]; } -void SoftDynamicBodyRenderingServerHandler::clear() { +void SoftBodyRenderingServerHandler::clear() { buffer.resize(0); stride = 0; offset_vertices = 0; @@ -66,23 +66,23 @@ void SoftDynamicBodyRenderingServerHandler::clear() { mesh = RID(); } -void SoftDynamicBodyRenderingServerHandler::open() { +void SoftBodyRenderingServerHandler::open() { write_buffer = buffer.ptrw(); } -void SoftDynamicBodyRenderingServerHandler::close() { +void SoftBodyRenderingServerHandler::close() { write_buffer = nullptr; } -void SoftDynamicBodyRenderingServerHandler::commit_changes() { +void SoftBodyRenderingServerHandler::commit_changes() { RS::get_singleton()->mesh_surface_update_vertex_region(mesh, surface, 0, buffer); } -void SoftDynamicBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) { +void SoftBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) { memcpy(&write_buffer[p_vertex_id * stride + offset_vertices], p_vector3, sizeof(float) * 3); } -void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const void *p_vector3) { +void SoftBodyRenderingServerHandler::set_normal(int p_vertex_id, const void *p_vector3) { // Store normal vector in A2B10G10R10 format. Vector3 n; memcpy(&n, p_vector3, sizeof(Vector3)); @@ -95,28 +95,28 @@ void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const vo memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t)); } -void SoftDynamicBodyRenderingServerHandler::set_aabb(const AABB &p_aabb) { +void SoftBodyRenderingServerHandler::set_aabb(const AABB &p_aabb) { RS::get_singleton()->mesh_set_custom_aabb(mesh, p_aabb); } -SoftDynamicBody3D::PinnedPoint::PinnedPoint() { +SoftBody3D::PinnedPoint::PinnedPoint() { } -SoftDynamicBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) { +SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) { point_index = obj_tocopy.point_index; spatial_attachment_path = obj_tocopy.spatial_attachment_path; spatial_attachment = obj_tocopy.spatial_attachment; offset = obj_tocopy.offset; } -void SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) { +void SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) { point_index = obj.point_index; spatial_attachment_path = obj.spatial_attachment_path; spatial_attachment = obj.spatial_attachment; offset = obj.offset; } -void SoftDynamicBody3D::_update_pickable() { +void SoftBody3D::_update_pickable() { if (!is_inside_tree()) { return; } @@ -124,7 +124,7 @@ void SoftDynamicBody3D::_update_pickable() { PhysicsServer3D::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable); } -bool SoftDynamicBody3D::_set(const StringName &p_name, const Variant &p_value) { +bool SoftBody3D::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; String which = name.get_slicec('/', 0); @@ -141,7 +141,7 @@ bool SoftDynamicBody3D::_set(const StringName &p_name, const Variant &p_value) { return false; } -bool SoftDynamicBody3D::_get(const StringName &p_name, Variant &r_ret) const { +bool SoftBody3D::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; String which = name.get_slicec('/', 0); @@ -168,7 +168,7 @@ bool SoftDynamicBody3D::_get(const StringName &p_name, Variant &r_ret) const { return false; } -void SoftDynamicBody3D::_get_property_list(List<PropertyInfo> *p_list) const { +void SoftBody3D::_get_property_list(List<PropertyInfo> *p_list) const { const int pinned_points_indices_size = pinned_points.size(); p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, PNAME("pinned_points"))); @@ -181,7 +181,7 @@ void SoftDynamicBody3D::_get_property_list(List<PropertyInfo> *p_list) const { } } -bool SoftDynamicBody3D::_set_property_pinned_points_indices(const Array &p_indices) { +bool SoftBody3D::_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 @@ -210,7 +210,7 @@ bool SoftDynamicBody3D::_set_property_pinned_points_indices(const Array &p_indic return true; } -bool SoftDynamicBody3D::_set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value) { +bool SoftBody3D::_set_property_pinned_points_attachment(int p_item, const String &p_what, const Variant &p_value) { if (pinned_points.size() <= p_item) { return false; } @@ -229,7 +229,7 @@ bool SoftDynamicBody3D::_set_property_pinned_points_attachment(int p_item, const return true; } -bool SoftDynamicBody3D::_get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const { +bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, Variant &r_ret) const { if (pinned_points.size() <= p_item) { return false; } @@ -248,7 +248,7 @@ bool SoftDynamicBody3D::_get_property_pinned_points(int p_item, const String &p_ return true; } -void SoftDynamicBody3D::_notification(int p_what) { +void SoftBody3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { if (Engine::get_singleton()->is_editor_hint()) { @@ -313,56 +313,56 @@ void SoftDynamicBody3D::_notification(int p_what) { } } -void SoftDynamicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_physics_rid"), &SoftDynamicBody3D::get_physics_rid); +void SoftBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_physics_rid"), &SoftBody3D::get_physics_rid); - ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftDynamicBody3D::set_collision_mask); - ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftDynamicBody3D::get_collision_mask); + ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody3D::set_collision_mask); + ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody3D::get_collision_mask); - ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &SoftDynamicBody3D::set_collision_layer); - ClassDB::bind_method(D_METHOD("get_collision_layer"), &SoftDynamicBody3D::get_collision_layer); + ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &SoftBody3D::set_collision_layer); + ClassDB::bind_method(D_METHOD("get_collision_layer"), &SoftBody3D::get_collision_layer); - ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &SoftDynamicBody3D::set_collision_mask_value); - ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &SoftDynamicBody3D::get_collision_mask_value); + ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &SoftBody3D::set_collision_mask_value); + ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &SoftBody3D::get_collision_mask_value); - ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &SoftDynamicBody3D::set_collision_layer_value); - ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &SoftDynamicBody3D::get_collision_layer_value); + ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &SoftBody3D::set_collision_layer_value); + ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &SoftBody3D::get_collision_layer_value); - ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftDynamicBody3D::set_parent_collision_ignore); - ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftDynamicBody3D::get_parent_collision_ignore); + ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftBody3D::set_parent_collision_ignore); + ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftBody3D::get_parent_collision_ignore); - ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &SoftDynamicBody3D::set_disable_mode); - ClassDB::bind_method(D_METHOD("get_disable_mode"), &SoftDynamicBody3D::get_disable_mode); + ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &SoftBody3D::set_disable_mode); + ClassDB::bind_method(D_METHOD("get_disable_mode"), &SoftBody3D::get_disable_mode); - ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &SoftDynamicBody3D::get_collision_exceptions); - ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftDynamicBody3D::add_collision_exception_with); - ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftDynamicBody3D::remove_collision_exception_with); + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &SoftBody3D::get_collision_exceptions); + ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftBody3D::add_collision_exception_with); + ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftBody3D::remove_collision_exception_with); - ClassDB::bind_method(D_METHOD("set_simulation_precision", "simulation_precision"), &SoftDynamicBody3D::set_simulation_precision); - ClassDB::bind_method(D_METHOD("get_simulation_precision"), &SoftDynamicBody3D::get_simulation_precision); + ClassDB::bind_method(D_METHOD("set_simulation_precision", "simulation_precision"), &SoftBody3D::set_simulation_precision); + ClassDB::bind_method(D_METHOD("get_simulation_precision"), &SoftBody3D::get_simulation_precision); - ClassDB::bind_method(D_METHOD("set_total_mass", "mass"), &SoftDynamicBody3D::set_total_mass); - ClassDB::bind_method(D_METHOD("get_total_mass"), &SoftDynamicBody3D::get_total_mass); + ClassDB::bind_method(D_METHOD("set_total_mass", "mass"), &SoftBody3D::set_total_mass); + ClassDB::bind_method(D_METHOD("get_total_mass"), &SoftBody3D::get_total_mass); - ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftDynamicBody3D::set_linear_stiffness); - ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftDynamicBody3D::get_linear_stiffness); + ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); + ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); - ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftDynamicBody3D::set_pressure_coefficient); - ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftDynamicBody3D::get_pressure_coefficient); + ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient); + ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient); - ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftDynamicBody3D::set_damping_coefficient); - ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftDynamicBody3D::get_damping_coefficient); + ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftBody3D::set_damping_coefficient); + ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftBody3D::get_damping_coefficient); - ClassDB::bind_method(D_METHOD("set_drag_coefficient", "drag_coefficient"), &SoftDynamicBody3D::set_drag_coefficient); - ClassDB::bind_method(D_METHOD("get_drag_coefficient"), &SoftDynamicBody3D::get_drag_coefficient); + ClassDB::bind_method(D_METHOD("set_drag_coefficient", "drag_coefficient"), &SoftBody3D::set_drag_coefficient); + ClassDB::bind_method(D_METHOD("get_drag_coefficient"), &SoftBody3D::get_drag_coefficient); - ClassDB::bind_method(D_METHOD("get_point_transform", "point_index"), &SoftDynamicBody3D::get_point_transform); + ClassDB::bind_method(D_METHOD("get_point_transform", "point_index"), &SoftBody3D::get_point_transform); - ClassDB::bind_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path"), &SoftDynamicBody3D::pin_point, DEFVAL(NodePath())); - ClassDB::bind_method(D_METHOD("is_point_pinned", "point_index"), &SoftDynamicBody3D::is_point_pinned); + ClassDB::bind_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path"), &SoftBody3D::pin_point, DEFVAL(NodePath())); + ClassDB::bind_method(D_METHOD("is_point_pinned", "point_index"), &SoftBody3D::is_point_pinned); - ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftDynamicBody3D::set_ray_pickable); - ClassDB::bind_method(D_METHOD("is_ray_pickable"), &SoftDynamicBody3D::is_ray_pickable); + ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftBody3D::set_ray_pickable); + ClassDB::bind_method(D_METHOD("is_ray_pickable"), &SoftBody3D::is_ray_pickable); ADD_GROUP("Collision", "collision_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); @@ -384,7 +384,7 @@ void SoftDynamicBody3D::_bind_methods() { BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE); } -TypedArray<String> SoftDynamicBody3D::get_configuration_warnings() const { +TypedArray<String> SoftBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (mesh.is_null()) { @@ -393,13 +393,13 @@ TypedArray<String> SoftDynamicBody3D::get_configuration_warnings() const { Transform3D t = get_transform(); if ((ABS(t.basis.get_column(0).length() - 1.0) > 0.05 || ABS(t.basis.get_column(1).length() - 1.0) > 0.05 || ABS(t.basis.get_column(2).length() - 1.0) > 0.05)) { - warnings.push_back(RTR("Size changes to SoftDynamicBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + warnings.push_back(RTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; } -void SoftDynamicBody3D::_update_physics_server() { +void SoftBody3D::_update_physics_server() { if (!simulation_started) { return; } @@ -415,7 +415,7 @@ void SoftDynamicBody3D::_update_physics_server() { } } -void SoftDynamicBody3D::_draw_soft_mesh() { +void SoftBody3D::_draw_soft_mesh() { if (mesh.is_null()) { return; } @@ -445,7 +445,7 @@ void SoftDynamicBody3D::_draw_soft_mesh() { rendering_server_handler->commit_changes(); } -void SoftDynamicBody3D::_prepare_physics_server() { +void SoftBody3D::_prepare_physics_server() { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { if (mesh.is_valid()) { @@ -465,22 +465,22 @@ void SoftDynamicBody3D::_prepare_physics_server() { mesh_rid = mesh->get_rid(); } PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); - RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); + RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh)); } else { PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, RID()); - if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh))) { - RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftDynamicBody3D::_draw_soft_mesh)); + if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh))) { + RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh)); } } } -void SoftDynamicBody3D::_become_mesh_owner() { +void SoftBody3D::_become_mesh_owner() { Vector<Ref<Material>> copy_materials; copy_materials.append_array(surface_override_materials); ERR_FAIL_COND(!mesh->get_surface_count()); - // Get current mesh array and create new mesh array with necessary flag for SoftDynamicBody + // 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); @@ -502,25 +502,25 @@ void SoftDynamicBody3D::_become_mesh_owner() { owned_mesh = soft_mesh->get_rid(); } -void SoftDynamicBody3D::set_collision_mask(uint32_t p_mask) { +void SoftBody3D::set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; PhysicsServer3D::get_singleton()->soft_body_set_collision_mask(physics_rid, p_mask); } -uint32_t SoftDynamicBody3D::get_collision_mask() const { +uint32_t SoftBody3D::get_collision_mask() const { return collision_mask; } -void SoftDynamicBody3D::set_collision_layer(uint32_t p_layer) { +void SoftBody3D::set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; PhysicsServer3D::get_singleton()->soft_body_set_collision_layer(physics_rid, p_layer); } -uint32_t SoftDynamicBody3D::get_collision_layer() const { +uint32_t SoftBody3D::get_collision_layer() const { return collision_layer; } -void SoftDynamicBody3D::set_collision_layer_value(int p_layer_number, bool p_value) { +void SoftBody3D::set_collision_layer_value(int p_layer_number, bool p_value) { ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); uint32_t collision_layer = get_collision_layer(); @@ -532,13 +532,13 @@ void SoftDynamicBody3D::set_collision_layer_value(int p_layer_number, bool p_val set_collision_layer(collision_layer); } -bool SoftDynamicBody3D::get_collision_layer_value(int p_layer_number) const { +bool SoftBody3D::get_collision_layer_value(int p_layer_number) const { ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); return get_collision_layer() & (1 << (p_layer_number - 1)); } -void SoftDynamicBody3D::set_collision_mask_value(int p_layer_number, bool p_value) { +void SoftBody3D::set_collision_mask_value(int p_layer_number, bool p_value) { ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); uint32_t mask = get_collision_mask(); @@ -550,13 +550,13 @@ void SoftDynamicBody3D::set_collision_mask_value(int p_layer_number, bool p_valu set_collision_mask(mask); } -bool SoftDynamicBody3D::get_collision_mask_value(int p_layer_number) const { +bool SoftBody3D::get_collision_mask_value(int p_layer_number) const { ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); return get_collision_mask() & (1 << (p_layer_number - 1)); } -void SoftDynamicBody3D::set_disable_mode(DisableMode p_mode) { +void SoftBody3D::set_disable_mode(DisableMode p_mode) { if (disable_mode == p_mode) { return; } @@ -568,30 +568,30 @@ void SoftDynamicBody3D::set_disable_mode(DisableMode p_mode) { } } -SoftDynamicBody3D::DisableMode SoftDynamicBody3D::get_disable_mode() const { +SoftBody3D::DisableMode SoftBody3D::get_disable_mode() const { return disable_mode; } -void SoftDynamicBody3D::set_parent_collision_ignore(const NodePath &p_parent_collision_ignore) { +void SoftBody3D::set_parent_collision_ignore(const NodePath &p_parent_collision_ignore) { parent_collision_ignore = p_parent_collision_ignore; } -const NodePath &SoftDynamicBody3D::get_parent_collision_ignore() const { +const NodePath &SoftBody3D::get_parent_collision_ignore() const { return parent_collision_ignore; } -void SoftDynamicBody3D::set_pinned_points_indices(Vector<SoftDynamicBody3D::PinnedPoint> p_pinned_points_indices) { +void SoftBody3D::set_pinned_points_indices(Vector<SoftBody3D::PinnedPoint> p_pinned_points_indices) { pinned_points = p_pinned_points_indices; for (int i = pinned_points.size() - 1; 0 <= i; --i) { pin_point(p_pinned_points_indices[i].point_index, true); } } -Vector<SoftDynamicBody3D::PinnedPoint> SoftDynamicBody3D::get_pinned_points_indices() { +Vector<SoftBody3D::PinnedPoint> SoftBody3D::get_pinned_points_indices() { return pinned_points; } -TypedArray<PhysicsBody3D> SoftDynamicBody3D::get_collision_exceptions() { +TypedArray<PhysicsBody3D> SoftBody3D::get_collision_exceptions() { List<RID> exceptions; PhysicsServer3D::get_singleton()->soft_body_get_collision_exceptions(physics_rid, &exceptions); TypedArray<PhysicsBody3D> ret; @@ -604,77 +604,77 @@ TypedArray<PhysicsBody3D> SoftDynamicBody3D::get_collision_exceptions() { return ret; } -void SoftDynamicBody3D::add_collision_exception_with(Node *p_node) { +void SoftBody3D::add_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node); ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds."); PhysicsServer3D::get_singleton()->soft_body_add_collision_exception(physics_rid, collision_object->get_rid()); } -void SoftDynamicBody3D::remove_collision_exception_with(Node *p_node) { +void SoftBody3D::remove_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node); ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds."); PhysicsServer3D::get_singleton()->soft_body_remove_collision_exception(physics_rid, collision_object->get_rid()); } -int SoftDynamicBody3D::get_simulation_precision() { +int SoftBody3D::get_simulation_precision() { return PhysicsServer3D::get_singleton()->soft_body_get_simulation_precision(physics_rid); } -void SoftDynamicBody3D::set_simulation_precision(int p_simulation_precision) { +void SoftBody3D::set_simulation_precision(int p_simulation_precision) { PhysicsServer3D::get_singleton()->soft_body_set_simulation_precision(physics_rid, p_simulation_precision); } -real_t SoftDynamicBody3D::get_total_mass() { +real_t SoftBody3D::get_total_mass() { return PhysicsServer3D::get_singleton()->soft_body_get_total_mass(physics_rid); } -void SoftDynamicBody3D::set_total_mass(real_t p_total_mass) { +void SoftBody3D::set_total_mass(real_t p_total_mass) { PhysicsServer3D::get_singleton()->soft_body_set_total_mass(physics_rid, p_total_mass); } -void SoftDynamicBody3D::set_linear_stiffness(real_t p_linear_stiffness) { +void SoftBody3D::set_linear_stiffness(real_t p_linear_stiffness) { PhysicsServer3D::get_singleton()->soft_body_set_linear_stiffness(physics_rid, p_linear_stiffness); } -real_t SoftDynamicBody3D::get_linear_stiffness() { +real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } -real_t SoftDynamicBody3D::get_pressure_coefficient() { +real_t SoftBody3D::get_pressure_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid); } -void SoftDynamicBody3D::set_pressure_coefficient(real_t p_pressure_coefficient) { +void SoftBody3D::set_pressure_coefficient(real_t p_pressure_coefficient) { PhysicsServer3D::get_singleton()->soft_body_set_pressure_coefficient(physics_rid, p_pressure_coefficient); } -real_t SoftDynamicBody3D::get_damping_coefficient() { +real_t SoftBody3D::get_damping_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_damping_coefficient(physics_rid); } -void SoftDynamicBody3D::set_damping_coefficient(real_t p_damping_coefficient) { +void SoftBody3D::set_damping_coefficient(real_t p_damping_coefficient) { PhysicsServer3D::get_singleton()->soft_body_set_damping_coefficient(physics_rid, p_damping_coefficient); } -real_t SoftDynamicBody3D::get_drag_coefficient() { +real_t SoftBody3D::get_drag_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_drag_coefficient(physics_rid); } -void SoftDynamicBody3D::set_drag_coefficient(real_t p_drag_coefficient) { +void SoftBody3D::set_drag_coefficient(real_t p_drag_coefficient) { PhysicsServer3D::get_singleton()->soft_body_set_drag_coefficient(physics_rid, p_drag_coefficient); } -Vector3 SoftDynamicBody3D::get_point_transform(int p_point_index) { +Vector3 SoftBody3D::get_point_transform(int p_point_index) { return PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, p_point_index); } -void SoftDynamicBody3D::pin_point_toggle(int p_point_index) { +void SoftBody3D::pin_point_toggle(int p_point_index) { pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index))); } -void SoftDynamicBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) { +void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) { _pin_point_on_physics_server(p_point_index, pin); if (pin) { _add_pinned_point(p_point_index, p_spatial_attachment_path); @@ -683,35 +683,35 @@ void SoftDynamicBody3D::pin_point(int p_point_index, bool pin, const NodePath &p } } -bool SoftDynamicBody3D::is_point_pinned(int p_point_index) const { +bool SoftBody3D::is_point_pinned(int p_point_index) const { return -1 != _has_pinned_point(p_point_index); } -void SoftDynamicBody3D::set_ray_pickable(bool p_ray_pickable) { +void SoftBody3D::set_ray_pickable(bool p_ray_pickable) { ray_pickable = p_ray_pickable; _update_pickable(); } -bool SoftDynamicBody3D::is_ray_pickable() const { +bool SoftBody3D::is_ray_pickable() const { return ray_pickable; } -SoftDynamicBody3D::SoftDynamicBody3D() : +SoftBody3D::SoftBody3D() : physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) { - rendering_server_handler = memnew(SoftDynamicBodyRenderingServerHandler); + rendering_server_handler = memnew(SoftBodyRenderingServerHandler); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); } -SoftDynamicBody3D::~SoftDynamicBody3D() { +SoftBody3D::~SoftBody3D() { memdelete(rendering_server_handler); PhysicsServer3D::get_singleton()->free(physics_rid); } -void SoftDynamicBody3D::_make_cache_dirty() { +void SoftBody3D::_make_cache_dirty() { pinned_points_cache_dirty = true; } -void SoftDynamicBody3D::_update_cache_pin_points_datas() { +void SoftBody3D::_update_cache_pin_points_datas() { if (!pinned_points_cache_dirty) { return; } @@ -724,17 +724,17 @@ void SoftDynamicBody3D::_update_cache_pin_points_datas() { w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(w[i].spatial_attachment_path)); } if (!w[i].spatial_attachment) { - ERR_PRINT("Node3D node not defined in the pinned point, this is undefined behavior for SoftDynamicBody3D!"); + ERR_PRINT("Node3D node not defined in the pinned point, this is undefined behavior for SoftBody3D!"); } } } -void SoftDynamicBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) { +void SoftBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) { PhysicsServer3D::get_singleton()->soft_body_pin_point(physics_rid, p_point_index, pin); } -void SoftDynamicBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) { - SoftDynamicBody3D::PinnedPoint *pinned_point; +void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) { + SoftBody3D::PinnedPoint *pinned_point; if (-1 == _get_pinned_point(p_point_index, pinned_point)) { // Create new PinnedPoint pp; @@ -759,7 +759,7 @@ void SoftDynamicBody3D::_add_pinned_point(int p_point_index, const NodePath &p_s } } -void SoftDynamicBody3D::_reset_points_offsets() { +void SoftBody3D::_reset_points_offsets() { if (!Engine::get_singleton()->is_editor_hint()) { return; } @@ -781,25 +781,25 @@ void SoftDynamicBody3D::_reset_points_offsets() { } } -void SoftDynamicBody3D::_remove_pinned_point(int p_point_index) { +void SoftBody3D::_remove_pinned_point(int p_point_index) { const int id(_has_pinned_point(p_point_index)); if (-1 != id) { pinned_points.remove_at(id); } } -int SoftDynamicBody3D::_get_pinned_point(int p_point_index, SoftDynamicBody3D::PinnedPoint *&r_point) const { +int SoftBody3D::_get_pinned_point(int p_point_index, SoftBody3D::PinnedPoint *&r_point) const { const int id = _has_pinned_point(p_point_index); if (-1 == id) { r_point = nullptr; return -1; } else { - r_point = const_cast<SoftDynamicBody3D::PinnedPoint *>(&pinned_points.ptr()[id]); + r_point = const_cast<SoftBody3D::PinnedPoint *>(&pinned_points.ptr()[id]); return id; } } -int SoftDynamicBody3D::_has_pinned_point(int p_point_index) const { +int SoftBody3D::_has_pinned_point(int p_point_index) const { const PinnedPoint *r = pinned_points.ptr(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { if (p_point_index == r[i].point_index) { diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_body_3d.h index 2b86fe2cae..40f3d6f1f4 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_body_3d.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* soft_dynamic_body_3d.h */ +/* soft_body_3d.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SOFT_DYNAMIC_BODY_3D_H -#define SOFT_DYNAMIC_BODY_3D_H +#ifndef SOFT_BODY_3D_H +#define SOFT_BODY_3D_H #include "scene/3d/mesh_instance_3d.h" #include "servers/physics_server_3d.h" class PhysicsBody3D; -class SoftDynamicBody3D; +class SoftBody3D; -class SoftDynamicBodyRenderingServerHandler : public PhysicsServer3DRenderingServerHandler { - friend class SoftDynamicBody3D; +class SoftBodyRenderingServerHandler : public PhysicsServer3DRenderingServerHandler { + friend class SoftBody3D; RID mesh; int surface = 0; @@ -50,7 +50,7 @@ class SoftDynamicBodyRenderingServerHandler : public PhysicsServer3DRenderingSer uint8_t *write_buffer = nullptr; private: - SoftDynamicBodyRenderingServerHandler(); + SoftBodyRenderingServerHandler(); bool is_ready(RID p_mesh_rid) const { return mesh.is_valid() && mesh == p_mesh_rid; } void prepare(RID p_mesh_rid, int p_surface); void clear(); @@ -64,8 +64,8 @@ public: void set_aabb(const AABB &p_aabb) override; }; -class SoftDynamicBody3D : public MeshInstance3D { - GDCLASS(SoftDynamicBody3D, MeshInstance3D); +class SoftBody3D : public MeshInstance3D { + GDCLASS(SoftBody3D, MeshInstance3D); public: enum DisableMode { @@ -85,7 +85,7 @@ public: }; private: - SoftDynamicBodyRenderingServerHandler *rendering_server_handler = nullptr; + SoftBodyRenderingServerHandler *rendering_server_handler = nullptr; RID physics_rid; @@ -182,8 +182,8 @@ public: void set_ray_pickable(bool p_ray_pickable); bool is_ray_pickable() const; - SoftDynamicBody3D(); - ~SoftDynamicBody3D(); + SoftBody3D(); + ~SoftBody3D(); private: void _make_cache_dirty(); @@ -198,6 +198,6 @@ private: int _has_pinned_point(int p_point_index) const; }; -VARIANT_ENUM_CAST(SoftDynamicBody3D::DisableMode); +VARIANT_ENUM_CAST(SoftBody3D::DisableMode); -#endif // SOFT_DYNAMIC_BODY_3D_H +#endif // SOFT_BODY_3D_H diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 212d220ace..669c3eb7fd 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -1004,14 +1004,17 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &p_property) const { names.sort_custom<StringName::AlphCompare>(); bool current_found = false; + bool is_first_element = true; - for (List<StringName>::Element *E = names.front(); E; E = E->next()) { - if (E->prev()) { + for (const StringName &E : names) { + if (!is_first_element) { p_property.hint_string += ","; + } else { + is_first_element = false; } - p_property.hint_string += String(E->get()); - if (animation == E->get()) { + p_property.hint_string += String(E); + if (animation == E) { current_found = true; } } diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 42ed52c9f2..d61b49eaa7 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -807,7 +807,7 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) { } void VehicleBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { - RigidDynamicBody3D::_body_state_changed(p_state); + RigidBody3D::_body_state_changed(p_state); real_t step = p_state->get_step(); diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index 2f3a37af2a..5c4f4beaea 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -152,8 +152,8 @@ public: VehicleWheel3D(); }; -class VehicleBody3D : public RigidDynamicBody3D { - GDCLASS(VehicleBody3D, RigidDynamicBody3D); +class VehicleBody3D : public RigidBody3D { + GDCLASS(VehicleBody3D, RigidBody3D); real_t engine_force = 0.0; real_t brake = 0.0; diff --git a/scene/SCsub b/scene/SCsub index 92288211bb..b4b2d6dd0a 100644 --- a/scene/SCsub +++ b/scene/SCsub @@ -17,6 +17,7 @@ SConscript("animation/SCsub") SConscript("audio/SCsub") SConscript("resources/SCsub") SConscript("debugger/SCsub") +SConscript("theme/SCsub") # Build it all as a library lib = env.add_library("scene", env.scene_sources) diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 4b3d7fd0a6..afb52de307 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -403,7 +403,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s bool do_start = (p_seek && p_time == 0) || play_start || current == StringName(); if (do_start) { - if (p_state_machine->start_node != StringName() && p_seek && p_time == 0) { + if (p_state_machine->start_node != StringName() && p_seek && p_time == 0 && current == StringName()) { current = p_state_machine->start_node; } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 48626ccc1b..073f61bfdd 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1151,7 +1151,7 @@ void AnimationPlayer::_animation_update_transforms() { } #endif - static_cast<Node2D *>(pa->object)->set_rotation(Math::deg2rad((double)pa->value_accum)); + static_cast<Node2D *>(pa->object)->set_rotation(Math::deg_to_rad((double)pa->value_accum)); } break; case SP_NODE2D_SCALE: { #ifdef DEBUG_ENABLED @@ -1501,7 +1501,7 @@ bool AnimationPlayer::has_animation(const StringName &p_name) const { } Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const { - ERR_FAIL_COND_V_MSG(!animation_set.has(p_name), Ref<Animation>(), vformat("Animation not found: %s.", p_name)); + ERR_FAIL_COND_V_MSG(!animation_set.has(p_name), Ref<Animation>(), vformat("Animation not found: \"%s\".", p_name)); const AnimationData &data = animation_set[p_name]; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 7dbe892299..d06324f0aa 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -602,6 +602,8 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { track_value->object = child; } + track_value->is_using_angle = anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE; + track_value->subpath = leftover_path; track_value->object_id = track_value->object->get_instance_id(); @@ -804,6 +806,10 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { default: { } } + } else if (track_cache_type == Animation::TYPE_VALUE) { + // If it has at least one angle interpolation, it also uses angle interpolation for blending. + TrackCacheValue *track_value = memnew(TrackCacheValue); + track_value->is_using_angle |= anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_LINEAR_ANGLE || anim->track_get_interpolation_type(i) == Animation::INTERPOLATION_CUBIC_ANGLE; } track->setup_pass = setup_pass; @@ -1353,8 +1359,28 @@ void AnimationTree::_process_graph(double p_delta) { t->value = t->init_value; } - Variant::sub(value, t->init_value, value); - Variant::blend(t->value, value, blend, t->value); + // Special case for angle interpolation. + if (t->is_using_angle) { + // For blending consistency, it prevents rotation of more than 180 degrees from init_value. + // This is the same as for Quaternion blends. + float rot_a = t->value; + float rot_b = value; + float rot_init = t->init_value; + rot_a = Math::fposmod(rot_a, (float)Math_TAU); + rot_b = Math::fposmod(rot_b, (float)Math_TAU); + rot_init = Math::fposmod(rot_init, (float)Math_TAU); + if (rot_init < Math_PI) { + rot_a = rot_a > rot_init + Math_PI ? rot_a - Math_TAU : rot_a; + rot_b = rot_b > rot_init + Math_PI ? rot_b - Math_TAU : rot_b; + } else { + rot_a = rot_a < rot_init - Math_PI ? rot_a + Math_TAU : rot_a; + rot_b = rot_b < rot_init - Math_PI ? rot_b + Math_TAU : rot_b; + } + t->value = Math::fposmod(rot_a + (rot_b - rot_init) * (float)blend, (float)Math_TAU); + } else { + Variant::sub(value, t->init_value, value); + Variant::blend(t->value, value, blend, t->value); + } } else { if (blend < CMP_EPSILON) { continue; //nothing to blend @@ -1528,7 +1554,7 @@ void AnimationTree::_process_graph(double p_delta) { } } - real_t db = Math::linear2db(MAX(blend, 0.00001)); + real_t db = Math::linear_to_db(MAX(blend, 0.00001)); if (t->object->has_method(SNAME("set_unit_db"))) { t->object->call(SNAME("set_unit_db"), db); } else { diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index ee51a54557..ee0c0303dc 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -233,6 +233,7 @@ private: Variant init_value; Variant value; Vector<StringName> subpath; + bool is_using_angle = false; TrackCacheValue() { type = Animation::TYPE_VALUE; } }; diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 7c85b650bf..04feb0dc6f 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -256,7 +256,7 @@ Vector<AudioFrame> AudioStreamPlayer::_get_volume_vector() { channel_volume_db = AudioFrame(0, 0); } - float volume_linear = Math::db2linear(volume_db); + float volume_linear = Math::db_to_linear(volume_db); // Set the volume vector up according to the speaker mode and mix target. // TODO do we need to scale the volume down when we output to more channels? diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 87a7355bb2..cee7c049a9 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -65,8 +65,9 @@ void BaseButton::gui_input(const Ref<InputEvent> &p_event) { bool button_masked = mouse_button.is_valid() && (mouse_button_to_mask(mouse_button->get_button_index()) & button_mask) != MouseButton::NONE; if (button_masked || ui_accept) { was_mouse_pressed = button_masked; - on_action_event(p_event); + was_mouse_pressed = false; + return; } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 9eef45f412..a417e7b9e2 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -536,7 +536,7 @@ void ColorPicker::_add_preset_button(int p_size, const Color &p_color) { btn_preset->set_preset_color(p_color); btn_preset->set_custom_minimum_size(Size2(p_size, p_size)); btn_preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input).bind(p_color)); - btn_preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1))); + btn_preset->set_tooltip_text(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1))); preset_container->add_child(btn_preset); } @@ -1236,7 +1236,7 @@ ColorPicker::ColorPicker() : btn_pick->set_flat(true); hb_smpl->add_child(btn_pick); btn_pick->set_toggle_mode(true); - btn_pick->set_tooltip(RTR("Pick a color from the editor window.")); + btn_pick->set_tooltip_text(RTR("Pick a color from the editor window.")); btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed)); VBoxContainer *vbl = memnew(VBoxContainer); @@ -1276,7 +1276,7 @@ ColorPicker::ColorPicker() : text_type = memnew(Button); hhb->add_child(text_type); text_type->set_text("#"); - text_type->set_tooltip(RTR("Switch between hexadecimal and code values.")); + text_type->set_tooltip_text(RTR("Switch between hexadecimal and code values.")); if (Engine::get_singleton()->is_editor_hint()) { text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled)); } else { @@ -1337,7 +1337,7 @@ ColorPicker::ColorPicker() : btn_add_preset = memnew(Button); btn_add_preset->set_icon_alignment(HORIZONTAL_ALIGNMENT_CENTER); - btn_add_preset->set_tooltip(RTR("Add current color as a preset.")); + btn_add_preset->set_tooltip_text(RTR("Add current color as a preset.")); btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed)); preset_container->add_child(btn_add_preset); } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 03fcef17f5..4de16a0a29 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -43,6 +43,7 @@ #include "scene/main/canvas_layer.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" +#include "scene/theme/theme_db.h" #include "servers/rendering_server.h" #include "servers/text_server.h" @@ -193,15 +194,15 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List List<StringName> sn; String pf = p_function; if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { - Theme::get_default()->get_color_list(get_class(), &sn); + ThemeDB::get_singleton()->get_default_theme()->get_color_list(get_class(), &sn); } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { - Theme::get_default()->get_stylebox_list(get_class(), &sn); + ThemeDB::get_singleton()->get_default_theme()->get_stylebox_list(get_class(), &sn); } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { - Theme::get_default()->get_font_list(get_class(), &sn); + ThemeDB::get_singleton()->get_default_theme()->get_font_list(get_class(), &sn); } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { - Theme::get_default()->get_font_size_list(get_class(), &sn); + ThemeDB::get_singleton()->get_default_theme()->get_font_size_list(get_class(), &sn); } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { - Theme::get_default()->get_constant_list(get_class(), &sn); + ThemeDB::get_singleton()->get_default_theme()->get_constant_list(get_class(), &sn); } sn.sort_custom<StringName::AlphCompare>(); @@ -252,36 +253,36 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("theme_override_icons/")) { String dname = name.get_slicec('/', 1); if (data.icon_override.has(dname)) { - data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.icon_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else if (name.begins_with("theme_override_styles/")) { String dname = name.get_slicec('/', 1); if (data.style_override.has(dname)) { - data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.style_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else if (name.begins_with("theme_override_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.font_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else if (name.begins_with("theme_override_font_sizes/")) { String dname = name.get_slicec('/', 1); data.font_size_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else if (name.begins_with("theme_override_colors/")) { String dname = name.get_slicec('/', 1); data.color_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else if (name.begins_with("theme_override_constants/")) { String dname = name.get_slicec('/', 1); data.constant_override.erase(dname); - notification(NOTIFICATION_THEME_CHANGED); + _notify_theme_override_changed(); } else { return false; } @@ -344,7 +345,7 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const { } void Control::_get_property_list(List<PropertyInfo> *p_list) const { - Ref<Theme> theme = Theme::get_default(); + Ref<Theme> theme = ThemeDB::get_singleton()->get_default_theme(); p_list->push_back(PropertyInfo(Variant::NIL, TTRC("Theme Overrides"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP)); @@ -429,9 +430,9 @@ void Control::_validate_property(PropertyInfo &p_property) const { // Only the default theme and the project theme are used for the list of options. // This is an imposed limitation to simplify the logic needed to leverage those options. - Theme::get_default()->get_type_variation_list(get_class_name(), &names); - if (Theme::get_project_default().is_valid()) { - Theme::get_project_default()->get_type_variation_list(get_class_name(), &names); + ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names); + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names); } names.sort_custom<StringName::AlphCompare>(); @@ -2260,62 +2261,62 @@ bool Control::is_clipping_contents() { // Theming. -void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) { +void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign) { Control *c = Object::cast_to<Control>(p_at); - - if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated - return; - } - Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; - if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated + if (!c && !w) { + // Theme inheritance chains are broken by nodes that aren't Control or Window. return; } - for (int i = 0; i < p_at->get_child_count(); i++) { - CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i)); - if (child) { - _propagate_theme_changed(child, p_owner, p_owner_window, p_assign); - } else { - Window *window = Object::cast_to<Window>(p_at->get_child(i)); - if (window) { - _propagate_theme_changed(window, p_owner, p_owner_window, p_assign); - } + bool assign = p_assign; + if (c) { + if (c != p_owner && c->data.theme.is_valid()) { + // Has a theme, so we don't want to change the theme owner, + // but we still want to propagate in case this child has theme items + // it inherits from the theme this node uses. + // See https://github.com/godotengine/godot/issues/62844. + assign = false; } - } - if (c) { - if (p_assign) { + if (assign) { c->data.theme_owner = p_owner; c->data.theme_owner_window = p_owner_window; } - c->notification(Control::NOTIFICATION_THEME_CHANGED); - c->emit_signal(SceneStringNames::get_singleton()->theme_changed); - } - if (w) { - if (p_assign) { + if (p_notify) { + c->notification(Control::NOTIFICATION_THEME_CHANGED); + } + } else if (w) { + if (w != p_owner_window && w->theme.is_valid()) { + // Same as above. + assign = false; + } + + if (assign) { w->theme_owner = p_owner; w->theme_owner_window = p_owner_window; } - w->notification(Window::NOTIFICATION_THEME_CHANGED); - w->emit_signal(SceneStringNames::get_singleton()->theme_changed); + + if (p_notify) { + w->notification(Window::NOTIFICATION_THEME_CHANGED); + } } -} -void Control::_theme_changed() { - _propagate_theme_changed(this, this, nullptr, false); + for (int i = 0; i < p_at->get_child_count(); i++) { + _propagate_theme_changed(p_at->get_child(i), p_owner, p_owner_window, p_notify, assign); + } } -void Control::_theme_property_override_changed() { - notification(NOTIFICATION_THEME_CHANGED); - emit_signal(SceneStringNames::get_singleton()->theme_changed); - update_minimum_size(); // Overrides are likely to affect minimum size. +void Control::_theme_changed() { + if (is_inside_tree()) { + _propagate_theme_changed(this, this, nullptr, true, false); + } } -void Control::_notify_theme_changed() { - if (!data.bulk_theme_override) { +void Control::_notify_theme_override_changed() { + if (!data.bulk_theme_override && is_inside_tree()) { notification(NOTIFICATION_THEME_CHANGED); } } @@ -2339,28 +2340,25 @@ void Control::set_theme(const Ref<Theme> &p_theme) { } data.theme = p_theme; - if (!p_theme.is_null()) { - data.theme_owner = this; - data.theme_owner_window = nullptr; - _propagate_theme_changed(this, this, nullptr); - } else { - Control *parent_c = Object::cast_to<Control>(get_parent()); + if (data.theme.is_valid()) { + _propagate_theme_changed(this, this, nullptr, is_inside_tree(), true); + data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), CONNECT_DEFERRED); + return; + } - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); - } else { - Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); - } else { - Control::_propagate_theme_changed(this, nullptr, nullptr); - } - } + Control *parent_c = Object::cast_to<Control>(get_parent()); + if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { + _propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + return; } - if (data.theme.is_valid()) { - data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), CONNECT_DEFERRED); + Window *parent_w = cast_to<Window>(get_parent()); + if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { + _propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + return; } + + _propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); } Ref<Theme> Control::get_theme() const { @@ -2372,7 +2370,9 @@ void Control::set_theme_type_variation(const StringName &p_theme_type) { return; } data.theme_type_variation = p_theme_type; - _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); + if (is_inside_tree()) { + notification(NOTIFICATION_THEME_CHANGED); + } } StringName Control::get_theme_type_variation() const { @@ -2420,22 +2420,22 @@ T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner } // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(p_data_type, p_name, E); } } } // Lastly, fall back on the items defined in the default Theme, if they exist. for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_default()->get_theme_item(p_data_type, p_name, E); + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, E); } } // If they don't exist, use any type to return the default/empty value. - return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(p_data_type, p_name, p_theme_types[0]); } bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { @@ -2476,9 +2476,9 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow } // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -2486,7 +2486,7 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow // Lastly, fall back on the items defined in the default Theme, if they exist. for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(p_data_type, p_name, E)) { return true; } } @@ -2495,13 +2495,13 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { - Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(data.theme_type_variation) != StringName()) { + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); } else { - Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); } } else { - Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); } } @@ -2697,93 +2697,93 @@ void Control::add_theme_icon_override(const StringName &p_name, const Ref<Textur ERR_FAIL_COND(!p_icon.is_valid()); if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.icon_override[p_name] = p_icon; - data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_override_changed(); } void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { ERR_FAIL_COND(!p_style.is_valid()); if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.style_override[p_name] = p_style; - data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_override_changed(); } void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { ERR_FAIL_COND(!p_font.is_valid()); if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.font_override[p_name] = p_font; - data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_notify_theme_override_changed), CONNECT_REFERENCE_COUNTED); + _notify_theme_override_changed(); } void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { data.font_size_override[p_name] = p_font_size; - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { data.color_override[p_name] = p_color; - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { data.constant_override[p_name] = p_constant; - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_icon_override(const StringName &p_name) { if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.icon_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_style_override(const StringName &p_name) { if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.style_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_font_override(const StringName &p_name) { if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } data.font_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_font_size_override(const StringName &p_name) { data.font_size_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_color_override(const StringName &p_name) { data.color_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } void Control::remove_theme_constant_override(const StringName &p_name) { data.constant_override.erase(p_name); - _notify_theme_changed(); + _notify_theme_override_changed(); } bool Control::has_theme_icon_override(const StringName &p_name) const { @@ -2852,17 +2852,17 @@ float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_ } // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_base_scale()) { - return Theme::get_project_default()->get_default_base_scale(); + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_base_scale(); } } // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_base_scale()) { - return Theme::get_default()->get_default_base_scale(); + if (ThemeDB::get_singleton()->get_default_theme()->has_default_base_scale()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_base_scale(); } - return Theme::get_fallback_base_scale(); + return ThemeDB::get_singleton()->get_fallback_base_scale(); } float Control::get_theme_default_base_scale() const { @@ -2903,17 +2903,17 @@ Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_th } // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font()) { - return Theme::get_project_default()->get_default_font(); + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font(); } } // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font()) { - return Theme::get_default()->get_default_font(); + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font(); } - return Theme::get_fallback_font(); + return ThemeDB::get_singleton()->get_fallback_font(); } Ref<Font> Control::get_theme_default_font() const { @@ -2954,17 +2954,17 @@ int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_the } // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font_size()) { - return Theme::get_project_default()->get_default_font_size(); + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_project_theme()->get_default_font_size(); } } // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font_size()) { - return Theme::get_default()->get_default_font_size(); + if (ThemeDB::get_singleton()->get_default_theme()->has_default_font_size()) { + return ThemeDB::get_singleton()->get_default_theme()->get_default_font_size(); } - return Theme::get_fallback_font_size(); + return ThemeDB::get_singleton()->get_fallback_font_size(); } int Control::get_theme_default_font_size() const { @@ -2981,7 +2981,7 @@ void Control::end_bulk_theme_override() { ERR_FAIL_COND(!data.bulk_theme_override); data.bulk_theme_override = false; - _notify_theme_changed(); + _notify_theme_override_changed(); } // Internationalization. @@ -3063,12 +3063,12 @@ bool Control::is_auto_translating() const { // Extra properties. -void Control::set_tooltip(const String &p_tooltip) { - data.tooltip = p_tooltip; +void Control::set_tooltip_text(const String &p_hint) { + data.tooltip = p_hint; update_configuration_warnings(); } -String Control::_get_tooltip() const { +String Control::get_tooltip_text() const { return data.tooltip; } @@ -3087,37 +3087,26 @@ Control *Control::make_custom_tooltip(const String &p_text) const { // Base object overrides. void Control::add_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_c, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff - } - - Window *child_w = Object::cast_to<Window>(p_child); - - if (child_w && child_w->theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_w, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff + // We propagate when this node uses a custom theme, so it can pass it on to its children. + if (data.theme_owner || data.theme_owner_window) { + // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. + _propagate_theme_changed(p_child, data.theme_owner, data.theme_owner_window, false, true); } } void Control::remove_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { - _propagate_theme_changed(child_c, nullptr, nullptr); - } - - Window *child_w = Object::cast_to<Window>(p_child); - - if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { - _propagate_theme_changed(child_w, nullptr, nullptr); + // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. + if (data.theme_owner || data.theme_owner_window) { + _propagate_theme_changed(p_child, nullptr, nullptr, false, true); } } void Control::_notification(int p_notification) { switch (p_notification) { case NOTIFICATION_ENTER_TREE: { - _invalidate_theme_cache(); + // Need to defer here, because theme owner information might be set in + // add_child_notify, which doesn't get called until right after this. + call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); } break; case NOTIFICATION_POST_ENTER_TREE: { @@ -3142,18 +3131,6 @@ void Control::_notification(int p_notification) { data.parent_window = Object::cast_to<Window>(get_parent()); data.is_rtl_dirty = true; - if (data.theme.is_null()) { - if (data.parent && (data.parent->data.theme_owner || data.parent->data.theme_owner_window)) { - data.theme_owner = data.parent->data.theme_owner; - data.theme_owner_window = data.parent->data.theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } else if (data.parent_window && (data.parent_window->theme_owner || data.parent_window->theme_owner_window)) { - data.theme_owner = data.parent_window->theme_owner; - data.theme_owner_window = data.parent_window->theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } - } - CanvasItem *node = this; bool has_parent_control = false; @@ -3257,6 +3234,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_THEME_CHANGED: { + emit_signal(SceneStringNames::get_singleton()->theme_changed); _invalidate_theme_cache(); update_minimum_size(); update(); @@ -3406,9 +3384,9 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_v_grow_direction", "direction"), &Control::set_v_grow_direction); ClassDB::bind_method(D_METHOD("get_v_grow_direction"), &Control::get_v_grow_direction); - ClassDB::bind_method(D_METHOD("set_tooltip", "tooltip"), &Control::set_tooltip); + ClassDB::bind_method(D_METHOD("set_tooltip_text", "hint"), &Control::set_tooltip_text); + ClassDB::bind_method(D_METHOD("get_tooltip_text"), &Control::get_tooltip_text); ClassDB::bind_method(D_METHOD("get_tooltip", "at_position"), &Control::get_tooltip, DEFVAL(Point2())); - ClassDB::bind_method(D_METHOD("_get_tooltip"), &Control::_get_tooltip); ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Control::set_default_cursor_shape); ClassDB::bind_method(D_METHOD("get_default_cursor_shape"), &Control::get_default_cursor_shape); @@ -3498,8 +3476,8 @@ void Control::_bind_methods() { ADD_GROUP("Auto Translate", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); - ADD_GROUP("Hint", "hint_"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip"); + ADD_GROUP("Tooltip", "tooltip_"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "tooltip_text", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip_text", "get_tooltip_text"); ADD_GROUP("Focus", "focus_"); ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "focus_neighbor_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbor", "get_focus_neighbor", SIDE_LEFT); @@ -3626,13 +3604,13 @@ void Control::_bind_methods() { Control::~Control() { // Resources need to be disconnected. for (KeyValue<StringName, Ref<Texture2D>> &E : data.icon_override) { - E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + E.value->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } for (KeyValue<StringName, Ref<StyleBox>> &E : data.style_override) { - E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + E.value->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } for (KeyValue<StringName, Ref<Font>> &E : data.font_override) { - E.value->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + E.value->disconnect("changed", callable_mp(this, &Control::_notify_theme_override_changed)); } // Then override maps can be simply cleared. diff --git a/scene/gui/control.h b/scene/gui/control.h index c69067f82f..6215594ae0 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -300,11 +300,10 @@ private: // Theming. void _theme_changed(); - void _theme_property_override_changed(); - void _notify_theme_changed(); + void _notify_theme_override_changed(); void _invalidate_theme_cache(); - static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign = true); + static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_notify, bool p_assign); template <class T> static T get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); @@ -313,7 +312,7 @@ private: // Extra properties. - String _get_tooltip() const; + String get_tooltip_text() const; protected: // Dynamic properties. @@ -605,7 +604,7 @@ public: // Extra properties. - void set_tooltip(const String &p_tooltip); + void set_tooltip_text(const String &text); virtual String get_tooltip(const Point2 &p_pos) const; virtual Control *make_custom_tooltip(const String &p_text) const; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 7965b12edd..57655afb4c 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -1015,13 +1015,13 @@ FileDialog::FileDialog() { dir_prev = memnew(Button); dir_prev->set_flat(true); - dir_prev->set_tooltip(RTR("Go to previous folder.")); + dir_prev->set_tooltip_text(RTR("Go to previous folder.")); dir_next = memnew(Button); dir_next->set_flat(true); - dir_next->set_tooltip(RTR("Go to next folder.")); + dir_next->set_tooltip_text(RTR("Go to next folder.")); dir_up = memnew(Button); dir_up->set_flat(true); - dir_up->set_tooltip(RTR("Go to parent folder.")); + dir_up->set_tooltip_text(RTR("Go to parent folder.")); hbc->add_child(dir_prev); hbc->add_child(dir_next); hbc->add_child(dir_up); @@ -1045,7 +1045,7 @@ FileDialog::FileDialog() { refresh = memnew(Button); refresh->set_flat(true); - refresh->set_tooltip(RTR("Refresh files.")); + refresh->set_tooltip_text(RTR("Refresh files.")); refresh->connect("pressed", callable_mp(this, &FileDialog::update_file_list)); hbc->add_child(refresh); @@ -1053,7 +1053,7 @@ FileDialog::FileDialog() { show_hidden->set_flat(true); 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->set_tooltip_text(RTR("Toggle the visibility of hidden files.")); show_hidden->connect("toggled", callable_mp(this, &FileDialog::set_show_hidden_files)); hbc->add_child(show_hidden); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index e6198b44ff..00f2e48601 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -607,13 +607,16 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_color = Object::cast_to<GraphNode>(to)->get_connection_input_color(E.to_port); connecting_target = false; connecting_to = pos; - just_disconnected = true; - emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); - to = get_node(String(connecting_from)); //maybe it was erased - if (Object::cast_to<GraphNode>(to)) { - connecting = true; - emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); + if (connecting_type >= 0) { + just_disconnected = true; + + emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); + to = get_node(String(connecting_from)); //maybe it was erased + if (Object::cast_to<GraphNode>(to)) { + connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); + } } return; } @@ -621,7 +624,6 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } - connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = true; @@ -629,8 +631,11 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_color = gn->get_connection_output_color(j); connecting_target = false; connecting_to = pos; - just_disconnected = false; - emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); + if (connecting_type >= 0) { + connecting = true; + just_disconnected = false; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); + } return; } } @@ -657,11 +662,13 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_to = pos; just_disconnected = true; - emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); - fr = get_node(String(connecting_from)); //maybe it was erased - if (Object::cast_to<GraphNode>(fr)) { - connecting = true; - emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); + if (connecting_type >= 0) { + emit_signal(SNAME("disconnection_request"), E.from, E.from_port, E.to, E.to_port); + fr = get_node(String(connecting_from)); //maybe it was erased + if (Object::cast_to<GraphNode>(fr)) { + connecting = true; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, true); + } } return; } @@ -669,7 +676,6 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { } } - connecting = true; connecting_from = gn->get_name(); connecting_index = j; connecting_out = false; @@ -677,8 +683,11 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_color = gn->get_connection_input_color(j); connecting_target = false; connecting_to = pos; - just_disconnected = false; - emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); + if (connecting_type >= 0) { + connecting = true; + just_disconnected = false; + emit_signal(SNAME("connection_drag_started"), connecting_from, connecting_index, false); + } return; } } @@ -1127,7 +1136,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { drag_accum += mm->get_relative(); for (int i = get_child_count() - 1; i >= 0; i--) { GraphNode *gn = Object::cast_to<GraphNode>(get_child(i)); - if (gn && gn->is_selected()) { + if (gn && gn->is_selected() && gn->is_draggable()) { Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom; // Snapping can be toggled temporarily by holding down Ctrl. @@ -1166,7 +1175,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } else if (gn->is_selected() && !box_selection_mode_additive) { emit_signal(SNAME("node_deselected"), gn); } - gn->set_selected(box_selection_mode_additive); + if (gn->is_selectable()) { + gn->set_selected(box_selection_mode_additive); + } } else { bool select = (previous_selected.find(gn) != nullptr); if (gn->is_selected() && !select) { @@ -1174,7 +1185,9 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } else if (!gn->is_selected() && select) { emit_signal(SNAME("node_selected"), gn); } - gn->set_selected(select); + if (gn->is_selectable()) { + gn->set_selected(select); + } } } @@ -1193,7 +1206,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { continue; } - bool select = (previous_selected.find(gn) != nullptr); + bool select = (gn->is_selectable() && previous_selected.find(gn) != nullptr); if (gn->is_selected() && !select) { emit_signal(SNAME("node_deselected"), gn); } else if (!gn->is_selected() && select) { @@ -1285,7 +1298,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (o_gn) { if (o_gn == gn) { - o_gn->set_selected(true); + o_gn->set_selected(o_gn->is_selectable()); } else { if (o_gn->is_selected()) { emit_signal(SNAME("node_deselected"), o_gn); @@ -1296,7 +1309,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) { } } - gn->set_selected(true); + gn->set_selected(gn->is_selectable()); for (int i = 0; i < get_child_count(); i++) { GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i)); if (!o_gn) { @@ -1711,6 +1724,19 @@ bool GraphEdit::is_minimap_enabled() const { return minimap_button->is_pressed(); } +void GraphEdit::set_arrange_nodes_button_hidden(bool p_enable) { + arrange_nodes_button_hidden = p_enable; + if (arrange_nodes_button_hidden) { + layout_button->hide(); + } else { + layout_button->show(); + } +} + +bool GraphEdit::is_arrange_nodes_button_hidden() const { + return arrange_nodes_button_hidden; +} + void GraphEdit::_minimap_toggled() { if (is_minimap_enabled()) { minimap->set_visible(true); @@ -2343,6 +2369,9 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_minimap_enabled", "enable"), &GraphEdit::set_minimap_enabled); ClassDB::bind_method(D_METHOD("is_minimap_enabled"), &GraphEdit::is_minimap_enabled); + ClassDB::bind_method(D_METHOD("set_arrange_nodes_button_hidden", "enable"), &GraphEdit::set_arrange_nodes_button_hidden); + ClassDB::bind_method(D_METHOD("is_arrange_nodes_button_hidden"), &GraphEdit::is_arrange_nodes_button_hidden); + 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); @@ -2382,6 +2411,9 @@ void GraphEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "minimap_size", PROPERTY_HINT_NONE, "suffix:px"), "set_minimap_size", "get_minimap_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "minimap_opacity"), "set_minimap_opacity", "get_minimap_opacity"); + ADD_GROUP("UI", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arrange_nodes_button_hidden"), "set_arrange_nodes_button_hidden", "is_arrange_nodes_button_hidden"); + 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"))); @@ -2464,28 +2496,28 @@ GraphEdit::GraphEdit() { zoom_minus = memnew(Button); zoom_minus->set_flat(true); zoom_hb->add_child(zoom_minus); - zoom_minus->set_tooltip(RTR("Zoom Out")); + zoom_minus->set_tooltip_text(RTR("Zoom Out")); zoom_minus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_minus)); zoom_minus->set_focus_mode(FOCUS_NONE); zoom_reset = memnew(Button); zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); - zoom_reset->set_tooltip(RTR("Zoom Reset")); + zoom_reset->set_tooltip_text(RTR("Zoom Reset")); zoom_reset->connect("pressed", callable_mp(this, &GraphEdit::_zoom_reset)); zoom_reset->set_focus_mode(FOCUS_NONE); zoom_plus = memnew(Button); zoom_plus->set_flat(true); zoom_hb->add_child(zoom_plus); - zoom_plus->set_tooltip(RTR("Zoom In")); + zoom_plus->set_tooltip_text(RTR("Zoom In")); zoom_plus->connect("pressed", callable_mp(this, &GraphEdit::_zoom_plus)); zoom_plus->set_focus_mode(FOCUS_NONE); snap_button = memnew(Button); snap_button->set_flat(true); snap_button->set_toggle_mode(true); - snap_button->set_tooltip(RTR("Enable snap and show grid.")); + snap_button->set_tooltip_text(RTR("Enable snap and show grid.")); snap_button->connect("pressed", callable_mp(this, &GraphEdit::_snap_toggled)); snap_button->set_pressed(true); snap_button->set_focus_mode(FOCUS_NONE); @@ -2502,7 +2534,7 @@ GraphEdit::GraphEdit() { minimap_button = memnew(Button); minimap_button->set_flat(true); minimap_button->set_toggle_mode(true); - minimap_button->set_tooltip(RTR("Enable grid minimap.")); + minimap_button->set_tooltip_text(RTR("Enable grid minimap.")); minimap_button->connect("pressed", callable_mp(this, &GraphEdit::_minimap_toggled)); minimap_button->set_pressed(true); minimap_button->set_focus_mode(FOCUS_NONE); @@ -2511,7 +2543,7 @@ GraphEdit::GraphEdit() { layout_button = memnew(Button); layout_button->set_flat(true); zoom_hb->add_child(layout_button); - layout_button->set_tooltip(RTR("Arrange nodes.")); + layout_button->set_tooltip_text(RTR("Arrange nodes.")); layout_button->connect("pressed", callable_mp(this, &GraphEdit::arrange_nodes)); layout_button->set_focus_mode(FOCUS_NONE); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index b8c9be9983..0a0676699f 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -133,6 +133,8 @@ private: void _pan_callback(Vector2 p_scroll_vec); void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt); + bool arrange_nodes_button_hidden = false; + bool connecting = false; String connecting_from; bool connecting_out = false; @@ -323,6 +325,9 @@ public: void set_minimap_enabled(bool p_enable); bool is_minimap_enabled() const; + void set_arrange_nodes_button_hidden(bool p_enable); + bool is_arrange_nodes_button_hidden() const; + GraphEditFilter *get_top_layer() const { return top_layer; } GraphEditMinimap *get_minimap() const { return minimap; } void get_connection_list(List<Connection> *r_connections) const; diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 7d31e929dc..b07d401e6b 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -1003,6 +1003,22 @@ bool GraphNode::is_resizable() const { return resizable; } +void GraphNode::set_draggable(bool p_draggable) { + draggable = p_draggable; +} + +bool GraphNode::is_draggable() { + return draggable; +} + +void GraphNode::set_selectable(bool p_selectable) { + selectable = p_selectable; +} + +bool GraphNode::is_selectable() { + return selectable; +} + Vector<int> GraphNode::get_allowed_size_flags_horizontal() const { Vector<int> flags; flags.append(SIZE_FILL); @@ -1064,6 +1080,12 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphNode::set_resizable); ClassDB::bind_method(D_METHOD("is_resizable"), &GraphNode::is_resizable); + ClassDB::bind_method(D_METHOD("set_draggable", "draggable"), &GraphNode::set_draggable); + ClassDB::bind_method(D_METHOD("is_draggable"), &GraphNode::is_draggable); + + ClassDB::bind_method(D_METHOD("set_selectable", "selectable"), &GraphNode::set_selectable); + ClassDB::bind_method(D_METHOD("is_selectable"), &GraphNode::is_selectable); + ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphNode::set_selected); ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected); @@ -1089,6 +1111,8 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_position_offset", "get_position_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draggable"), "set_draggable", "is_draggable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selectable"), "set_selectable", "is_selectable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selected"), "set_selected", "is_selected"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "comment"), "set_comment", "is_comment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay"); diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index d575b6ceed..9c8f926403 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -67,6 +67,8 @@ private: Vector2 position_offset; bool comment = false; bool resizable = false; + bool draggable = true; + bool selectable = true; bool resizing = false; Vector2 resizing_from; @@ -183,6 +185,12 @@ public: void set_resizable(bool p_enable); bool is_resizable() const; + void set_draggable(bool p_draggable); + bool is_draggable(); + + void set_selectable(bool p_selectable); + bool is_selectable(); + virtual Size2 get_minimum_size() const override; virtual Vector<int> get_allowed_size_flags_horizontal() const override; diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 7a88afaa3b..fa7d4195cb 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -279,8 +279,8 @@ void Label::_notification(int p_what) { return; // Nothing new. } xl_text = new_text; - if (percent_visible < 1) { - visible_chars = get_total_character_count() * percent_visible; + if (visible_ratio < 1) { + visible_chars = get_total_character_count() * visible_ratio; } dirty = true; @@ -348,7 +348,7 @@ void Label::_notification(int p_what) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; total_glyphs += TS->shaped_text_get_glyph_count(lines_rid[i]) + TS->shaped_text_get_ellipsis_glyph_count(lines_rid[i]); } - int visible_glyphs = total_glyphs * percent_visible; + int visible_glyphs = total_glyphs * visible_ratio; int processed_glyphs = 0; total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); @@ -652,8 +652,8 @@ void Label::set_text(const String &p_string) { text = p_string; xl_text = atr(p_string); dirty = true; - if (percent_visible < 1) { - visible_chars = get_total_character_count() * percent_visible; + if (visible_ratio < 1) { + visible_chars = get_total_character_count() * visible_ratio; } update(); update_minimum_size(); @@ -771,9 +771,9 @@ void Label::set_visible_characters(int p_amount) { if (visible_chars != p_amount) { visible_chars = p_amount; if (get_total_character_count() > 0) { - percent_visible = (float)p_amount / (float)get_total_character_count(); + visible_ratio = (float)p_amount / (float)get_total_character_count(); } else { - percent_visible = 1.0; + visible_ratio = 1.0; } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { dirty = true; @@ -786,17 +786,17 @@ int Label::get_visible_characters() const { return visible_chars; } -void Label::set_percent_visible(float p_percent) { - if (percent_visible != p_percent) { - if (percent_visible >= 1.0) { +void Label::set_visible_ratio(float p_ratio) { + if (visible_ratio != p_ratio) { + if (visible_ratio >= 1.0) { visible_chars = -1; - percent_visible = 1.0; - } else if (percent_visible < 0.0) { + visible_ratio = 1.0; + } else if (visible_ratio < 0.0) { visible_chars = 0; - percent_visible = 0.0; + visible_ratio = 0.0; } else { - visible_chars = get_total_character_count() * p_percent; - percent_visible = p_percent; + visible_chars = get_total_character_count() * p_ratio; + visible_ratio = p_ratio; } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { @@ -806,8 +806,8 @@ void Label::set_percent_visible(float p_percent) { } } -float Label::get_percent_visible() const { - return percent_visible; +float Label::get_visible_ratio() const { + return visible_ratio; } TextServer::VisibleCharactersBehavior Label::get_visible_characters_behavior() const { @@ -889,8 +889,8 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_visible_characters"), &Label::get_visible_characters); ClassDB::bind_method(D_METHOD("get_visible_characters_behavior"), &Label::get_visible_characters_behavior); ClassDB::bind_method(D_METHOD("set_visible_characters_behavior", "behavior"), &Label::set_visible_characters_behavior); - ClassDB::bind_method(D_METHOD("set_percent_visible", "percent_visible"), &Label::set_percent_visible); - ClassDB::bind_method(D_METHOD("get_percent_visible"), &Label::get_percent_visible); + ClassDB::bind_method(D_METHOD("set_visible_ratio", "ratio"), &Label::set_visible_ratio); + ClassDB::bind_method(D_METHOD("get_visible_ratio"), &Label::get_visible_ratio); ClassDB::bind_method(D_METHOD("set_lines_skipped", "lines_skipped"), &Label::set_lines_skipped); ClassDB::bind_method(D_METHOD("get_lines_skipped"), &Label::get_lines_skipped); ClassDB::bind_method(D_METHOD("set_max_lines_visible", "lines_visible"), &Label::set_max_lines_visible); @@ -908,13 +908,14 @@ void Label::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_text"), "set_clip_text", "is_clipping_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); + + ADD_GROUP("Displayed Text", ""); 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"); - - // Note: "visible_characters" and "percent_visible" should be set after "text" to be correctly applied. + // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visible_ratio", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_visible_ratio", "get_visible_ratio"); ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); diff --git a/scene/gui/label.h b/scene/gui/label.h index cab5b36d68..65831cab6e 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -59,10 +59,9 @@ private: TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT; Array st_args; - float percent_visible = 1.0; - TextServer::VisibleCharactersBehavior visible_chars_behavior = TextServer::VC_CHARS_BEFORE_SHAPING; int visible_chars = -1; + float visible_ratio = 1.0; int lines_skipped = 0; int max_lines_visible = -1; @@ -110,22 +109,22 @@ public: void set_uppercase(bool p_uppercase); bool is_uppercase() const; - TextServer::VisibleCharactersBehavior get_visible_characters_behavior() const; void set_visible_characters_behavior(TextServer::VisibleCharactersBehavior p_behavior); + TextServer::VisibleCharactersBehavior get_visible_characters_behavior() const; void set_visible_characters(int p_amount); int get_visible_characters() const; int get_total_character_count() const; + void set_visible_ratio(float p_ratio); + float get_visible_ratio() const; + void set_clip_text(bool p_clip); bool is_clipping_text() const; void set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior); TextServer::OverrunBehavior get_text_overrun_behavior() const; - void set_percent_visible(float p_percent); - float get_percent_visible() const; - void set_lines_skipped(int p_lines); int get_lines_skipped() const; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index cc39b0e57a..34a60b907c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -718,7 +718,7 @@ void LineEdit::_notification(int p_what) { case NOTIFICATION_RESIZED: { _fit_to_width(); - scroll_offset = 0; + scroll_offset = 0.0; set_caret_column(get_caret_column()); } break; @@ -801,7 +801,7 @@ void LineEdit::_notification(int p_what) { } } break; case HORIZONTAL_ALIGNMENT_CENTER: { - if (scroll_offset != 0) { + if (!Math::is_zero_approx(scroll_offset)) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - (text_width)) / 2); @@ -846,7 +846,7 @@ void LineEdit::_notification(int p_what) { r_icon->draw(ci, Point2(width - r_icon->get_width() - style->get_margin(SIDE_RIGHT), height / 2 - r_icon->get_height() / 2), color_icon); if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { - if (scroll_offset == 0) { + if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(size.width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); } } else { @@ -1208,7 +1208,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { } } break; case HORIZONTAL_ALIGNMENT_CENTER: { - if (scroll_offset != 0) { + if (!Math::is_zero_approx(scroll_offset)) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); @@ -1228,7 +1228,7 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { if (right_icon.is_valid() || display_clear_icon) { Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { - if (scroll_offset == 0) { + if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); } } else { @@ -1236,11 +1236,11 @@ void LineEdit::set_caret_at_pixel_pos(int p_x) { } } - int ofs = TS->shaped_text_hit_test_position(text_rid, p_x - x_ofs - scroll_offset); + int ofs = ceil(TS->shaped_text_hit_test_position(text_rid, p_x - x_ofs - scroll_offset)); set_caret_column(ofs); } -Vector2i LineEdit::get_caret_pixel_pos() { +Vector2 LineEdit::get_caret_pixel_pos() { Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); bool rtl = is_layout_rtl(); @@ -1256,7 +1256,7 @@ Vector2i LineEdit::get_caret_pixel_pos() { } } break; case HORIZONTAL_ALIGNMENT_CENTER: { - if (scroll_offset != 0) { + if (!Math::is_zero_approx(scroll_offset)) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); @@ -1276,7 +1276,7 @@ Vector2i LineEdit::get_caret_pixel_pos() { if (right_icon.is_valid() || display_clear_icon) { Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { - if (scroll_offset == 0) { + if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); } } else { @@ -1284,7 +1284,7 @@ Vector2i LineEdit::get_caret_pixel_pos() { } } - Vector2i ret; + Vector2 ret; CaretInfo caret; // Get position of the start of caret. if (ime_text.length() != 0 && ime_selection.x != 0) { @@ -1427,7 +1427,7 @@ void LineEdit::set_text(String p_text) { update(); caret_column = 0; - scroll_offset = 0; + scroll_offset = 0.0; } void LineEdit::set_text_direction(Control::TextDirection p_text_direction) { @@ -1555,7 +1555,7 @@ void LineEdit::set_caret_column(int p_column) { // Fit to window. if (!is_inside_tree()) { - scroll_offset = 0; + scroll_offset = 0.0; return; } @@ -1574,7 +1574,7 @@ void LineEdit::set_caret_column(int p_column) { } } break; case HORIZONTAL_ALIGNMENT_CENTER: { - if (scroll_offset != 0) { + if (!Math::is_zero_approx(scroll_offset)) { x_ofs = style->get_offset().x; } else { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - (text_width)) / 2); @@ -1595,7 +1595,7 @@ void LineEdit::set_caret_column(int p_column) { if (right_icon.is_valid() || display_clear_icon) { Ref<Texture2D> r_icon = display_clear_icon ? Control::get_theme_icon(SNAME("clear")) : right_icon; if (alignment == HORIZONTAL_ALIGNMENT_CENTER) { - if (scroll_offset == 0) { + if (Math::is_zero_approx(scroll_offset)) { x_ofs = MAX(style->get_margin(SIDE_LEFT), int(get_size().width - text_width - r_icon->get_width() - style->get_margin(SIDE_RIGHT) * 2) / 2); } } else { @@ -1605,12 +1605,12 @@ void LineEdit::set_caret_column(int p_column) { } // Note: Use two coordinates to fit IME input range. - Vector2i primary_catret_offset = get_caret_pixel_pos(); + Vector2 primary_caret_offset = get_caret_pixel_pos(); - if (MIN(primary_catret_offset.x, primary_catret_offset.y) <= x_ofs) { - scroll_offset += (x_ofs - MIN(primary_catret_offset.x, primary_catret_offset.y)); - } else if (MAX(primary_catret_offset.x, primary_catret_offset.y) >= ofs_max) { - scroll_offset += (ofs_max - MAX(primary_catret_offset.x, primary_catret_offset.y)); + if (MIN(primary_caret_offset.x, primary_caret_offset.y) <= x_ofs) { + scroll_offset += x_ofs - MIN(primary_caret_offset.x, primary_caret_offset.y); + } else if (MAX(primary_caret_offset.x, primary_caret_offset.y) >= ofs_max) { + scroll_offset += ofs_max - MAX(primary_caret_offset.x, primary_caret_offset.y); } scroll_offset = MIN(0, scroll_offset); @@ -1621,14 +1621,14 @@ int LineEdit::get_caret_column() const { return caret_column; } -void LineEdit::set_scroll_offset(int p_pos) { +void LineEdit::set_scroll_offset(float p_pos) { scroll_offset = p_pos; - if (scroll_offset < 0) { - scroll_offset = 0; + if (scroll_offset < 0.0) { + scroll_offset = 0.0; } } -int LineEdit::get_scroll_offset() const { +float LineEdit::get_scroll_offset() const { return scroll_offset; } @@ -1656,7 +1656,7 @@ void LineEdit::clear_internal() { deselect(); _clear_undo_stack(); caret_column = 0; - scroll_offset = 0; + scroll_offset = 0.0; undo_text = ""; text = ""; _shape(); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 254f842b66..dabdaa3395 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -113,7 +113,7 @@ private: bool caret_mid_grapheme_enabled = true; int caret_column = 0; - int scroll_offset = 0; + float scroll_offset = 0.0; int max_length = 0; // 0 for no maximum. String language; @@ -153,8 +153,7 @@ private: struct TextOperation { int caret_column = 0; - int scroll_offset = 0; - int cached_width = 0; + float scroll_offset = 0.0; String text; }; List<TextOperation> undo_stack; @@ -192,11 +191,11 @@ private: void shift_selection_check_post(bool); void selection_fill_at_caret(); - void set_scroll_offset(int p_pos); - int get_scroll_offset() const; + void set_scroll_offset(float p_pos); + float get_scroll_offset() const; void set_caret_at_pixel_pos(int p_x); - Vector2i get_caret_pixel_pos(); + Vector2 get_caret_pixel_pos(); void _reset_caret_blink_timer(); void _toggle_draw_caret(); diff --git a/scene/gui/menu_bar.cpp b/scene/gui/menu_bar.cpp index f450222130..9b7b67d83e 100644 --- a/scene/gui/menu_bar.cpp +++ b/scene/gui/menu_bar.cpp @@ -60,7 +60,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { if (active_menu >= 0) { get_menu_popup(active_menu)->hide(); } - _open_popup(selected_menu); + _open_popup(selected_menu, true); } return; } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { @@ -82,7 +82,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { if (active_menu >= 0) { get_menu_popup(active_menu)->hide(); } - _open_popup(selected_menu); + _open_popup(selected_menu, true); } return; } @@ -110,7 +110,7 @@ void MenuBar::gui_input(const Ref<InputEvent> &p_event) { } } -void MenuBar::_open_popup(int p_index) { +void MenuBar::_open_popup(int p_index, bool p_focus_item) { ERR_FAIL_INDEX(p_index, menu_cache.size()); PopupMenu *pm = get_menu_popup(p_index); @@ -134,6 +134,15 @@ void MenuBar::_open_popup(int p_index) { pm->set_parent_rect(Rect2(Point2(screen_pos - pm->get_position()), Size2(screen_size.x, screen_pos.y))); pm->popup(); + if (p_focus_item) { + for (int i = 0; i < pm->get_item_count(); i++) { + if (!pm->is_item_disabled(i)) { + pm->set_current_index(i); + break; + } + } + } + update(); } @@ -276,10 +285,7 @@ void MenuBar::_update_submenu(const String &p_menu_name, PopupMenu *p_child) { } bool MenuBar::is_native_menu() const { - if (!is_visible_in_tree()) { - return false; - } - if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root()->is_ancestor_of(this) || get_tree()->get_edited_scene_root() == this)) { + if (Engine::get_singleton()->is_editor_hint() && is_inside_tree() && get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root()->is_ancestor_of(this) || get_tree()->get_edited_scene_root() == this)) { return false; } @@ -308,7 +314,7 @@ void MenuBar::_clear_menu() { void MenuBar::_update_menu() { _clear_menu(); - if (!is_inside_tree()) { + if (!is_visible_in_tree()) { return; } diff --git a/scene/gui/menu_bar.h b/scene/gui/menu_bar.h index 3c4a25fd06..b7d9933ab2 100644 --- a/scene/gui/menu_bar.h +++ b/scene/gui/menu_bar.h @@ -84,7 +84,7 @@ class MenuBar : public Control { Vector<PopupMenu *> _get_popups() const; int get_menu_idx_from_control(PopupMenu *p_child) const; - void _open_popup(int p_index); + void _open_popup(int p_index, bool p_focus_item = false); void _popup_visibility_changed(bool p_visible); void _update_submenu(const String &p_menu_name, PopupMenu *p_child); void _clear_menu(); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index a03db82332..f779f87ae7 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -86,6 +86,11 @@ void MenuButton::_popup_visibility_changed(bool p_visible) { } void MenuButton::pressed() { + if (popup->is_visible()) { + popup->hide(); + return; + } + emit_signal(SNAME("about_to_popup")); Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); @@ -98,16 +103,17 @@ void MenuButton::pressed() { popup->set_position(gp); popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), size)); - // If not triggered by the mouse, start the popup with its first item selected. - if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) { - popup->set_current_index(0); + // If not triggered by the mouse, start the popup with its first enabled item focused. + if (!_was_pressed_by_mouse()) { + for (int i = 0; i < popup->get_item_count(); i++) { + if (!popup->is_item_disabled(i)) { + popup->set_current_index(i); + break; + } + } } - if (popup->is_visible()) { - popup->hide(); - } else { - popup->popup(); - } + popup->popup(); } void MenuButton::gui_input(const Ref<InputEvent> &p_event) { @@ -160,7 +166,10 @@ void MenuButton::_notification(int p_what) { if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { popup->hide(); + menu_btn_other->pressed(); + // As the popup wasn't triggered by a mouse click, the item focus needs to be removed manually. + menu_btn_other->get_popup()->set_current_index(-1); } } break; } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 931dffe3bb..a87c46e8ac 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -198,16 +198,33 @@ void OptionButton::_selected(int p_which) { } void OptionButton::pressed() { + if (popup->is_visible()) { + popup->hide(); + return; + } + Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); popup->set_size(Size2(size.width, 0)); - // If not triggered by the mouse, start the popup with the checked item selected. - if (popup->get_item_count() > 0) { + // If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused. + if (current != NONE_SELECTED && !popup->is_item_disabled(current)) { if (!_was_pressed_by_mouse()) { - popup->set_current_index(current > -1 ? current : 0); + popup->set_current_index(current); } else { - popup->scroll_to_item(current > -1 ? current : 0); + popup->scroll_to_item(current); + } + } else { + for (int i = 0; i < popup->get_item_count(); i++) { + if (!popup->is_item_disabled(i)) { + if (!_was_pressed_by_mouse()) { + popup->set_current_index(i); + } else { + popup->scroll_to_item(i); + } + + break; + } } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 4e2aec0278..c8bb9fd530 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -216,9 +216,14 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) { submenu_pum->activated_by_keyboard = p_by_keyboard; - // If not triggered by the mouse, start the popup with its first item selected. - if (submenu_pum->get_item_count() > 0 && p_by_keyboard) { - submenu_pum->set_current_index(0); + // If not triggered by the mouse, start the popup with its first enabled item focused. + if (p_by_keyboard) { + for (int i = 0; i < submenu_pum->get_item_count(); i++) { + if (!submenu_pum->is_item_disabled(i)) { + submenu_pum->set_current_index(i); + break; + } + } } submenu_pum->popup(); @@ -278,102 +283,104 @@ void PopupMenu::_submenu_timeout() { void PopupMenu::gui_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (p_event->is_action("ui_down") && p_event->is_pressed()) { - int search_from = mouse_over + 1; - if (search_from >= items.size()) { - search_from = 0; - } - - bool match_found = false; - for (int i = search_from; i < items.size(); i++) { - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal(SNAME("id_focused"), i); - scroll_to_item(i); - control->update(); - set_input_as_handled(); - match_found = true; - break; + if (!items.is_empty()) { + if (p_event->is_action("ui_down") && p_event->is_pressed()) { + int search_from = mouse_over + 1; + if (search_from >= items.size()) { + search_from = 0; } - } - if (!match_found) { - // If the last item is not selectable, try re-searching from the start. - for (int i = 0; i < search_from; i++) { + bool match_found = false; + for (int i = search_from; i < items.size(); i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; emit_signal(SNAME("id_focused"), i); scroll_to_item(i); control->update(); set_input_as_handled(); + match_found = true; break; } } - } - } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { - int search_from = mouse_over - 1; - if (search_from < 0) { - search_from = items.size() - 1; - } - bool match_found = false; - for (int i = search_from; i >= 0; i--) { - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal(SNAME("id_focused"), i); - scroll_to_item(i); - control->update(); - set_input_as_handled(); - match_found = true; - break; + if (!match_found) { + // If the last item is not selectable, try re-searching from the start. + for (int i = 0; i < search_from; i++) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal(SNAME("id_focused"), i); + scroll_to_item(i); + control->update(); + set_input_as_handled(); + break; + } + } + } + } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { + int search_from = mouse_over - 1; + if (search_from < 0) { + search_from = items.size() - 1; } - } - if (!match_found) { - // If the first item is not selectable, try re-searching from the end. - for (int i = items.size() - 1; i >= search_from; i--) { + bool match_found = false; + for (int i = search_from; i >= 0; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; emit_signal(SNAME("id_focused"), i); scroll_to_item(i); control->update(); set_input_as_handled(); + match_found = true; break; } } - } - } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { - Node *n = get_parent(); - if (n) { - if (Object::cast_to<PopupMenu>(n)) { - hide(); - set_input_as_handled(); - } else if (Object::cast_to<MenuBar>(n)) { - Object::cast_to<MenuBar>(n)->gui_input(p_event); - set_input_as_handled(); - return; + + if (!match_found) { + // If the first item is not selectable, try re-searching from the end. + for (int i = items.size() - 1; i >= search_from; i--) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal(SNAME("id_focused"), i); + scroll_to_item(i); + control->update(); + set_input_as_handled(); + break; + } + } } - } - } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { - _activate_submenu(mouse_over, true); - set_input_as_handled(); - } else { + } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { Node *n = get_parent(); - if (n && Object::cast_to<MenuBar>(n)) { - Object::cast_to<MenuBar>(n)->gui_input(p_event); - set_input_as_handled(); - return; + if (n) { + if (Object::cast_to<PopupMenu>(n)) { + hide(); + set_input_as_handled(); + } else if (Object::cast_to<MenuBar>(n)) { + Object::cast_to<MenuBar>(n)->gui_input(p_event); + set_input_as_handled(); + return; + } } - } - } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { - if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { + } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && !items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { _activate_submenu(mouse_over, true); + set_input_as_handled(); } else { - activate_item(mouse_over); + Node *n = get_parent(); + if (n && Object::cast_to<MenuBar>(n)) { + Object::cast_to<MenuBar>(n)->gui_input(p_event); + set_input_as_handled(); + return; + } + } + } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { + if (!items[mouse_over].submenu.is_empty() && submenu_over != mouse_over) { + _activate_submenu(mouse_over, true); + } else { + activate_item(mouse_over); + } + set_input_as_handled(); } - set_input_as_handled(); } } @@ -1532,14 +1539,19 @@ bool PopupMenu::is_item_shortcut_disabled(int p_idx) const { } void PopupMenu::set_current_index(int p_idx) { - ERR_FAIL_INDEX(p_idx, items.size()); + if (p_idx != -1) { + ERR_FAIL_INDEX(p_idx, items.size()); + } if (mouse_over == p_idx) { return; } mouse_over = p_idx; - scroll_to_item(mouse_over); + if (mouse_over != -1) { + scroll_to_item(mouse_over); + } + control->update(); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 6ab3cdcb69..8ce8663091 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -742,7 +742,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o bool trim_glyphs_ltr = (visible_characters >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_LTR) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && !lrtl)); bool trim_glyphs_rtl = (visible_characters >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_RTL) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && lrtl)); int total_glyphs = (trim_glyphs_ltr || trim_glyphs_rtl) ? get_total_glyph_count() : 0; - int visible_glyphs = total_glyphs * percent_visible; + int visible_glyphs = total_glyphs * visible_ratio; Vector<int> list_index; Vector<ItemList *> list_items; @@ -4940,19 +4940,19 @@ TextServer::AutowrapMode RichTextLabel::get_autowrap_mode() const { return autowrap_mode; } -void RichTextLabel::set_percent_visible(float p_percent) { - if (percent_visible != p_percent) { +void RichTextLabel::set_visible_ratio(float p_ratio) { + if (visible_ratio != p_ratio) { _stop_thread(); - if (percent_visible >= 1.0) { + if (visible_ratio >= 1.0) { visible_characters = -1; - percent_visible = 1.0; - } else if (percent_visible < 0.0) { + visible_ratio = 1.0; + } else if (visible_ratio < 0.0) { visible_characters = 0; - percent_visible = 0.0; + visible_ratio = 0.0; } else { - visible_characters = get_total_character_count() * p_percent; - percent_visible = p_percent; + visible_characters = get_total_character_count() * p_ratio; + visible_ratio = p_ratio; } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { @@ -4963,8 +4963,8 @@ void RichTextLabel::set_percent_visible(float p_percent) { } } -float RichTextLabel::get_percent_visible() const { - return percent_visible; +float RichTextLabel::get_visible_ratio() const { + return visible_ratio; } void RichTextLabel::set_effects(Array p_effects) { @@ -5139,8 +5139,8 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_visible_characters_behavior"), &RichTextLabel::get_visible_characters_behavior); ClassDB::bind_method(D_METHOD("set_visible_characters_behavior", "behavior"), &RichTextLabel::set_visible_characters_behavior); - ClassDB::bind_method(D_METHOD("set_percent_visible", "percent_visible"), &RichTextLabel::set_percent_visible); - ClassDB::bind_method(D_METHOD("get_percent_visible"), &RichTextLabel::get_percent_visible); + ClassDB::bind_method(D_METHOD("set_visible_ratio", "ratio"), &RichTextLabel::set_visible_ratio); + ClassDB::bind_method(D_METHOD("get_visible_ratio"), &RichTextLabel::get_visible_ratio); ClassDB::bind_method(D_METHOD("get_character_line", "character"), &RichTextLabel::get_character_line); ClassDB::bind_method(D_METHOD("get_character_paragraph", "character"), &RichTextLabel::get_character_paragraph); @@ -5172,30 +5172,35 @@ void RichTextLabel::_bind_methods() { // Note: set "bbcode_enabled" first, to avoid unnecessary "text" resets. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bbcode_enabled"), "set_use_bbcode", "is_using_bbcode"); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "threaded"), "set_threaded", "is_threaded"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "progress_bar_delay", PROPERTY_HINT_NONE, "suffix:ms"), "set_progress_bar_delay", "get_progress_bar_delay"); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fit_content_height"), "set_fit_content_height", "is_fit_content_height_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_active"), "set_scroll_active", "is_scroll_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_following"), "set_scroll_follow", "is_scroll_following"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_size", PROPERTY_HINT_RANGE, "0,24,1"), "set_tab_size", "get_tab_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); + + ADD_GROUP("Markup", ""); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "RichTextEffect"), (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hint_underlined"), "set_hint_underline", "is_hint_underlined"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); - // Note: "visible_characters" and "percent_visible" should be set after "text" to be correctly applied. + ADD_GROUP("Threading", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "threaded"), "set_threaded", "is_threaded"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "progress_bar_delay", PROPERTY_HINT_NONE, "suffix:ms"), "set_progress_bar_delay", "get_progress_bar_delay"); + + ADD_GROUP("Text Selection", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); + + ADD_GROUP("Displayed Text", ""); + // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters_behavior", PROPERTY_HINT_ENUM, "Characters Before Shaping,Characters After Shaping,Glyphs (Layout Direction),Glyphs (Left-to-Right),Glyphs (Right-to-Left)"), "set_visible_characters_behavior", "get_visible_characters_behavior"); - 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, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visible_ratio", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_visible_ratio", "get_visible_ratio"); ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); @@ -5264,11 +5269,11 @@ void RichTextLabel::set_visible_characters(int p_visible) { visible_characters = p_visible; if (p_visible == -1) { - percent_visible = 1; + visible_ratio = 1; } else { int total_char_count = get_total_character_count(); if (total_char_count > 0) { - percent_visible = (float)p_visible / (float)total_char_count; + visible_ratio = (float)p_visible / (float)total_char_count; } } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 95e55bf1a1..79f9c62539 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -440,7 +440,7 @@ private: void _menu_option(int p_option); int visible_characters = -1; - float percent_visible = 1.0; + float visible_ratio = 1.0; TextServer::VisibleCharactersBehavior visible_chars_behavior = TextServer::VC_CHARS_BEFORE_SHAPING; bool _is_click_inside_selection() const; @@ -660,8 +660,8 @@ public: int get_total_character_count() const; int get_total_glyph_count() const; - void set_percent_visible(float p_percent); - float get_percent_visible() const; + void set_visible_ratio(float p_ratio); + float get_visible_ratio() const; TextServer::VisibleCharactersBehavior get_visible_characters_behavior() const; void set_visible_characters_behavior(TextServer::VisibleCharactersBehavior p_behavior); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 517c83545c..65c4a09c84 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -41,12 +41,16 @@ Size2 SpinBox::get_minimum_size() const { void SpinBox::_value_changed(double p_value) { String value = TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step()))); - if (!prefix.is_empty()) { - value = prefix + " " + value; - } - if (!suffix.is_empty()) { - value += " " + suffix; + + if (!line_edit->has_focus()) { + if (!prefix.is_empty()) { + value = prefix + " " + value; + } + if (!suffix.is_empty()) { + value += " " + suffix; + } } + line_edit->set_text(value); Range::_value_changed(p_value); } @@ -105,8 +109,9 @@ void SpinBox::_range_click_timeout() { void SpinBox::_release_mouse() { if (drag.enabled) { drag.enabled = false; - Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_HIDDEN); warp_mouse(drag.capture_pos); + Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); } } @@ -181,8 +186,14 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { } } +void SpinBox::_line_edit_focus_enter() { + int col = line_edit->get_caret_column(); + _value_changed(0); // Update the LineEdit's text. + line_edit->set_caret_column(col); +} + void SpinBox::_line_edit_focus_exit() { - // discontinue because the focus_exit was caused by right-click context menu + // Discontinue because the focus_exit was caused by right-click context menu. if (line_edit->is_menu_visible()) { return; } @@ -346,6 +357,7 @@ SpinBox::SpinBox() { line_edit->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT); line_edit->connect("text_submitted", callable_mp(this, &SpinBox::_text_submitted), CONNECT_DEFERRED); + line_edit->connect("focus_entered", callable_mp(this, &SpinBox::_line_edit_focus_enter), CONNECT_DEFERRED); line_edit->connect("focus_exited", callable_mp(this, &SpinBox::_line_edit_focus_exit), CONNECT_DEFERRED); line_edit->connect("gui_input", callable_mp(this, &SpinBox::_line_edit_input)); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 0aae9efe78..3fcb85ac99 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -64,6 +64,7 @@ class SpinBox : public Range { double diff_y = 0.0; } drag; + void _line_edit_focus_enter(); void _line_edit_focus_exit(); inline void _adjust_width_for_icon(const Ref<Texture2D> &icon); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index b6073ce265..3e60db0846 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -97,16 +97,12 @@ void SplitContainer::_resort() { // Compute the final middle separation. middle_sep = no_offset_middle_sep; - if (prev_no_offset_middle_sep != INT_MAX) { - split_offset -= middle_sep - prev_no_offset_middle_sep; - } - prev_no_offset_middle_sep = middle_sep; - if (!collapsed) { int clamped_split_offset = CLAMP(split_offset, ms_first[axis] - no_offset_middle_sep, (get_size()[axis] - ms_second[axis] - sep) - no_offset_middle_sep); middle_sep += clamped_split_offset; if (should_clamp_split_offset) { split_offset = clamped_split_offset; + should_clamp_split_offset = false; } } diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index dd15362199..a69ffe4de9 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -47,7 +47,6 @@ private: bool should_clamp_split_offset = false; int split_offset = 0; int middle_sep = 0; - int prev_no_offset_middle_sep = INT_MAX; bool vertical = false; bool dragging = false; int drag_from = 0; diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp index 7baa4d44aa..4024d4c80e 100644 --- a/scene/gui/video_stream_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -362,7 +362,7 @@ void VideoStreamPlayer::set_volume_db(float p_db) { if (p_db < -79) { set_volume(0); } else { - set_volume(Math::db2linear(p_db)); + set_volume(Math::db_to_linear(p_db)); } } @@ -370,7 +370,7 @@ float VideoStreamPlayer::get_volume_db() const { if (volume == 0) { return -80; } else { - return Math::linear2db(volume); + return Math::linear_to_db(volume); } } diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index dcf506aafa..515f4d88a6 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -587,6 +587,12 @@ void CanvasItem::draw_msdf_texture_rect_region(const Ref<Texture2D> &p_texture, RenderingServer::get_singleton()->canvas_item_add_msdf_texture_rect_region(canvas_item, p_rect, p_texture->get_rid(), p_src_rect, p_modulate, p_outline, p_pixel_range); } +void CanvasItem::draw_lcd_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate) { + ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL_COND(p_texture.is_null()); + RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(canvas_item, p_rect, p_texture->get_rid(), p_src_rect, p_modulate); +} + void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -919,6 +925,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false), DEFVAL(true)); ClassDB::bind_method(D_METHOD("draw_msdf_texture_rect_region", "texture", "rect", "src_rect", "modulate", "outline", "pixel_range"), &CanvasItem::draw_msdf_texture_rect_region, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0.0), DEFVAL(4.0)); + ClassDB::bind_method(D_METHOD("draw_lcd_texture_rect_region", "texture", "rect", "src_rect", "modulate"), &CanvasItem::draw_lcd_texture_rect_region, DEFVAL(Color(1, 1, 1, 1))); 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"), &CanvasItem::draw_primitive, DEFVAL(Ref<Texture2D>()), DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture"), &CanvasItem::draw_polygon, DEFVAL(PackedVector2Array()), DEFVAL(Ref<Texture2D>())); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 38e0be1683..1e0d4552ce 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -226,6 +226,7 @@ public: 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); 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, bool p_clip_uv = false); void draw_msdf_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), double p_outline = 0.0, double p_pixel_range = 4.0); + void draw_lcd_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)); 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<Texture2D> p_texture = Ref<Texture2D>(), real_t p_width = 1); 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>()); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 9773218574..cc3d14e5be 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -948,6 +948,21 @@ String Node::validate_child_name(Node *p_child) { } #endif +String Node::adjust_name_casing(const String &p_name) { + switch (GLOBAL_GET("editor/node_naming/name_casing").operator int()) { + case NAME_CASING_PASCAL_CASE: + return p_name.capitalize().replace(" ", ""); + case NAME_CASING_CAMEL_CASE: { + String name = p_name.capitalize().replace(" ", ""); + name[0] = name.to_lower()[0]; + return name; + } + case NAME_CASING_SNAKE_CASE: + return p_name.capitalize().replace(" ", "_").to_lower(); + } + return p_name; +} + void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { /* Make sure the name is unique */ @@ -1021,19 +1036,8 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co //no name and a new name is needed, create one. name = p_child->get_class(); - // Adjust casing according to project setting. The current type name is expected to be in PascalCase. - switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) { - case NAME_CASING_PASCAL_CASE: - break; - case NAME_CASING_CAMEL_CASE: { - String n = name; - n[0] = n.to_lower()[0]; - name = n; - } break; - case NAME_CASING_SNAKE_CASE: - name = String(name).camelcase_to_underscore(true); - break; - } + // Adjust casing according to project setting. + name = adjust_name_casing(name); } //quickly test if proposed name exists diff --git a/scene/main/node.h b/scene/main/node.h index 52ccf3d825..703c580d3f 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -459,6 +459,7 @@ public: #ifdef TOOLS_ENABLED String validate_child_name(Node *p_child); #endif + static String adjust_name_casing(const String &p_name); void queue_delete(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 764fc60bc1..a5a4e29186 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -798,6 +798,7 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, RS::get_singleton()->viewport_set_size(viewport, 0, 0); } _update_global_transform(); + update_configuration_warnings(); update_canvas_items(); @@ -1103,7 +1104,7 @@ Vector2 Viewport::get_mouse_position() const { void Viewport::warp_mouse(const Vector2 &p_position) { Transform2D xform = get_screen_transform(); - Vector2 gpos = xform.xform(p_position).round(); + Vector2 gpos = xform.xform(p_position); Input::get_singleton()->warp_mouse(gpos); } @@ -1708,15 +1709,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { is_tooltip_shown = true; } } else { - Variant t = gui.tooltip_popup->call("get_tooltip_text"); - - if (t.get_type() == Variant::STRING) { - if (tooltip == String(t)) { - is_tooltip_shown = true; - } - } else { - is_tooltip_shown = true; // Nothing to compare against, likely using custom control, so if it changes there is nothing we can do. - } + is_tooltip_shown = true; // Nothing to compare against, likely using custom control, so if it changes there is nothing we can do. } } else { _gui_cancel_tooltip(); @@ -2853,8 +2846,8 @@ Variant Viewport::gui_get_drag_data() const { TypedArray<String> Viewport::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); - if (size.x == 0 || size.y == 0) { - warnings.push_back(RTR("Viewport size must be greater than 0 to render anything.")); + if (size.x <= 1 || size.y <= 1) { + warnings.push_back(RTR("The Viewport size must be greater than or equal to 2 pixels on both dimensions to render anything.")); } return warnings; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index a0ec2d54dd..83083cd65a 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -563,7 +563,7 @@ public: bool is_input_disabled() const; Vector2 get_mouse_position() const; - void warp_mouse(const Vector2 &p_position); + virtual void warp_mouse(const Vector2 &p_position); void set_physics_object_picking(bool p_enable); bool get_physics_object_picking(); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index bf50ca0956..5328ae7b8c 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -35,6 +35,7 @@ #include "core/string/translation.h" #include "scene/gui/control.h" #include "scene/scene_string_names.h" +#include "scene/theme/theme_db.h" void Window::set_title(const String &p_title) { title = p_title; @@ -848,21 +849,13 @@ void Window::_notification(int p_what) { RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); } - if (theme.is_null()) { - Control *parent_c = cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } else { - Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } - } - } + // Need to defer here, because theme owner information might be set in + // add_child_notify, which doesn't get called until right after this. + call_deferred(SNAME("notification"), NOTIFICATION_THEME_CHANGED); + } break; + + case NOTIFICATION_THEME_CHANGED: { + emit_signal(SceneStringNames::get_singleton()->theme_changed); } break; case NOTIFICATION_READY: { @@ -974,6 +967,18 @@ DisplayServer::WindowID Window::get_window_id() const { return window_id; } +void Window::warp_mouse(const Vector2 &p_position) { + Transform2D xform = get_screen_transform(); + Vector2 gpos = xform.xform(p_position); + + if (transient_parent && !transient_parent->is_embedding_subwindows()) { + Transform2D window_trans = Transform2D().translated(get_position() + (transient_parent->get_visible_rect().size - transient_parent->get_real_size())); + gpos = window_trans.xform(gpos); + } + + Input::get_singleton()->warp_mouse(gpos); +} + void Window::set_wrap_controls(bool p_enable) { wrap_controls = p_enable; if (wrap_controls) { @@ -1250,16 +1255,10 @@ Rect2i Window::get_usable_parent_rect() const { } void Window::add_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && child_c->data.theme.is_null() && (theme_owner || theme_owner_window)) { - Control::_propagate_theme_changed(child_c, theme_owner, theme_owner_window); //need to propagate here, since many controls may require setting up stuff - } - - Window *child_w = Object::cast_to<Window>(p_child); - - if (child_w && child_w->theme.is_null() && (theme_owner || theme_owner_window)) { - Control::_propagate_theme_changed(child_w, theme_owner, theme_owner_window); //need to propagate here, since many controls may require setting up stuff + // We propagate when this node uses a custom theme, so it can pass it on to its children. + if (theme_owner || theme_owner_window) { + // `p_notify` is false here as `NOTIFICATION_THEME_CHANGED` will be handled by `NOTIFICATION_ENTER_TREE`. + Control::_propagate_theme_changed(this, theme_owner, theme_owner_window, false, true); } if (is_inside_tree() && wrap_controls) { @@ -1268,16 +1267,9 @@ void Window::add_child_notify(Node *p_child) { } void Window::remove_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { - Control::_propagate_theme_changed(child_c, nullptr, nullptr); - } - - Window *child_w = Object::cast_to<Window>(p_child); - - if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { - Control::_propagate_theme_changed(child_w, nullptr, nullptr); + // If the removed child isn't inheriting any theme items through this node, then there's no need to propagate. + if (theme_owner || theme_owner_window) { + Control::_propagate_theme_changed(this, nullptr, nullptr, false, true); } if (is_inside_tree() && wrap_controls) { @@ -1290,34 +1282,47 @@ void Window::set_theme(const Ref<Theme> &p_theme) { return; } + if (theme.is_valid()) { + theme->disconnect("changed", callable_mp(this, &Window::_theme_changed)); + } + theme = p_theme; + if (theme.is_valid()) { + Control::_propagate_theme_changed(this, nullptr, this, is_inside_tree(), true); + theme->connect("changed", callable_mp(this, &Window::_theme_changed), CONNECT_DEFERRED); + return; + } - if (!p_theme.is_null()) { - theme_owner = nullptr; - theme_owner_window = this; - Control::_propagate_theme_changed(this, nullptr, this); - } else { - Control *parent_c = cast_to<Control>(get_parent()); - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); - } else { - Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); - } else { - Control::_propagate_theme_changed(this, nullptr, nullptr); - } - } + Control *parent_c = Object::cast_to<Control>(get_parent()); + if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window, is_inside_tree(), true); + return; } + + Window *parent_w = cast_to<Window>(get_parent()); + if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window, is_inside_tree(), true); + return; + } + + Control::_propagate_theme_changed(this, nullptr, nullptr, is_inside_tree(), true); } Ref<Theme> Window::get_theme() const { return theme; } +void Window::_theme_changed() { + if (is_inside_tree()) { + Control::_propagate_theme_changed(this, nullptr, this, true, false); + } +} + void Window::set_theme_type_variation(const StringName &p_theme_type) { theme_type_variation = p_theme_type; - Control::_propagate_theme_changed(this, theme_owner, theme_owner_window); + if (is_inside_tree()) { + notification(NOTIFICATION_THEME_CHANGED); + } } StringName Window::get_theme_type_variation() const { @@ -1326,13 +1331,13 @@ StringName Window::get_theme_type_variation() const { void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) { - if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(theme_type_variation) != StringName()) { - Theme::get_project_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); + if (ThemeDB::get_singleton()->get_project_theme().is_valid() && ThemeDB::get_singleton()->get_project_theme()->get_type_variation_base(theme_type_variation) != StringName()) { + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); } else { - Theme::get_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), theme_type_variation, p_list); } } else { - Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(p_theme_type, StringName(), p_list); } } @@ -1518,9 +1523,9 @@ void Window::_validate_property(PropertyInfo &p_property) const { // Only the default theme and the project theme are used for the list of options. // This is an imposed limitation to simplify the logic needed to leverage those options. - Theme::get_default()->get_type_variation_list(get_class_name(), &names); - if (Theme::get_project_default().is_valid()) { - Theme::get_project_default()->get_type_variation_list(get_class_name(), &names); + ThemeDB::get_singleton()->get_default_theme()->get_type_variation_list(get_class_name(), &names); + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { + ThemeDB::get_singleton()->get_project_theme()->get_type_variation_list(get_class_name(), &names); } names.sort_custom<StringName::AlphCompare>(); @@ -1681,6 +1686,7 @@ void Window::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transparent"), "set_flag", "get_flag", FLAG_TRANSPARENT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "unfocusable"), "set_flag", "get_flag", FLAG_NO_FOCUS); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "popup_window"), "set_flag", "get_flag", FLAG_POPUP); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "extend_to_title"), "set_flag", "get_flag", FLAG_EXTEND_TO_TITLE); ADD_GROUP("Limits", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "min_size", PROPERTY_HINT_NONE, "suffix:px"), "set_min_size", "get_min_size"); @@ -1712,6 +1718,7 @@ void Window::_bind_methods() { ADD_SIGNAL(MethodInfo("theme_changed")); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); + BIND_CONSTANT(NOTIFICATION_THEME_CHANGED); BIND_ENUM_CONSTANT(MODE_WINDOWED); BIND_ENUM_CONSTANT(MODE_MINIMIZED); @@ -1725,6 +1732,7 @@ void Window::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_TRANSPARENT); BIND_ENUM_CONSTANT(FLAG_NO_FOCUS); BIND_ENUM_CONSTANT(FLAG_POPUP); + BIND_ENUM_CONSTANT(FLAG_EXTEND_TO_TITLE); BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED); diff --git a/scene/main/window.h b/scene/main/window.h index aa32edbb04..a5b6b26104 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -56,6 +56,7 @@ public: FLAG_TRANSPARENT = DisplayServer::WINDOW_FLAG_TRANSPARENT, FLAG_NO_FOCUS = DisplayServer::WINDOW_FLAG_NO_FOCUS, FLAG_POPUP = DisplayServer::WINDOW_FLAG_POPUP, + FLAG_EXTEND_TO_TITLE = DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE, FLAG_MAX = DisplayServer::WINDOW_FLAG_MAX, }; @@ -239,6 +240,8 @@ public: void set_use_font_oversampling(bool p_oversampling); bool is_using_font_oversampling() const; + void warp_mouse(const Vector2 &p_position) override; + void set_wrap_controls(bool p_enable); bool is_wrapping_controls() const; void child_controls_changed(); @@ -253,6 +256,7 @@ public: void set_theme(const Ref<Theme> &p_theme); Ref<Theme> get_theme() const; + void _theme_changed(); void set_theme_type_variation(const StringName &p_theme_type); StringName get_theme_type_variation() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 62573ed3e8..6c7bc552bf 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -162,7 +162,7 @@ #include "scene/resources/multimesh.h" #include "scene/resources/navigation_mesh.h" #include "scene/resources/packed_scene.h" -#include "scene/resources/particles_material.h" +#include "scene/resources/particle_process_material.h" #include "scene/resources/physics_material.h" #include "scene/resources/polygon_path_finder.h" #include "scene/resources/primitive_meshes.h" @@ -193,12 +193,14 @@ #include "scene/resources/sky.h" #include "scene/resources/sky_material.h" #include "scene/resources/sphere_shape_3d.h" +#include "scene/resources/style_box.h" #include "scene/resources/surface_tool.h" #include "scene/resources/syntax_highlighter.h" #include "scene/resources/text_file.h" #include "scene/resources/text_line.h" #include "scene/resources/text_paragraph.h" #include "scene/resources/texture.h" +#include "scene/resources/theme.h" #include "scene/resources/tile_set.h" #include "scene/resources/video_stream.h" #include "scene/resources/visual_shader.h" @@ -210,6 +212,7 @@ #include "scene/resources/world_boundary_shape_2d.h" #include "scene/resources/world_boundary_shape_3d.h" #include "scene/scene_string_names.h" +#include "scene/theme/theme_db.h" #include "scene/main/shader_globals_override.h" @@ -248,7 +251,7 @@ #include "scene/3d/shape_cast_3d.h" #include "scene/3d/skeleton_3d.h" #include "scene/3d/skeleton_ik_3d.h" -#include "scene/3d/soft_dynamic_body_3d.h" +#include "scene/3d/soft_body_3d.h" #include "scene/3d/spring_arm_3d.h" #include "scene/3d/sprite_3d.h" #include "scene/3d/vehicle_body_3d.h" @@ -533,13 +536,13 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(PhysicsBody3D); GDREGISTER_CLASS(StaticBody3D); GDREGISTER_CLASS(AnimatableBody3D); - GDREGISTER_CLASS(RigidDynamicBody3D); + GDREGISTER_CLASS(RigidBody3D); GDREGISTER_CLASS(KinematicCollision3D); GDREGISTER_CLASS(CharacterBody3D); GDREGISTER_CLASS(SpringArm3D); GDREGISTER_CLASS(PhysicalBone3D); - GDREGISTER_CLASS(SoftDynamicBody3D); + GDREGISTER_CLASS(SoftBody3D); GDREGISTER_CLASS(SkeletonIK3D); GDREGISTER_CLASS(BoneAttachment3D); @@ -611,6 +614,7 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeColorFunc); GDREGISTER_CLASS(VisualShaderNodeTransformFunc); GDREGISTER_CLASS(VisualShaderNodeUVFunc); + GDREGISTER_CLASS(VisualShaderNodeUVPolarCoord); GDREGISTER_CLASS(VisualShaderNodeDotProduct); GDREGISTER_CLASS(VisualShaderNodeVectorLen); GDREGISTER_CLASS(VisualShaderNodeDeterminant); @@ -649,6 +653,7 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeTexture2DArrayUniform); GDREGISTER_CLASS(VisualShaderNodeTexture3DUniform); GDREGISTER_CLASS(VisualShaderNodeCubemapUniform); + GDREGISTER_CLASS(VisualShaderNodeLinearSceneDepth); GDREGISTER_CLASS(VisualShaderNodeIf); GDREGISTER_CLASS(VisualShaderNodeSwitch); GDREGISTER_CLASS(VisualShaderNodeFresnel); @@ -658,6 +663,10 @@ void register_scene_types() { GDREGISTER_CLASS(VisualShaderNodeCompare); GDREGISTER_CLASS(VisualShaderNodeMultiplyAdd); GDREGISTER_CLASS(VisualShaderNodeBillboard); + GDREGISTER_CLASS(VisualShaderNodeDistanceFade); + GDREGISTER_CLASS(VisualShaderNodeProximityFade); + GDREGISTER_CLASS(VisualShaderNodeRandomRange); + GDREGISTER_CLASS(VisualShaderNodeRemap); GDREGISTER_ABSTRACT_CLASS(VisualShaderNodeVarying); GDREGISTER_CLASS(VisualShaderNodeVaryingSetter); GDREGISTER_CLASS(VisualShaderNodeVaryingGetter); @@ -704,7 +713,7 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(PhysicsBody2D); GDREGISTER_CLASS(StaticBody2D); GDREGISTER_CLASS(AnimatableBody2D); - GDREGISTER_CLASS(RigidDynamicBody2D); + GDREGISTER_CLASS(RigidBody2D); GDREGISTER_CLASS(CharacterBody2D); GDREGISTER_CLASS(KinematicCollision2D); GDREGISTER_CLASS(Area2D); @@ -761,9 +770,9 @@ void register_scene_types() { /* REGISTER RESOURCES */ GDREGISTER_ABSTRACT_CLASS(Shader); - GDREGISTER_CLASS(ParticlesMaterial); - SceneTree::add_idle_callback(ParticlesMaterial::flush_changes); - ParticlesMaterial::init_shaders(); + GDREGISTER_CLASS(ParticleProcessMaterial); + SceneTree::add_idle_callback(ParticleProcessMaterial::flush_changes); + ParticleProcessMaterial::init_shaders(); GDREGISTER_VIRTUAL_CLASS(Mesh); GDREGISTER_CLASS(ArrayMesh); @@ -1019,6 +1028,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("PanoramaSky", "Sky"); ClassDB::add_compatibility_class("Particles", "GPUParticles3D"); ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D"); + ClassDB::add_compatibility_class("ParticlesMaterial", "ParticleProcessMaterial"); ClassDB::add_compatibility_class("Path", "Path3D"); ClassDB::add_compatibility_class("PathFollow", "PathFollow3D"); ClassDB::add_compatibility_class("PhysicalBone", "PhysicalBone3D"); @@ -1041,14 +1051,16 @@ void register_scene_types() { ClassDB::add_compatibility_class("RayShape", "SeparationRayShape3D"); ClassDB::add_compatibility_class("RayShape2D", "SeparationRayShape2D"); ClassDB::add_compatibility_class("RemoteTransform", "RemoteTransform3D"); - ClassDB::add_compatibility_class("RigidBody", "RigidDynamicBody3D"); - ClassDB::add_compatibility_class("RigidBody2D", "RigidDynamicBody2D"); + ClassDB::add_compatibility_class("RigidBody", "RigidBody3D"); + ClassDB::add_compatibility_class("RigidDynamicBody2D", "RigidBody2D"); + ClassDB::add_compatibility_class("RigidDynamicBody3D", "RigidBody3D"); ClassDB::add_compatibility_class("Shape", "Shape3D"); ClassDB::add_compatibility_class("ShortCut", "Shortcut"); ClassDB::add_compatibility_class("Skeleton", "Skeleton3D"); ClassDB::add_compatibility_class("SkeletonIK", "SkeletonIK3D"); ClassDB::add_compatibility_class("SliderJoint", "SliderJoint3D"); - ClassDB::add_compatibility_class("SoftBody", "SoftDynamicBody3D"); + ClassDB::add_compatibility_class("SoftBody", "SoftBody3D"); + ClassDB::add_compatibility_class("SoftDynamicBody3D", "SoftBody3D"); ClassDB::add_compatibility_class("Spatial", "Node3D"); ClassDB::add_compatibility_class("SpatialGizmo", "Node3DGizmo"); ClassDB::add_compatibility_class("SpatialMaterial", "StandardMaterial3D"); @@ -1121,58 +1133,8 @@ void register_scene_types() { SceneDebugger::initialize(); } -void initialize_theme() { - // Allow creating the default theme at a different scale to suit higher/lower base resolutions. - float default_theme_scale = GLOBAL_DEF("gui/theme/default_theme_scale", 1.0); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_theme_scale", PropertyInfo(Variant::FLOAT, "gui/theme/default_theme_scale", PROPERTY_HINT_RANGE, "0.5,8,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - String theme_path = GLOBAL_DEF_RST("gui/theme/custom", ""); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", ""); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - bool font_antialiased = (bool)GLOBAL_DEF_RST("gui/theme/default_font_antialiased", true); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiased", PropertyInfo(Variant::BOOL, "gui/theme/default_font_antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - TextServer::Hinting font_hinting = (TextServer::Hinting)(int)GLOBAL_DEF_RST("gui/theme/default_font_hinting", TextServer::HINTING_LIGHT); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_hinting", PropertyInfo(Variant::INT, "gui/theme/default_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST("gui/theme/default_font_subpixel_positioning", TextServer::SUBPIXEL_POSITIONING_AUTO); - ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_subpixel_positioning", PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); - - const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false); - const bool font_generate_mipmaps = GLOBAL_DEF_RST("gui/theme/default_font_generate_mipmaps", false); - - Ref<Font> font; - if (!font_path.is_empty()) { - font = ResourceLoader::load(font_path); - if (!font.is_valid()) { - ERR_PRINT("Error loading custom font '" + font_path + "'"); - } - } - - // Always make the default theme to avoid invalid default font/icon/style in the given theme. - if (RenderingServer::get_singleton()) { - make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiased, font_msdf, font_generate_mipmaps); - } - - if (!theme_path.is_empty()) { - Ref<Theme> theme = ResourceLoader::load(theme_path); - if (theme.is_valid()) { - Theme::set_project_default(theme); - if (font.is_valid()) { - Theme::set_fallback_font(font); - } - } else { - ERR_PRINT("Error loading custom theme '" + theme_path + "'"); - } - } -} - void unregister_scene_types() { SceneDebugger::deinitialize(); - clear_default_theme(); ResourceLoader::remove_resource_format_loader(resource_loader_texture_layered); resource_loader_texture_layered.unref(); @@ -1209,8 +1171,14 @@ void unregister_scene_types() { ProceduralSkyMaterial::cleanup_shader(); #endif // _3D_DISABLED - ParticlesMaterial::finish_shaders(); + ParticleProcessMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); ColorPicker::finish_shaders(); SceneStringNames::free(); } + +void register_scene_singletons() { + GDREGISTER_CLASS(ThemeDB); + + Engine::get_singleton()->add_singleton(Engine::Singleton("ThemeDB", ThemeDB::get_singleton())); +} diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h index dce8713976..cb3249c5d7 100644 --- a/scene/register_scene_types.h +++ b/scene/register_scene_types.h @@ -33,7 +33,6 @@ void register_scene_types(); void unregister_scene_types(); - -void initialize_theme(); +void register_scene_singletons(); #endif // REGISTER_SCENE_TYPES_H diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index da59c4dbd1..9d5bc18c96 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2323,100 +2323,23 @@ Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, real_t p } real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const { - return p_a * (1.0 - p_c) + p_b * p_c; + return Math::lerp(p_a, p_b, p_c); } -// Cubic interpolation for anytype. - -Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c) const { - return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); -} - -Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const { - return p_a.spherical_cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); -} - -Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const { +Variant Animation::_interpolate_angle(const Variant &p_a, const Variant &p_b, real_t p_c) const { Variant::Type type_a = p_a.get_type(); Variant::Type type_b = p_b.get_type(); - Variant::Type type_pa = p_pre_a.get_type(); - Variant::Type type_pb = p_post_b.get_type(); - - //make int and real play along - uint32_t vformat = 1 << type_a; vformat |= 1 << type_b; - vformat |= 1 << type_pa; - vformat |= 1 << type_pb; - if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) { - //mix of real and int real_t a = p_a; real_t b = p_b; - real_t pa = p_pre_a; - real_t pb = p_post_b; - - return Math::cubic_interpolate(a, b, pa, pb, p_c); - } else if ((vformat & (vformat - 1))) { - return p_a; //can't interpolate, mix of types - } - - switch (type_a) { - case Variant::VECTOR2: { - Vector2 a = p_a; - Vector2 b = p_b; - Vector2 pa = p_pre_a; - Vector2 pb = p_post_b; - - return a.cubic_interpolate(b, pa, pb, p_c); - } - case Variant::RECT2: { - Rect2 a = p_a; - Rect2 b = p_b; - Rect2 pa = p_pre_a; - Rect2 pb = p_post_b; - - return Rect2( - a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c), - a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c)); - } - case Variant::VECTOR3: { - Vector3 a = p_a; - Vector3 b = p_b; - Vector3 pa = p_pre_a; - Vector3 pb = p_post_b; - - return a.cubic_interpolate(b, pa, pb, p_c); - } - case Variant::QUATERNION: { - Quaternion a = p_a; - Quaternion b = p_b; - Quaternion pa = p_pre_a; - Quaternion pb = p_post_b; - - return a.spherical_cubic_interpolate(b, pa, pb, p_c); - } - case Variant::AABB: { - AABB a = p_a; - AABB b = p_b; - AABB pa = p_pre_a; - AABB pb = p_post_b; - - return AABB( - a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c), - a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c)); - } - default: { - return _interpolate(p_a, p_b, p_c); - } + return Math::fposmod((float)Math::lerp_angle(a, b, p_c), (float)Math_TAU); } -} - -real_t Animation::_cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const { return _interpolate(p_a, p_b, p_c); } -// Cubic interpolation in time for anytype. +// Cubic interpolation for anytype. Vector3 Animation::_cubic_interpolate_in_time(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { return p_a.cubic_interpolate_in_time(p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t); @@ -2503,6 +2426,25 @@ Variant Animation::_cubic_interpolate_in_time(const Variant &p_pre_a, const Vari } real_t Animation::_cubic_interpolate_in_time(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + return Math::cubic_interpolate_in_time(p_a, p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t); +} + +Variant Animation::_cubic_interpolate_angle_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const { + Variant::Type type_a = p_a.get_type(); + Variant::Type type_b = p_b.get_type(); + Variant::Type type_pa = p_pre_a.get_type(); + Variant::Type type_pb = p_post_b.get_type(); + uint32_t vformat = 1 << type_a; + vformat |= 1 << type_b; + vformat |= 1 << type_pa; + vformat |= 1 << type_pb; + if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) { + real_t a = p_a; + real_t b = p_b; + real_t pa = p_pre_a; + real_t pb = p_post_b; + return Math::fposmod((float)Math::cubic_interpolate_angle_in_time(a, b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t), (float)Math_TAU); + } return _interpolate(p_a, p_b, p_c); } @@ -2685,8 +2627,11 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol case INTERPOLATION_LINEAR: { return _interpolate(p_keys[idx].value, p_keys[next].value, c); } break; + case INTERPOLATION_LINEAR_ANGLE: { + return _interpolate_angle(p_keys[idx].value, p_keys[next].value, c); + } break; case INTERPOLATION_CUBIC: - case INTERPOLATION_CUBIC_IN_TIME: { + case INTERPOLATION_CUBIC_ANGLE: { int pre = 0; int post = 0; if (!p_backward) { @@ -2725,25 +2670,27 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol } } + real_t pre_t = 0.0; + real_t to_t = 0.0; + real_t post_t = 0.0; if (loop_mode == LOOP_LINEAR && p_loop_wrap) { - if (p_interp == INTERPOLATION_CUBIC) { - return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); - } - return _cubic_interpolate_in_time( - p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c, - pre > idx ? -length + p_keys[pre].time - p_keys[idx].time : p_keys[pre].time - p_keys[idx].time, - next < idx ? length + p_keys[next].time - p_keys[idx].time : p_keys[next].time - p_keys[idx].time, - next < idx || post <= idx ? length + p_keys[post].time - p_keys[idx].time : p_keys[post].time - p_keys[idx].time); + pre_t = pre > idx ? -length + p_keys[pre].time - p_keys[idx].time : p_keys[pre].time - p_keys[idx].time; + to_t = next < idx ? length + p_keys[next].time - p_keys[idx].time : p_keys[next].time - p_keys[idx].time; + post_t = next < idx || post <= idx ? length + p_keys[post].time - p_keys[idx].time : p_keys[post].time - p_keys[idx].time; + } else { + pre_t = p_keys[pre].time - p_keys[idx].time; + to_t = p_keys[next].time - p_keys[idx].time; + post_t = p_keys[post].time - p_keys[idx].time; } - if (p_interp == INTERPOLATION_CUBIC) { - return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c); + if (p_interp == INTERPOLATION_CUBIC_ANGLE) { + return _cubic_interpolate_angle_in_time( + p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c, + pre_t, to_t, post_t); } return _cubic_interpolate_in_time( p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c, - p_keys[pre].time - p_keys[idx].time, - p_keys[next].time - p_keys[idx].time, - p_keys[post].time - p_keys[idx].time); + pre_t, to_t, post_t); } break; default: return p_keys[idx].value; @@ -4073,7 +4020,8 @@ void Animation::_bind_methods() { BIND_ENUM_CONSTANT(INTERPOLATION_NEAREST); BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR); BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC); - BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC_IN_TIME); + BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR_ANGLE); + BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC_ANGLE); BIND_ENUM_CONSTANT(UPDATE_CONTINUOUS); BIND_ENUM_CONSTANT(UPDATE_DISCRETE); @@ -4100,28 +4048,27 @@ void Animation::clear() { emit_signal(SceneStringNames::get_singleton()->tracks_changed); } -bool Animation::_vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) { +bool Animation::_float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error) { // Remove overlapping keys. if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) { return true; } - if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) { + if (abs(t0.value - t1.value) < p_allowed_precision_error && abs(t1.value - t2.value) < p_allowed_precision_error) { return true; } // Calc velocities. - Vector3 vc0 = (t1.value - t0.value) / (t1.time - t0.time); - Vector3 vc1 = (t2.value - t1.value) / (t2.time - t1.time); - real_t v0 = vc0.length(); - real_t v1 = vc1.length(); + double v0 = (t1.value - t0.value) / (t1.time - t0.time); + double v1 = (t2.value - t1.value) / (t2.time - t1.time); // Avoid zero div but check equality. if (abs(v0 - v1) < p_allowed_precision_error) { return true; } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) { return false; } - // Check axis. - if (vc0.normalized().dot(vc1.normalized()) >= 1.0 - p_allowed_angular_error * 2.0) { - real_t ratio = v0 < v1 ? v0 / v1 : v1 / v0; + if (!signbit(v0 * v1)) { + v0 = abs(v0); + v1 = abs(v1); + double ratio = v0 < v1 ? v0 / v1 : v1 / v0; if (ratio >= 1.0 - p_allowed_velocity_err) { return true; } @@ -4129,7 +4076,7 @@ bool Animation::_vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<V return false; } -bool Animation::_quaternion_track_optimize_key(const TKey<Quaternion> t0, const TKey<Quaternion> t1, const TKey<Quaternion> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) { +bool Animation::_vector2_track_optimize_key(const TKey<Vector2> t0, const TKey<Vector2> t1, const TKey<Vector2> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) { // Remove overlapping keys. if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) { return true; @@ -4137,20 +4084,22 @@ bool Animation::_quaternion_track_optimize_key(const TKey<Quaternion> t0, const if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) { return true; } + // Calc velocities. + Vector2 vc0 = (t1.value - t0.value) / (t1.time - t0.time); + Vector2 vc1 = (t2.value - t1.value) / (t2.time - t1.time); + double v0 = vc0.length(); + double v1 = vc1.length(); + // Avoid zero div but check equality. + if (abs(v0 - v1) < p_allowed_precision_error) { + return true; + } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) { + return false; + } // Check axis. - Quaternion q0 = t0.value * t1.value * t0.value.inverse(); - Quaternion q1 = t1.value * t2.value * t1.value.inverse(); - if (q0.get_axis().dot(q1.get_axis()) >= 1.0 - p_allowed_angular_error * 2.0) { - // Calc velocities. - real_t v0 = Math::acos(t0.value.dot(t1.value)) / (t1.time - t0.time); - real_t v1 = Math::acos(t1.value.dot(t2.value)) / (t2.time - t1.time); - // Avoid zero div but check equality. - if (abs(v0 - v1) < p_allowed_precision_error) { - return true; - } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) { - return false; - } - real_t ratio = v0 < v1 ? v0 / v1 : v1 / v0; + if (vc0.normalized().dot(vc1.normalized()) >= 1.0 - p_allowed_angular_error * 2.0) { + v0 = abs(v0); + v1 = abs(v1); + double ratio = v0 < v1 ? v0 / v1 : v1 / v0; if (ratio >= 1.0 - p_allowed_velocity_err) { return true; } @@ -4158,25 +4107,64 @@ bool Animation::_quaternion_track_optimize_key(const TKey<Quaternion> t0, const return false; } -bool Animation::_float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error) { +bool Animation::_vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) { // Remove overlapping keys. if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) { return true; } - if (abs(t0.value - t1.value) < p_allowed_precision_error && abs(t1.value - t2.value) < p_allowed_precision_error) { + if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) { return true; } // Calc velocities. - real_t v0 = (t1.value - t0.value) / (t1.time - t0.time); - real_t v1 = (t2.value - t1.value) / (t2.time - t1.time); + Vector3 vc0 = (t1.value - t0.value) / (t1.time - t0.time); + Vector3 vc1 = (t2.value - t1.value) / (t2.time - t1.time); + double v0 = vc0.length(); + double v1 = vc1.length(); // Avoid zero div but check equality. if (abs(v0 - v1) < p_allowed_precision_error) { return true; } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) { return false; } - if (!signbit(v0 * v1)) { - real_t ratio = v0 < v1 ? v0 / v1 : v1 / v0; + // Check axis. + if (vc0.normalized().dot(vc1.normalized()) >= 1.0 - p_allowed_angular_error * 2.0) { + v0 = abs(v0); + v1 = abs(v1); + double ratio = v0 < v1 ? v0 / v1 : v1 / v0; + if (ratio >= 1.0 - p_allowed_velocity_err) { + return true; + } + } + return false; +} + +bool Animation::_quaternion_track_optimize_key(const TKey<Quaternion> t0, const TKey<Quaternion> t1, const TKey<Quaternion> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) { + // Remove overlapping keys. + if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) { + return true; + } + if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) { + return true; + } + // Check axis. + Quaternion q0 = t0.value * t1.value * t0.value.inverse(); + Quaternion q1 = t1.value * t2.value * t1.value.inverse(); + if (q0.get_axis().dot(q1.get_axis()) >= 1.0 - p_allowed_angular_error * 2.0) { + double a0 = Math::acos(t0.value.dot(t1.value)); + double a1 = Math::acos(t1.value.dot(t2.value)); + if (a0 + a1 >= Math_PI) { + return false; // Rotation is more than 180 deg, keep key. + } + // Calc velocities. + double v0 = a0 / (t1.time - t0.time); + double v1 = a1 / (t2.time - t1.time); + // Avoid zero div but check equality. + if (abs(v0 - v1) < p_allowed_precision_error) { + return true; + } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) { + return false; + } + double ratio = v0 < v1 ? v0 / v1 : v1 / v0; if (ratio >= 1.0 - p_allowed_velocity_err) { return true; } @@ -4213,25 +4201,25 @@ void Animation::_position_track_optimize(int p_idx, real_t p_allowed_velocity_er void Animation::_rotation_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) { ERR_FAIL_INDEX(p_idx, tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type != TYPE_ROTATION_3D); - RotationTrack *tt = static_cast<RotationTrack *>(tracks[p_idx]); + RotationTrack *rt = static_cast<RotationTrack *>(tracks[p_idx]); int i = 0; - while (i < tt->rotations.size() - 2) { - TKey<Quaternion> t0 = tt->rotations[i]; - TKey<Quaternion> t1 = tt->rotations[i + 1]; - TKey<Quaternion> t2 = tt->rotations[i + 2]; + while (i < rt->rotations.size() - 2) { + TKey<Quaternion> t0 = rt->rotations[i]; + TKey<Quaternion> t1 = rt->rotations[i + 1]; + TKey<Quaternion> t2 = rt->rotations[i + 2]; bool erase = _quaternion_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error); if (erase) { - tt->rotations.remove_at(i + 1); + rt->rotations.remove_at(i + 1); } else { i++; } } - if (tt->rotations.size() == 2) { - if ((tt->rotations[0].value - tt->rotations[1].value).length() < p_allowed_precision_error) { - tt->rotations.remove_at(1); + if (rt->rotations.size() == 2) { + if ((rt->rotations[0].value - rt->rotations[1].value).length() < p_allowed_precision_error) { + rt->rotations.remove_at(1); } } } @@ -4239,25 +4227,25 @@ void Animation::_rotation_track_optimize(int p_idx, real_t p_allowed_velocity_er void Animation::_scale_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) { ERR_FAIL_INDEX(p_idx, tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type != TYPE_SCALE_3D); - ScaleTrack *tt = static_cast<ScaleTrack *>(tracks[p_idx]); + ScaleTrack *st = static_cast<ScaleTrack *>(tracks[p_idx]); int i = 0; - while (i < tt->scales.size() - 2) { - TKey<Vector3> t0 = tt->scales[i]; - TKey<Vector3> t1 = tt->scales[i + 1]; - TKey<Vector3> t2 = tt->scales[i + 2]; + while (i < st->scales.size() - 2) { + TKey<Vector3> t0 = st->scales[i]; + TKey<Vector3> t1 = st->scales[i + 1]; + TKey<Vector3> t2 = st->scales[i + 2]; bool erase = _vector3_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error); if (erase) { - tt->scales.remove_at(i + 1); + st->scales.remove_at(i + 1); } else { i++; } } - if (tt->scales.size() == 2) { - if ((tt->scales[0].value - tt->scales[1].value).length() < p_allowed_precision_error) { - tt->scales.remove_at(1); + if (st->scales.size() == 2) { + if ((st->scales[0].value - st->scales[1].value).length() < p_allowed_precision_error) { + st->scales.remove_at(1); } } } @@ -4265,25 +4253,144 @@ void Animation::_scale_track_optimize(int p_idx, real_t p_allowed_velocity_err, void Animation::_blend_shape_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_precision_error) { ERR_FAIL_INDEX(p_idx, tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type != TYPE_BLEND_SHAPE); - BlendShapeTrack *tt = static_cast<BlendShapeTrack *>(tracks[p_idx]); + BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(tracks[p_idx]); int i = 0; - while (i < tt->blend_shapes.size() - 2) { - TKey<float> t0 = tt->blend_shapes[i]; - TKey<float> t1 = tt->blend_shapes[i + 1]; - TKey<float> t2 = tt->blend_shapes[i + 2]; + while (i < bst->blend_shapes.size() - 2) { + TKey<float> t0 = bst->blend_shapes[i]; + TKey<float> t1 = bst->blend_shapes[i + 1]; + TKey<float> t2 = bst->blend_shapes[i + 2]; bool erase = _float_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_precision_error); if (erase) { - tt->blend_shapes.remove_at(i + 1); + bst->blend_shapes.remove_at(i + 1); + } else { + i++; + } + } + + if (bst->blend_shapes.size() == 2) { + if (abs(bst->blend_shapes[0].value - bst->blend_shapes[1].value) < p_allowed_precision_error) { + bst->blend_shapes.remove_at(1); + } + } +} + +void Animation::_value_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) { + ERR_FAIL_INDEX(p_idx, tracks.size()); + ERR_FAIL_COND(tracks[p_idx]->type != TYPE_VALUE); + ValueTrack *vt = static_cast<ValueTrack *>(tracks[p_idx]); + if (vt->values.size() == 0) { + return; + } + Variant::Type type = vt->values[0].value.get_type(); + + // Special case for angle interpolation. + bool is_using_angle = vt->interpolation == Animation::INTERPOLATION_LINEAR_ANGLE || vt->interpolation == Animation::INTERPOLATION_CUBIC_ANGLE; + int i = 0; + while (i < vt->values.size() - 2) { + bool erase = false; + switch (type) { + case Variant::FLOAT: { + TKey<float> t0; + TKey<float> t1; + TKey<float> t2; + t0.time = vt->values[i].time; + t1.time = vt->values[i + 1].time; + t2.time = vt->values[i + 2].time; + t0.value = vt->values[i].value; + t1.value = vt->values[i + 1].value; + t2.value = vt->values[i + 2].value; + if (is_using_angle) { + float diff1 = fmod(t1.value - t0.value, Math_TAU); + t1.value = t0.value + fmod(2.0 * diff1, Math_TAU) - diff1; + float diff2 = fmod(t2.value - t1.value, Math_TAU); + t2.value = t1.value + fmod(2.0 * diff2, Math_TAU) - diff2; + if (abs(abs(diff1) + abs(diff2)) >= Math_PI) { + break; // Rotation is more than 180 deg, keep key. + } + } + erase = _float_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_precision_error); + } break; + case Variant::VECTOR2: { + TKey<Vector2> t0; + TKey<Vector2> t1; + TKey<Vector2> t2; + t0.time = vt->values[i].time; + t1.time = vt->values[i + 1].time; + t2.time = vt->values[i + 2].time; + t0.value = vt->values[i].value; + t1.value = vt->values[i + 1].value; + t2.value = vt->values[i + 2].value; + erase = _vector2_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error); + } break; + case Variant::VECTOR3: { + TKey<Vector3> t0; + TKey<Vector3> t1; + TKey<Vector3> t2; + t0.time = vt->values[i].time; + t1.time = vt->values[i + 1].time; + t2.time = vt->values[i + 2].time; + t0.value = vt->values[i].value; + t1.value = vt->values[i + 1].value; + t2.value = vt->values[i + 2].value; + erase = _vector3_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error); + } break; + case Variant::QUATERNION: { + TKey<Quaternion> t0; + TKey<Quaternion> t1; + TKey<Quaternion> t2; + t0.time = vt->values[i].time; + t1.time = vt->values[i + 1].time; + t2.time = vt->values[i + 2].time; + t0.value = vt->values[i].value; + t1.value = vt->values[i + 1].value; + t2.value = vt->values[i + 2].value; + erase = _quaternion_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error); + } break; + default: { + } break; + } + + if (erase) { + vt->values.remove_at(i + 1); } else { i++; } } - if (tt->blend_shapes.size() == 2) { - if (abs(tt->blend_shapes[0].value - tt->blend_shapes[1].value) < p_allowed_precision_error) { - tt->blend_shapes.remove_at(1); + if (vt->values.size() == 2) { + bool single_key = false; + switch (type) { + case Variant::FLOAT: { + float val_0 = vt->values[0].value; + float val_1 = vt->values[1].value; + if (is_using_angle) { + float diff1 = fmod(val_1 - val_0, Math_TAU); + val_1 = val_0 + fmod(2.0 * diff1, Math_TAU) - diff1; + } + single_key = abs(val_0 - val_1) < p_allowed_precision_error; + } break; + case Variant::VECTOR2: { + Vector2 val_0 = vt->values[0].value; + Vector2 val_1 = vt->values[1].value; + single_key = (val_0 - val_1).length() < p_allowed_precision_error; + } break; + case Variant::VECTOR3: { + Vector3 val_0 = vt->values[0].value; + Vector3 val_1 = vt->values[1].value; + single_key = (val_0 - val_1).length() < p_allowed_precision_error; + } break; + case Variant::QUATERNION: { + Quaternion val_0 = vt->values[0].value; + Quaternion val_1 = vt->values[1].value; + single_key = (val_0 - val_1).length() < p_allowed_precision_error; + } break; + default: { + } break; + } + if (single_key) { + vt->values.remove_at(1); } } } @@ -4302,6 +4409,8 @@ void Animation::optimize(real_t p_allowed_velocity_err, real_t p_allowed_angular _scale_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision); } else if (tracks[i]->type == TYPE_BLEND_SHAPE) { _blend_shape_track_optimize(i, p_allowed_velocity_err, precision); + } else if (tracks[i]->type == TYPE_VALUE) { + _value_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision); } } } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 5e88980397..46a88df130 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -57,7 +57,8 @@ public: INTERPOLATION_NEAREST, INTERPOLATION_LINEAR, INTERPOLATION_CUBIC, - INTERPOLATION_CUBIC_IN_TIME, + INTERPOLATION_LINEAR_ANGLE, + INTERPOLATION_CUBIC_ANGLE, }; enum UpdateMode { @@ -237,16 +238,13 @@ private: _FORCE_INLINE_ Quaternion _interpolate(const Quaternion &p_a, const Quaternion &p_b, real_t p_c) const; _FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const; _FORCE_INLINE_ real_t _interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const; - - _FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c) const; - _FORCE_INLINE_ Quaternion _cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const; - _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const; - _FORCE_INLINE_ real_t _cubic_interpolate(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c) const; + _FORCE_INLINE_ Variant _interpolate_angle(const Variant &p_a, const Variant &p_b, real_t p_c) const; _FORCE_INLINE_ Vector3 _cubic_interpolate_in_time(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; _FORCE_INLINE_ Quaternion _cubic_interpolate_in_time(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; _FORCE_INLINE_ Variant _cubic_interpolate_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; _FORCE_INLINE_ real_t _cubic_interpolate_in_time(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; + _FORCE_INLINE_ Variant _cubic_interpolate_angle_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const; template <class T> _FORCE_INLINE_ T _interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward = false) const; @@ -368,14 +366,16 @@ private: return idxr; } + bool _float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error); + bool _vector2_track_optimize_key(const TKey<Vector2> t0, const TKey<Vector2> t1, const TKey<Vector2> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error); bool _vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_alowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error); bool _quaternion_track_optimize_key(const TKey<Quaternion> t0, const TKey<Quaternion> t1, const TKey<Quaternion> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error); - bool _float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error); void _position_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error); void _rotation_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error); void _scale_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error); void _blend_shape_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_precision_error); + void _value_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error); protected: bool _set(const StringName &p_name, const Variant &p_value); diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp index 5f725b2fbe..427d418551 100644 --- a/scene/resources/animation_library.cpp +++ b/scene/resources/animation_library.cpp @@ -85,7 +85,7 @@ bool AnimationLibrary::has_animation(const StringName &p_name) const { } Ref<Animation> AnimationLibrary::get_animation(const StringName &p_name) const { - ERR_FAIL_COND_V(!animations.has(p_name), Ref<Animation>()); + ERR_FAIL_COND_V_MSG(!animations.has(p_name), Ref<Animation>(), vformat("Animation not found: \"%s\".", p_name)); return animations[p_name]; } diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index 214004824f..b0454004a0 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -40,8 +40,8 @@ Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() const { Vector3 d(0, height * 0.5 - radius, 0); for (int i = 0; i < 360; i++) { - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); + float ra = Math::deg_to_rad((float)i); + float rb = Math::deg_to_rad((float)i + 1); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 1835604285..ee53578517 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -763,7 +763,7 @@ void Curve2D::_bake_segment2d(RBMap<real_t, Vector2> &r_bake, real_t p_begin, re Vector2 nb = (end - mid).normalized(); real_t dp = na.dot(nb); - if (dp < Math::cos(Math::deg2rad(p_tol))) { + if (dp < Math::cos(Math::deg_to_rad(p_tol))) { r_bake[mp] = mid; } @@ -1352,7 +1352,7 @@ void Curve3D::_bake_segment3d(RBMap<real_t, Vector3> &r_bake, real_t p_begin, re Vector3 nb = (end - mid).normalized(); real_t dp = na.dot(nb); - if (dp < Math::cos(Math::deg2rad(p_tol))) { + if (dp < Math::cos(Math::deg_to_rad(p_tol))) { r_bake[mp] = mid; } if (p_depth < p_max_depth) { diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 345df5ffed..a5951db8ea 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -40,8 +40,8 @@ Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() const { Vector3 d(0, height * 0.5, 0); for (int i = 0; i < 360; i++) { - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); + float ra = Math::deg_to_rad((float)i); + float rb = Math::deg_to_rad((float)i + 1); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 6d99073fa4..410f35e597 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -35,6 +35,7 @@ #include "default_theme_icons.gen.h" #include "scene/resources/font.h" #include "scene/resources/theme.h" +#include "scene/theme/theme_db.h" #include "servers/text_server.h" #include "modules/modules_enabled.gen.h" // For svg. @@ -1053,7 +1054,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const default_style = make_flat_stylebox(Color(1, 0.365, 0.365), 4, 4, 4, 4, 0, false, 2); } -void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel, TextServer::Hinting p_font_hinting, bool p_font_antialiased, bool p_font_msdf, bool p_font_generate_mipmaps) { +void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel, TextServer::Hinting p_font_hinting, TextServer::FontAntialiasing p_font_antialiasing, bool p_font_msdf, bool p_font_generate_mipmaps) { Ref<Theme> t; t.instantiate(); @@ -1077,7 +1078,7 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos dynamic_font->set_data_ptr(_font_OpenSans_SemiBold, _font_OpenSans_SemiBold_size); dynamic_font->set_subpixel_positioning(p_font_subpixel); dynamic_font->set_hinting(p_font_hinting); - dynamic_font->set_antialiased(p_font_antialiased); + dynamic_font->set_antialiasing(p_font_antialiasing); dynamic_font->set_multichannel_signed_distance_field(p_font_msdf); dynamic_font->set_generate_mipmaps(p_font_generate_mipmaps); @@ -1101,18 +1102,11 @@ void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPos fill_default_theme(t, default_font, bold_font, bold_italics_font, italics_font, default_icon, default_style, default_scale); - Theme::set_default(t); - Theme::set_fallback_base_scale(default_scale); - Theme::set_fallback_icon(default_icon); - Theme::set_fallback_style(default_style); - Theme::set_fallback_font(default_font); - Theme::set_fallback_font_size(default_font_size * default_scale); -} + ThemeDB::get_singleton()->set_default_theme(t); -void clear_default_theme() { - Theme::set_project_default(nullptr); - Theme::set_default(nullptr); - Theme::set_fallback_icon(nullptr); - Theme::set_fallback_style(nullptr); - Theme::set_fallback_font(nullptr); + ThemeDB::get_singleton()->set_fallback_base_scale(default_scale); + ThemeDB::get_singleton()->set_fallback_icon(default_icon); + ThemeDB::get_singleton()->set_fallback_stylebox(default_style); + ThemeDB::get_singleton()->set_fallback_font(default_font); + ThemeDB::get_singleton()->set_fallback_font_size(default_font_size * default_scale); } diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index 9b070a90cc..003934ce90 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -36,7 +36,6 @@ const int default_font_size = 16; void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &bold_font, const Ref<Font> &bold_italics_font, const Ref<Font> &italics_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale); -void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, bool p_font_antialiased = true, bool p_font_msdf = false, bool p_font_generate_mipmaps = false); -void clear_default_theme(); +void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, TextServer::FontAntialiasing p_font_antialiased = TextServer::FONT_ANTIALIASING_GRAY, bool p_font_msdf = false, bool p_font_generate_mipmaps = false); #endif // DEFAULT_THEME_H diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index f8651fecd6..8ec5678f0a 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -39,6 +39,7 @@ #include "scene/resources/text_line.h" #include "scene/resources/text_paragraph.h" #include "scene/resources/theme.h" +#include "scene/theme/theme_db.h" /*************************************************************************/ /* Font */ @@ -576,7 +577,7 @@ _FORCE_INLINE_ void FontFile::_ensure_rid(int p_cache_index) const { if (unlikely(!cache[p_cache_index].is_valid())) { cache.write[p_cache_index] = TS->create_font(); TS->font_set_data_ptr(cache[p_cache_index], data_ptr, data_size); - TS->font_set_antialiased(cache[p_cache_index], antialiased); + TS->font_set_antialiasing(cache[p_cache_index], antialiasing); TS->font_set_generate_mipmaps(cache[p_cache_index], mipmaps); TS->font_set_multichannel_signed_distance_field(cache[p_cache_index], msdf); TS->font_set_msdf_pixel_range(cache[p_cache_index], msdf_pixel_range); @@ -875,8 +876,8 @@ void FontFile::_bind_methods() { ClassDB::bind_method(D_METHOD("set_font_style_name", "name"), &FontFile::set_font_style_name); ClassDB::bind_method(D_METHOD("set_font_style", "style"), &FontFile::set_font_style); - ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontFile::set_antialiased); - ClassDB::bind_method(D_METHOD("is_antialiased"), &FontFile::is_antialiased); + ClassDB::bind_method(D_METHOD("set_antialiasing", "antialiasing"), &FontFile::set_antialiasing); + ClassDB::bind_method(D_METHOD("get_antialiasing"), &FontFile::get_antialiasing); ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &FontFile::set_generate_mipmaps); ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &FontFile::get_generate_mipmaps); @@ -996,7 +997,7 @@ void FontFile::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_generate_mipmaps", "get_generate_mipmaps"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_STORAGE), "set_antialiasing", "get_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name"); ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic,Fixed Size", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style"); @@ -1318,7 +1319,7 @@ void FontFile::reset_state() { data_size = 0; cache.clear(); - antialiased = true; + antialiasing = TextServer::FONT_ANTIALIASING_GRAY; mipmaps = false; msdf = false; force_autohinter = false; @@ -1337,7 +1338,7 @@ void FontFile::reset_state() { Error FontFile::load_bitmap_font(const String &p_path) { reset_state(); - antialiased = false; + antialiasing = TextServer::FONT_ANTIALIASING_NONE; mipmaps = false; msdf = false; force_autohinter = false; @@ -1817,11 +1818,9 @@ void FontFile::set_data_ptr(const uint8_t *p_data, size_t p_size) { data_ptr = p_data; data_size = p_size; - if (data_ptr != nullptr) { - for (int i = 0; i < cache.size(); i++) { - if (cache[i].is_valid()) { - TS->font_set_data_ptr(cache[i], data_ptr, data_size); - } + for (int i = 0; i < cache.size(); i++) { + if (cache[i].is_valid()) { + TS->font_set_data_ptr(cache[i], data_ptr, data_size); } } } @@ -1831,11 +1830,9 @@ void FontFile::set_data(const PackedByteArray &p_data) { data_ptr = data.ptr(); data_size = data.size(); - if (data_ptr != nullptr) { - for (int i = 0; i < cache.size(); i++) { - if (cache[i].is_valid()) { - TS->font_set_data_ptr(cache[i], data_ptr, data_size); - } + for (int i = 0; i < cache.size(); i++) { + if (cache[i].is_valid()) { + TS->font_set_data_ptr(cache[i], data_ptr, data_size); } } } @@ -1864,19 +1861,19 @@ void FontFile::set_font_style(BitField<TextServer::FontStyle> p_style) { TS->font_set_style(cache[0], p_style); } -void FontFile::set_antialiased(bool p_antialiased) { - if (antialiased != p_antialiased) { - antialiased = p_antialiased; +void FontFile::set_antialiasing(TextServer::FontAntialiasing p_antialiasing) { + if (antialiasing != p_antialiasing) { + antialiasing = p_antialiasing; for (int i = 0; i < cache.size(); i++) { _ensure_rid(i); - TS->font_set_antialiased(cache[i], antialiased); + TS->font_set_antialiasing(cache[i], antialiasing); } emit_changed(); } } -bool FontFile::is_antialiased() const { - return antialiased; +TextServer::FontAntialiasing FontFile::get_antialiasing() const { + return antialiasing; } void FontFile::set_generate_mipmaps(bool p_generate_mipmaps) { @@ -2556,13 +2553,13 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { } // Check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { List<StringName> theme_types; - Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2573,13 +2570,13 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { } // Lastly, fall back on the items defined in the default Theme, if they exist. - if (Theme::get_default().is_valid()) { + if (ThemeDB::get_singleton()->get_default_theme().is_valid()) { List<StringName> theme_types; - Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2589,7 +2586,7 @@ Ref<Font> FontVariation::_get_base_font_or_default() const { } // If they don't exist, use any type to return the default/empty value. - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<FontVariation *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2699,8 +2696,8 @@ FontVariation::~FontVariation() { /*************************************************************************/ void SystemFont::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &SystemFont::set_antialiased); - ClassDB::bind_method(D_METHOD("is_antialiased"), &SystemFont::is_antialiased); + ClassDB::bind_method(D_METHOD("set_antialiasing", "antialiasing"), &SystemFont::set_antialiasing); + ClassDB::bind_method(D_METHOD("get_antialiasing"), &SystemFont::get_antialiasing); ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &SystemFont::set_generate_mipmaps); ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &SystemFont::get_generate_mipmaps); @@ -2727,7 +2724,7 @@ void SystemFont::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "font_names"), "set_font_names", "get_font_names"); ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic"), "set_font_style", "get_font_style"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_STORAGE), "set_antialiasing", "get_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "get_generate_mipmaps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); @@ -2804,7 +2801,7 @@ void SystemFont::_update_base_font() { } // Apply font rendering settings. - file->set_antialiased(antialiased); + file->set_antialiasing(antialiasing); file->set_generate_mipmaps(mipmaps); file->set_force_autohinter(force_autohinter); file->set_hinting(hinting); @@ -2841,7 +2838,7 @@ void SystemFont::reset_state() { ftr_weight = 0; ftr_italic = 0; style = 0; - antialiased = true; + antialiasing = TextServer::FONT_ANTIALIASING_GRAY; mipmaps = false; force_autohinter = false; hinting = TextServer::HINTING_LIGHT; @@ -2863,13 +2860,13 @@ Ref<Font> SystemFont::_get_base_font_or_default() const { } // Check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { List<StringName> theme_types; - Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2880,13 +2877,13 @@ Ref<Font> SystemFont::_get_base_font_or_default() const { } // Lastly, fall back on the items defined in the default Theme, if they exist. - if (Theme::get_default().is_valid()) { + if (ThemeDB::get_singleton()->get_default_theme().is_valid()) { List<StringName> theme_types; - Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2896,7 +2893,7 @@ Ref<Font> SystemFont::_get_base_font_or_default() const { } // If they don't exist, use any type to return the default/empty value. - Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + Ref<Font> f = ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); if (f.is_valid()) { theme_font = f; theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), CONNECT_REFERENCE_COUNTED); @@ -2907,18 +2904,18 @@ Ref<Font> SystemFont::_get_base_font_or_default() const { return Ref<Font>(); } -void SystemFont::set_antialiased(bool p_antialiased) { - if (antialiased != p_antialiased) { - antialiased = p_antialiased; +void SystemFont::set_antialiasing(TextServer::FontAntialiasing p_antialiasing) { + if (antialiasing != p_antialiasing) { + antialiasing = p_antialiasing; if (base_font.is_valid()) { - base_font->set_antialiased(antialiased); + base_font->set_antialiasing(antialiasing); } emit_changed(); } } -bool SystemFont::is_antialiased() const { - return antialiased; +TextServer::FontAntialiasing SystemFont::get_antialiasing() const { + return antialiasing; } void SystemFont::set_generate_mipmaps(bool p_generate_mipmaps) { diff --git a/scene/resources/font.h b/scene/resources/font.h index decbcfbb69..5cf596b41d 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -141,7 +141,7 @@ class FontFile : public Font { size_t data_size = 0; PackedByteArray data; - bool antialiased = true; + TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY; bool mipmaps = false; bool msdf = false; int msdf_pixel_range = 16; @@ -192,8 +192,8 @@ public: virtual void set_font_style_name(const String &p_name); virtual void set_font_style(BitField<TextServer::FontStyle> p_style); - virtual void set_antialiased(bool p_antialiased); - virtual bool is_antialiased() const; + virtual void set_antialiasing(TextServer::FontAntialiasing p_antialiasing); + virtual TextServer::FontAntialiasing get_antialiasing() const; virtual void set_generate_mipmaps(bool p_generate_mipmaps); virtual bool get_generate_mipmaps() const; @@ -398,7 +398,7 @@ class SystemFont : public Font { int ftr_weight = 0; int ftr_italic = 0; - bool antialiased = true; + TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY; bool mipmaps = false; bool force_autohinter = false; TextServer::Hinting hinting = TextServer::HINTING_LIGHT; @@ -417,8 +417,8 @@ protected: public: virtual Ref<Font> _get_base_font_or_default() const; - virtual void set_antialiased(bool p_antialiased); - virtual bool is_antialiased() const; + virtual void set_antialiasing(TextServer::FontAntialiasing p_antialiasing); + virtual TextServer::FontAntialiasing get_antialiasing() const; virtual void set_generate_mipmaps(bool p_generate_mipmaps); virtual bool get_generate_mipmaps() const; diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 293fdd6f05..3638d1862c 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -301,9 +301,9 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli } } - float normal_merge_threshold = Math::cos(Math::deg2rad(p_normal_merge_angle)); - float normal_pre_split_threshold = Math::cos(Math::deg2rad(MIN(180.0f, p_normal_split_angle * 2.0f))); - float normal_split_threshold = Math::cos(Math::deg2rad(p_normal_split_angle)); + float normal_merge_threshold = Math::cos(Math::deg_to_rad(p_normal_merge_angle)); + float normal_pre_split_threshold = Math::cos(Math::deg_to_rad(MIN(180.0f, p_normal_split_angle * 2.0f))); + float normal_split_threshold = Math::cos(Math::deg_to_rad(p_normal_split_angle)); const Vector3 *normals_ptr = normals.ptr(); HashMap<Vector3, LocalVector<Pair<int, int>>> unique_vertices; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 0e1b18d584..33334801c3 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -279,25 +279,36 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { Ref<Resource> res = value; if (res.is_valid()) { if (res->is_local_to_scene()) { - HashMap<Ref<Resource>, Ref<Resource>>::Iterator E = resources_local_to_scene.find(res); - - if (E) { - value = E->value; + // In a situation where a local-to-scene resource is used in a child node of a non-editable instance, + // we need to avoid the parent scene from overriding the resource potentially also used in the root + // of the instantiated scene. That would to the instance having two different instances of the resource. + // Since at this point it's too late to propagate the resource instance in the parent scene to all the relevant + // nodes in the instance (and that would require very complex bookkepping), what we do instead is + // tampering the resource object already there with the values from the node in the parent scene and + // then tell this node to reference that resource. + if (n.instance >= 0) { + Ref<Resource> node_res = node->get(snames[nprops[j].name]); + if (node_res.is_valid()) { + node_res->copy_from(res); + node_res->configure_for_local_scene(node, resources_local_to_scene); + value = node_res; + } } else { + HashMap<Ref<Resource>, Ref<Resource>>::Iterator E = resources_local_to_scene.find(res); Node *base = i == 0 ? node : ret_nodes[0]; - - if (p_edit_state == GEN_EDIT_STATE_MAIN || p_edit_state == GEN_EDIT_STATE_MAIN_INHERITED) { - //for the main scene, use the resource as is - res->configure_for_local_scene(base, resources_local_to_scene); - resources_local_to_scene[res] = res; - + if (E) { + value = E->value; } else { - //for instances, a copy must be made - Node *base2 = i == 0 ? node : ret_nodes[0]; - Ref<Resource> local_dupe = res->duplicate_for_local_scene(base2, resources_local_to_scene); - resources_local_to_scene[res] = local_dupe; - res = local_dupe; - value = local_dupe; + if (p_edit_state == GEN_EDIT_STATE_MAIN) { + //for the main scene, use the resource as is + res->configure_for_local_scene(base, resources_local_to_scene); + resources_local_to_scene[res] = res; + } else { + //for instances, a copy must be made + Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene); + resources_local_to_scene[res] = local_dupe; + value = local_dupe; + } } } //must make a copy, because this res is local to scene @@ -398,7 +409,9 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { } for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_scene) { - E.value->setup_local_to_scene(); + if (E.value->get_local_scene() == ret_nodes[0]) { + E.value->setup_local_to_scene(); + } } //do connections diff --git a/scene/resources/particles_material.cpp b/scene/resources/particle_process_material.cpp index 29a06622a3..ed19101de4 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* particles_material.cpp */ +/* particle_process_material.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "particles_material.h" +#include "particle_process_material.h" #include "core/version.h" -Mutex ParticlesMaterial::material_mutex; -SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = nullptr; -HashMap<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData, ParticlesMaterial::MaterialKey> ParticlesMaterial::shader_map; -ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = nullptr; +Mutex ParticleProcessMaterial::material_mutex; +SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; +HashMap<ParticleProcessMaterial::MaterialKey, ParticleProcessMaterial::ShaderData, ParticleProcessMaterial::MaterialKey> ParticleProcessMaterial::shader_map; +ParticleProcessMaterial::ShaderNames *ParticleProcessMaterial::shader_names = nullptr; -void ParticlesMaterial::init_shaders() { - dirty_materials = memnew(SelfList<ParticlesMaterial>::List); +void ParticleProcessMaterial::init_shaders() { + dirty_materials = memnew(SelfList<ParticleProcessMaterial>::List); shader_names = memnew(ShaderNames); @@ -121,14 +121,14 @@ void ParticlesMaterial::init_shaders() { shader_names->collision_bounce = "collision_bounce"; } -void ParticlesMaterial::finish_shaders() { +void ParticleProcessMaterial::finish_shaders() { memdelete(dirty_materials); dirty_materials = nullptr; memdelete(shader_names); } -void ParticlesMaterial::_update_shader() { +void ParticleProcessMaterial::_update_shader() { dirty_materials->remove(&element); MaterialKey mk = _compute_key(); @@ -155,7 +155,7 @@ void ParticlesMaterial::_update_shader() { //must create a shader! // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). - String code = "// NOTE: Shader automatically converted from " VERSION_NAME " " VERSION_FULL_CONFIG "'s ParticlesMaterial.\n\n"; + String code = "// NOTE: Shader automatically converted from " VERSION_NAME " " VERSION_FULL_CONFIG "'s ParticleProcessMaterial.\n\n"; code += "shader_type particles;\n"; @@ -908,7 +908,7 @@ void ParticlesMaterial::_update_shader() { RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); } -void ParticlesMaterial::flush_changes() { +void ParticleProcessMaterial::flush_changes() { MutexLock lock(material_mutex); while (dirty_materials->first()) { @@ -916,7 +916,7 @@ void ParticlesMaterial::flush_changes() { } } -void ParticlesMaterial::_queue_shader_change() { +void ParticleProcessMaterial::_queue_shader_change() { MutexLock lock(material_mutex); if (is_initialized && !element.in_list()) { @@ -924,40 +924,40 @@ void ParticlesMaterial::_queue_shader_change() { } } -bool ParticlesMaterial::_is_shader_dirty() const { +bool ParticleProcessMaterial::_is_shader_dirty() const { MutexLock lock(material_mutex); return element.in_list(); } -void ParticlesMaterial::set_direction(Vector3 p_direction) { +void ParticleProcessMaterial::set_direction(Vector3 p_direction) { direction = p_direction; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction); } -Vector3 ParticlesMaterial::get_direction() const { +Vector3 ParticleProcessMaterial::get_direction() const { return direction; } -void ParticlesMaterial::set_spread(float p_spread) { +void ParticleProcessMaterial::set_spread(float p_spread) { spread = p_spread; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread); } -float ParticlesMaterial::get_spread() const { +float ParticleProcessMaterial::get_spread() const { return spread; } -void ParticlesMaterial::set_flatness(float p_flatness) { +void ParticleProcessMaterial::set_flatness(float p_flatness) { flatness = p_flatness; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness); } -float ParticlesMaterial::get_flatness() const { +float ParticleProcessMaterial::get_flatness() const { return flatness; } -void ParticlesMaterial::set_param_min(Parameter p_param, float p_value) { +void ParticleProcessMaterial::set_param_min(Parameter p_param, float p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_min[p_param] = p_value; @@ -1016,13 +1016,13 @@ void ParticlesMaterial::set_param_min(Parameter p_param, float p_value) { } } -float ParticlesMaterial::get_param_min(Parameter p_param) const { +float ParticleProcessMaterial::get_param_min(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_min[p_param]; } -void ParticlesMaterial::set_param_max(Parameter p_param, float p_value) { +void ParticleProcessMaterial::set_param_max(Parameter p_param, float p_value) { ERR_FAIL_INDEX(p_param, PARAM_MAX); params_max[p_param] = p_value; @@ -1081,7 +1081,7 @@ void ParticlesMaterial::set_param_max(Parameter p_param, float p_value) { } } -float ParticlesMaterial::get_param_max(Parameter p_param) const { +float ParticleProcessMaterial::get_param_max(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); return params_max[p_param]; @@ -1096,7 +1096,7 @@ static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, fl curve_tex->ensure_default_setup(p_min, p_max); } -void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) { +void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) { ERR_FAIL_INDEX(p_param, PARAM_MAX); tex_parameters[p_param] = p_texture; @@ -1167,22 +1167,22 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D _queue_shader_change(); } -Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const { +Ref<Texture2D> ParticleProcessMaterial::get_param_texture(Parameter p_param) const { ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture2D>()); return tex_parameters[p_param]; } -void ParticlesMaterial::set_color(const Color &p_color) { +void ParticleProcessMaterial::set_color(const Color &p_color) { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color); color = p_color; } -Color ParticlesMaterial::get_color() const { +Color ParticleProcessMaterial::get_color() const { return color; } -void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { +void ParticleProcessMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, tex_rid); @@ -1190,11 +1190,11 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { notify_property_list_changed(); } -Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { +Ref<Texture2D> ParticleProcessMaterial::get_color_ramp() const { return color_ramp; } -void ParticlesMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) { +void ParticleProcessMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) { color_initial_ramp = p_texture; RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_initial_ramp, tex_rid); @@ -1202,11 +1202,11 @@ void ParticlesMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) notify_property_list_changed(); } -Ref<Texture2D> ParticlesMaterial::get_color_initial_ramp() const { +Ref<Texture2D> ParticleProcessMaterial::get_color_initial_ramp() const { return color_initial_ramp; } -void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { +void ParticleProcessMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); @@ -1215,165 +1215,165 @@ void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_ } } -bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { +bool ParticleProcessMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); return particle_flags[p_particle_flag]; } -void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { +void ParticleProcessMaterial::set_emission_shape(EmissionShape p_shape) { ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX); emission_shape = p_shape; notify_property_list_changed(); _queue_shader_change(); } -void ParticlesMaterial::set_emission_sphere_radius(real_t p_radius) { +void ParticleProcessMaterial::set_emission_sphere_radius(real_t p_radius) { emission_sphere_radius = p_radius; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius); } -void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) { +void ParticleProcessMaterial::set_emission_box_extents(Vector3 p_extents) { emission_box_extents = p_extents; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents); } -void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) { +void ParticleProcessMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) { emission_point_texture = p_points; RID tex_rid = p_points.is_valid() ? p_points->get_rid() : RID(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, tex_rid); } -void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) { +void ParticleProcessMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) { emission_normal_texture = p_normals; RID tex_rid = p_normals.is_valid() ? p_normals->get_rid() : RID(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, tex_rid); } -void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) { +void ParticleProcessMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) { emission_color_texture = p_colors; RID tex_rid = p_colors.is_valid() ? p_colors->get_rid() : RID(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, tex_rid); _queue_shader_change(); } -void ParticlesMaterial::set_emission_point_count(int p_count) { +void ParticleProcessMaterial::set_emission_point_count(int p_count) { emission_point_count = p_count; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count); } -void ParticlesMaterial::set_emission_ring_axis(Vector3 p_axis) { +void ParticleProcessMaterial::set_emission_ring_axis(Vector3 p_axis) { emission_ring_axis = p_axis; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ring_axis, p_axis); } -void ParticlesMaterial::set_emission_ring_height(real_t p_height) { +void ParticleProcessMaterial::set_emission_ring_height(real_t p_height) { emission_ring_height = p_height; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ring_height, p_height); } -void ParticlesMaterial::set_emission_ring_radius(real_t p_radius) { +void ParticleProcessMaterial::set_emission_ring_radius(real_t p_radius) { emission_ring_radius = p_radius; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ring_radius, p_radius); } -void ParticlesMaterial::set_emission_ring_inner_radius(real_t p_radius) { +void ParticleProcessMaterial::set_emission_ring_inner_radius(real_t p_radius) { emission_ring_inner_radius = p_radius; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ring_inner_radius, p_radius); } -ParticlesMaterial::EmissionShape ParticlesMaterial::get_emission_shape() const { +ParticleProcessMaterial::EmissionShape ParticleProcessMaterial::get_emission_shape() const { return emission_shape; } -real_t ParticlesMaterial::get_emission_sphere_radius() const { +real_t ParticleProcessMaterial::get_emission_sphere_radius() const { return emission_sphere_radius; } -Vector3 ParticlesMaterial::get_emission_box_extents() const { +Vector3 ParticleProcessMaterial::get_emission_box_extents() const { return emission_box_extents; } -Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const { +Ref<Texture2D> ParticleProcessMaterial::get_emission_point_texture() const { return emission_point_texture; } -Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const { +Ref<Texture2D> ParticleProcessMaterial::get_emission_normal_texture() const { return emission_normal_texture; } -Ref<Texture2D> ParticlesMaterial::get_emission_color_texture() const { +Ref<Texture2D> ParticleProcessMaterial::get_emission_color_texture() const { return emission_color_texture; } -int ParticlesMaterial::get_emission_point_count() const { +int ParticleProcessMaterial::get_emission_point_count() const { return emission_point_count; } -Vector3 ParticlesMaterial::get_emission_ring_axis() const { +Vector3 ParticleProcessMaterial::get_emission_ring_axis() const { return emission_ring_axis; } -real_t ParticlesMaterial::get_emission_ring_height() const { +real_t ParticleProcessMaterial::get_emission_ring_height() const { return emission_ring_height; } -real_t ParticlesMaterial::get_emission_ring_radius() const { +real_t ParticleProcessMaterial::get_emission_ring_radius() const { return emission_ring_radius; } -real_t ParticlesMaterial::get_emission_ring_inner_radius() const { +real_t ParticleProcessMaterial::get_emission_ring_inner_radius() const { return emission_ring_inner_radius; } -void ParticlesMaterial::set_turbulence_enabled(const bool p_turbulence_enabled) { +void ParticleProcessMaterial::set_turbulence_enabled(const bool p_turbulence_enabled) { turbulence_enabled = p_turbulence_enabled; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_enabled, turbulence_enabled); _queue_shader_change(); notify_property_list_changed(); } -bool ParticlesMaterial::get_turbulence_enabled() const { +bool ParticleProcessMaterial::get_turbulence_enabled() const { return turbulence_enabled; } -void ParticlesMaterial::set_turbulence_noise_strength(float p_turbulence_noise_strength) { +void ParticleProcessMaterial::set_turbulence_noise_strength(float p_turbulence_noise_strength) { turbulence_noise_strength = p_turbulence_noise_strength; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_strength, p_turbulence_noise_strength); } -float ParticlesMaterial::get_turbulence_noise_strength() const { +float ParticleProcessMaterial::get_turbulence_noise_strength() const { return turbulence_noise_strength; } -void ParticlesMaterial::set_turbulence_noise_scale(float p_turbulence_noise_scale) { +void ParticleProcessMaterial::set_turbulence_noise_scale(float p_turbulence_noise_scale) { turbulence_noise_scale = p_turbulence_noise_scale; float shader_turbulence_noise_scale = (pow(p_turbulence_noise_scale, 0.25) * 5.6234 / 10.0) * 4.0 - 3.0; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_scale, shader_turbulence_noise_scale); } -float ParticlesMaterial::get_turbulence_noise_scale() const { +float ParticleProcessMaterial::get_turbulence_noise_scale() const { return turbulence_noise_scale; } -void ParticlesMaterial::set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random) { +void ParticleProcessMaterial::set_turbulence_noise_speed_random(float p_turbulence_noise_speed_random) { turbulence_noise_speed_random = p_turbulence_noise_speed_random; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed_random, p_turbulence_noise_speed_random); } -float ParticlesMaterial::get_turbulence_noise_speed_random() const { +float ParticleProcessMaterial::get_turbulence_noise_speed_random() const { return turbulence_noise_speed_random; } -void ParticlesMaterial::set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed) { +void ParticleProcessMaterial::set_turbulence_noise_speed(const Vector3 &p_turbulence_noise_speed) { turbulence_noise_speed = p_turbulence_noise_speed; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->turbulence_noise_speed, turbulence_noise_speed); } -Vector3 ParticlesMaterial::get_turbulence_noise_speed() const { +Vector3 ParticleProcessMaterial::get_turbulence_noise_speed() const { return turbulence_noise_speed; } -void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { +void ParticleProcessMaterial::set_gravity(const Vector3 &p_gravity) { gravity = p_gravity; Vector3 gset = gravity; if (gset == Vector3()) { @@ -1382,25 +1382,25 @@ void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->gravity, gset); } -Vector3 ParticlesMaterial::get_gravity() const { +Vector3 ParticleProcessMaterial::get_gravity() const { return gravity; } -void ParticlesMaterial::set_lifetime_randomness(double p_lifetime) { +void ParticleProcessMaterial::set_lifetime_randomness(double p_lifetime) { lifetime_randomness = p_lifetime; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness); } -double ParticlesMaterial::get_lifetime_randomness() const { +double ParticleProcessMaterial::get_lifetime_randomness() const { return lifetime_randomness; } -RID ParticlesMaterial::get_shader_rid() const { +RID ParticleProcessMaterial::get_shader_rid() const { ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); return shader_map[current_key].shader; } -void ParticlesMaterial::_validate_property(PropertyInfo &p_property) const { +void ParticleProcessMaterial::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { p_property.usage = PROPERTY_USAGE_NONE; } @@ -1460,203 +1460,203 @@ void ParticlesMaterial::_validate_property(PropertyInfo &p_property) const { } } -void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { +void ParticleProcessMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { sub_emitter_mode = p_sub_emitter_mode; _queue_shader_change(); notify_property_list_changed(); } -ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const { +ParticleProcessMaterial::SubEmitterMode ParticleProcessMaterial::get_sub_emitter_mode() const { return sub_emitter_mode; } -void ParticlesMaterial::set_sub_emitter_frequency(double p_frequency) { +void ParticleProcessMaterial::set_sub_emitter_frequency(double p_frequency) { sub_emitter_frequency = p_frequency; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pass delta instead of frequency, since its easier to compute } -double ParticlesMaterial::get_sub_emitter_frequency() const { +double ParticleProcessMaterial::get_sub_emitter_frequency() const { return sub_emitter_frequency; } -void ParticlesMaterial::set_sub_emitter_amount_at_end(int p_amount) { +void ParticleProcessMaterial::set_sub_emitter_amount_at_end(int p_amount) { sub_emitter_amount_at_end = p_amount; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_amount_at_end, p_amount); } -int ParticlesMaterial::get_sub_emitter_amount_at_end() const { +int ParticleProcessMaterial::get_sub_emitter_amount_at_end() const { return sub_emitter_amount_at_end; } -void ParticlesMaterial::set_sub_emitter_keep_velocity(bool p_enable) { +void ParticleProcessMaterial::set_sub_emitter_keep_velocity(bool p_enable) { sub_emitter_keep_velocity = p_enable; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_keep_velocity, p_enable); } -bool ParticlesMaterial::get_sub_emitter_keep_velocity() const { +bool ParticleProcessMaterial::get_sub_emitter_keep_velocity() const { return sub_emitter_keep_velocity; } -void ParticlesMaterial::set_attractor_interaction_enabled(bool p_enable) { +void ParticleProcessMaterial::set_attractor_interaction_enabled(bool p_enable) { attractor_interaction_enabled = p_enable; _queue_shader_change(); } -bool ParticlesMaterial::is_attractor_interaction_enabled() const { +bool ParticleProcessMaterial::is_attractor_interaction_enabled() const { return attractor_interaction_enabled; } -void ParticlesMaterial::set_collision_mode(CollisionMode p_collision_mode) { +void ParticleProcessMaterial::set_collision_mode(CollisionMode p_collision_mode) { collision_mode = p_collision_mode; _queue_shader_change(); notify_property_list_changed(); } -ParticlesMaterial::CollisionMode ParticlesMaterial::get_collision_mode() const { +ParticleProcessMaterial::CollisionMode ParticleProcessMaterial::get_collision_mode() const { return collision_mode; } -void ParticlesMaterial::set_collision_use_scale(bool p_scale) { +void ParticleProcessMaterial::set_collision_use_scale(bool p_scale) { collision_scale = p_scale; _queue_shader_change(); } -bool ParticlesMaterial::is_collision_using_scale() const { +bool ParticleProcessMaterial::is_collision_using_scale() const { return collision_scale; } -void ParticlesMaterial::set_collision_friction(float p_friction) { +void ParticleProcessMaterial::set_collision_friction(float p_friction) { collision_friction = p_friction; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->collision_friction, p_friction); } -float ParticlesMaterial::get_collision_friction() const { +float ParticleProcessMaterial::get_collision_friction() const { return collision_friction; } -void ParticlesMaterial::set_collision_bounce(float p_bounce) { +void ParticleProcessMaterial::set_collision_bounce(float p_bounce) { collision_bounce = p_bounce; RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->collision_bounce, p_bounce); } -float ParticlesMaterial::get_collision_bounce() const { +float ParticleProcessMaterial::get_collision_bounce() const { return collision_bounce; } -Shader::Mode ParticlesMaterial::get_shader_mode() const { +Shader::Mode ParticleProcessMaterial::get_shader_mode() const { return Shader::MODE_PARTICLES; } -void ParticlesMaterial::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticlesMaterial::set_direction); - ClassDB::bind_method(D_METHOD("get_direction"), &ParticlesMaterial::get_direction); +void ParticleProcessMaterial::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticleProcessMaterial::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &ParticleProcessMaterial::get_direction); - ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticlesMaterial::set_spread); - ClassDB::bind_method(D_METHOD("get_spread"), &ParticlesMaterial::get_spread); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticleProcessMaterial::set_spread); + ClassDB::bind_method(D_METHOD("get_spread"), &ParticleProcessMaterial::get_spread); - ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &ParticlesMaterial::set_flatness); - ClassDB::bind_method(D_METHOD("get_flatness"), &ParticlesMaterial::get_flatness); + ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &ParticleProcessMaterial::set_flatness); + ClassDB::bind_method(D_METHOD("get_flatness"), &ParticleProcessMaterial::get_flatness); - ClassDB::bind_method(D_METHOD("set_param_min", "param", "value"), &ParticlesMaterial::set_param_min); - ClassDB::bind_method(D_METHOD("get_param_min", "param"), &ParticlesMaterial::get_param_min); + ClassDB::bind_method(D_METHOD("set_param_min", "param", "value"), &ParticleProcessMaterial::set_param_min); + ClassDB::bind_method(D_METHOD("get_param_min", "param"), &ParticleProcessMaterial::get_param_min); - ClassDB::bind_method(D_METHOD("set_param_max", "param", "value"), &ParticlesMaterial::set_param_max); - ClassDB::bind_method(D_METHOD("get_param_max", "param"), &ParticlesMaterial::get_param_max); + ClassDB::bind_method(D_METHOD("set_param_max", "param", "value"), &ParticleProcessMaterial::set_param_max); + ClassDB::bind_method(D_METHOD("get_param_max", "param"), &ParticleProcessMaterial::get_param_max); - ClassDB::bind_method(D_METHOD("set_param_texture", "param", "texture"), &ParticlesMaterial::set_param_texture); - ClassDB::bind_method(D_METHOD("get_param_texture", "param"), &ParticlesMaterial::get_param_texture); + ClassDB::bind_method(D_METHOD("set_param_texture", "param", "texture"), &ParticleProcessMaterial::set_param_texture); + ClassDB::bind_method(D_METHOD("get_param_texture", "param"), &ParticleProcessMaterial::get_param_texture); - ClassDB::bind_method(D_METHOD("set_color", "color"), &ParticlesMaterial::set_color); - ClassDB::bind_method(D_METHOD("get_color"), &ParticlesMaterial::get_color); + ClassDB::bind_method(D_METHOD("set_color", "color"), &ParticleProcessMaterial::set_color); + ClassDB::bind_method(D_METHOD("get_color"), &ParticleProcessMaterial::get_color); - ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); - ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticleProcessMaterial::set_color_ramp); + ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticleProcessMaterial::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &ParticlesMaterial::set_color_initial_ramp); - ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &ParticlesMaterial::get_color_initial_ramp); + ClassDB::bind_method(D_METHOD("set_color_initial_ramp", "ramp"), &ParticleProcessMaterial::set_color_initial_ramp); + ClassDB::bind_method(D_METHOD("get_color_initial_ramp"), &ParticleProcessMaterial::get_color_initial_ramp); - ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag); - ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticleProcessMaterial::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticleProcessMaterial::get_particle_flag); - ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape); - ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape); + ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticleProcessMaterial::set_emission_shape); + ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticleProcessMaterial::get_emission_shape); - ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &ParticlesMaterial::set_emission_sphere_radius); - ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &ParticlesMaterial::get_emission_sphere_radius); + ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &ParticleProcessMaterial::set_emission_sphere_radius); + ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &ParticleProcessMaterial::get_emission_sphere_radius); - ClassDB::bind_method(D_METHOD("set_emission_box_extents", "extents"), &ParticlesMaterial::set_emission_box_extents); - ClassDB::bind_method(D_METHOD("get_emission_box_extents"), &ParticlesMaterial::get_emission_box_extents); + ClassDB::bind_method(D_METHOD("set_emission_box_extents", "extents"), &ParticleProcessMaterial::set_emission_box_extents); + ClassDB::bind_method(D_METHOD("get_emission_box_extents"), &ParticleProcessMaterial::get_emission_box_extents); - ClassDB::bind_method(D_METHOD("set_emission_point_texture", "texture"), &ParticlesMaterial::set_emission_point_texture); - ClassDB::bind_method(D_METHOD("get_emission_point_texture"), &ParticlesMaterial::get_emission_point_texture); + ClassDB::bind_method(D_METHOD("set_emission_point_texture", "texture"), &ParticleProcessMaterial::set_emission_point_texture); + ClassDB::bind_method(D_METHOD("get_emission_point_texture"), &ParticleProcessMaterial::get_emission_point_texture); - ClassDB::bind_method(D_METHOD("set_emission_normal_texture", "texture"), &ParticlesMaterial::set_emission_normal_texture); - ClassDB::bind_method(D_METHOD("get_emission_normal_texture"), &ParticlesMaterial::get_emission_normal_texture); + ClassDB::bind_method(D_METHOD("set_emission_normal_texture", "texture"), &ParticleProcessMaterial::set_emission_normal_texture); + ClassDB::bind_method(D_METHOD("get_emission_normal_texture"), &ParticleProcessMaterial::get_emission_normal_texture); - ClassDB::bind_method(D_METHOD("set_emission_color_texture", "texture"), &ParticlesMaterial::set_emission_color_texture); - ClassDB::bind_method(D_METHOD("get_emission_color_texture"), &ParticlesMaterial::get_emission_color_texture); + ClassDB::bind_method(D_METHOD("set_emission_color_texture", "texture"), &ParticleProcessMaterial::set_emission_color_texture); + ClassDB::bind_method(D_METHOD("get_emission_color_texture"), &ParticleProcessMaterial::get_emission_color_texture); - ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count); - ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count); + ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticleProcessMaterial::set_emission_point_count); + ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticleProcessMaterial::get_emission_point_count); - ClassDB::bind_method(D_METHOD("set_emission_ring_axis", "axis"), &ParticlesMaterial::set_emission_ring_axis); - ClassDB::bind_method(D_METHOD("get_emission_ring_axis"), &ParticlesMaterial::get_emission_ring_axis); + ClassDB::bind_method(D_METHOD("set_emission_ring_axis", "axis"), &ParticleProcessMaterial::set_emission_ring_axis); + ClassDB::bind_method(D_METHOD("get_emission_ring_axis"), &ParticleProcessMaterial::get_emission_ring_axis); - ClassDB::bind_method(D_METHOD("set_emission_ring_height", "height"), &ParticlesMaterial::set_emission_ring_height); - ClassDB::bind_method(D_METHOD("get_emission_ring_height"), &ParticlesMaterial::get_emission_ring_height); + ClassDB::bind_method(D_METHOD("set_emission_ring_height", "height"), &ParticleProcessMaterial::set_emission_ring_height); + ClassDB::bind_method(D_METHOD("get_emission_ring_height"), &ParticleProcessMaterial::get_emission_ring_height); - ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &ParticlesMaterial::set_emission_ring_radius); - ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &ParticlesMaterial::get_emission_ring_radius); + ClassDB::bind_method(D_METHOD("set_emission_ring_radius", "radius"), &ParticleProcessMaterial::set_emission_ring_radius); + ClassDB::bind_method(D_METHOD("get_emission_ring_radius"), &ParticleProcessMaterial::get_emission_ring_radius); - ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &ParticlesMaterial::set_emission_ring_inner_radius); - ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &ParticlesMaterial::get_emission_ring_inner_radius); + ClassDB::bind_method(D_METHOD("set_emission_ring_inner_radius", "inner_radius"), &ParticleProcessMaterial::set_emission_ring_inner_radius); + ClassDB::bind_method(D_METHOD("get_emission_ring_inner_radius"), &ParticleProcessMaterial::get_emission_ring_inner_radius); - ClassDB::bind_method(D_METHOD("get_turbulence_enabled"), &ParticlesMaterial::get_turbulence_enabled); - ClassDB::bind_method(D_METHOD("set_turbulence_enabled", "turbulence_enabled"), &ParticlesMaterial::set_turbulence_enabled); + ClassDB::bind_method(D_METHOD("get_turbulence_enabled"), &ParticleProcessMaterial::get_turbulence_enabled); + ClassDB::bind_method(D_METHOD("set_turbulence_enabled", "turbulence_enabled"), &ParticleProcessMaterial::set_turbulence_enabled); - ClassDB::bind_method(D_METHOD("get_turbulence_noise_strength"), &ParticlesMaterial::get_turbulence_noise_strength); - ClassDB::bind_method(D_METHOD("set_turbulence_noise_strength", "turbulence_noise_strength"), &ParticlesMaterial::set_turbulence_noise_strength); + ClassDB::bind_method(D_METHOD("get_turbulence_noise_strength"), &ParticleProcessMaterial::get_turbulence_noise_strength); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_strength", "turbulence_noise_strength"), &ParticleProcessMaterial::set_turbulence_noise_strength); - ClassDB::bind_method(D_METHOD("get_turbulence_noise_scale"), &ParticlesMaterial::get_turbulence_noise_scale); - ClassDB::bind_method(D_METHOD("set_turbulence_noise_scale", "turbulence_noise_scale"), &ParticlesMaterial::set_turbulence_noise_scale); + ClassDB::bind_method(D_METHOD("get_turbulence_noise_scale"), &ParticleProcessMaterial::get_turbulence_noise_scale); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_scale", "turbulence_noise_scale"), &ParticleProcessMaterial::set_turbulence_noise_scale); - ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed_random"), &ParticlesMaterial::get_turbulence_noise_speed_random); - ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed_random", "turbulence_noise_speed_random"), &ParticlesMaterial::set_turbulence_noise_speed_random); + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed_random"), &ParticleProcessMaterial::get_turbulence_noise_speed_random); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed_random", "turbulence_noise_speed_random"), &ParticleProcessMaterial::set_turbulence_noise_speed_random); - ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed"), &ParticlesMaterial::get_turbulence_noise_speed); - ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed", "turbulence_noise_speed"), &ParticlesMaterial::set_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("get_turbulence_noise_speed"), &ParticleProcessMaterial::get_turbulence_noise_speed); + ClassDB::bind_method(D_METHOD("set_turbulence_noise_speed", "turbulence_noise_speed"), &ParticleProcessMaterial::set_turbulence_noise_speed); - ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); - ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); + ClassDB::bind_method(D_METHOD("get_gravity"), &ParticleProcessMaterial::get_gravity); + ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticleProcessMaterial::set_gravity); - ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticlesMaterial::set_lifetime_randomness); - ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness); + ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticleProcessMaterial::set_lifetime_randomness); + ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticleProcessMaterial::get_lifetime_randomness); - ClassDB::bind_method(D_METHOD("get_sub_emitter_mode"), &ParticlesMaterial::get_sub_emitter_mode); - ClassDB::bind_method(D_METHOD("set_sub_emitter_mode", "mode"), &ParticlesMaterial::set_sub_emitter_mode); + ClassDB::bind_method(D_METHOD("get_sub_emitter_mode"), &ParticleProcessMaterial::get_sub_emitter_mode); + ClassDB::bind_method(D_METHOD("set_sub_emitter_mode", "mode"), &ParticleProcessMaterial::set_sub_emitter_mode); - ClassDB::bind_method(D_METHOD("get_sub_emitter_frequency"), &ParticlesMaterial::get_sub_emitter_frequency); - ClassDB::bind_method(D_METHOD("set_sub_emitter_frequency", "hz"), &ParticlesMaterial::set_sub_emitter_frequency); + ClassDB::bind_method(D_METHOD("get_sub_emitter_frequency"), &ParticleProcessMaterial::get_sub_emitter_frequency); + ClassDB::bind_method(D_METHOD("set_sub_emitter_frequency", "hz"), &ParticleProcessMaterial::set_sub_emitter_frequency); - ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_end"), &ParticlesMaterial::get_sub_emitter_amount_at_end); - ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_end", "amount"), &ParticlesMaterial::set_sub_emitter_amount_at_end); + ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_end"), &ParticleProcessMaterial::get_sub_emitter_amount_at_end); + ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_end", "amount"), &ParticleProcessMaterial::set_sub_emitter_amount_at_end); - ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticlesMaterial::get_sub_emitter_keep_velocity); - ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticlesMaterial::set_sub_emitter_keep_velocity); + ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticleProcessMaterial::get_sub_emitter_keep_velocity); + ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticleProcessMaterial::set_sub_emitter_keep_velocity); - ClassDB::bind_method(D_METHOD("set_attractor_interaction_enabled", "enabled"), &ParticlesMaterial::set_attractor_interaction_enabled); - ClassDB::bind_method(D_METHOD("is_attractor_interaction_enabled"), &ParticlesMaterial::is_attractor_interaction_enabled); + ClassDB::bind_method(D_METHOD("set_attractor_interaction_enabled", "enabled"), &ParticleProcessMaterial::set_attractor_interaction_enabled); + ClassDB::bind_method(D_METHOD("is_attractor_interaction_enabled"), &ParticleProcessMaterial::is_attractor_interaction_enabled); - ClassDB::bind_method(D_METHOD("set_collision_mode", "mode"), &ParticlesMaterial::set_collision_mode); - ClassDB::bind_method(D_METHOD("get_collision_mode"), &ParticlesMaterial::get_collision_mode); + ClassDB::bind_method(D_METHOD("set_collision_mode", "mode"), &ParticleProcessMaterial::set_collision_mode); + ClassDB::bind_method(D_METHOD("get_collision_mode"), &ParticleProcessMaterial::get_collision_mode); - ClassDB::bind_method(D_METHOD("set_collision_use_scale", "radius"), &ParticlesMaterial::set_collision_use_scale); - ClassDB::bind_method(D_METHOD("is_collision_using_scale"), &ParticlesMaterial::is_collision_using_scale); + ClassDB::bind_method(D_METHOD("set_collision_use_scale", "radius"), &ParticleProcessMaterial::set_collision_use_scale); + ClassDB::bind_method(D_METHOD("is_collision_using_scale"), &ParticleProcessMaterial::is_collision_using_scale); - ClassDB::bind_method(D_METHOD("set_collision_friction", "friction"), &ParticlesMaterial::set_collision_friction); - ClassDB::bind_method(D_METHOD("get_collision_friction"), &ParticlesMaterial::get_collision_friction); + ClassDB::bind_method(D_METHOD("set_collision_friction", "friction"), &ParticleProcessMaterial::set_collision_friction); + ClassDB::bind_method(D_METHOD("get_collision_friction"), &ParticleProcessMaterial::get_collision_friction); - ClassDB::bind_method(D_METHOD("set_collision_bounce", "bounce"), &ParticlesMaterial::set_collision_bounce); - ClassDB::bind_method(D_METHOD("get_collision_bounce"), &ParticlesMaterial::get_collision_bounce); + ClassDB::bind_method(D_METHOD("set_collision_bounce", "bounce"), &ParticleProcessMaterial::set_collision_bounce); + ClassDB::bind_method(D_METHOD("get_collision_bounce"), &ParticleProcessMaterial::get_collision_bounce); ADD_GROUP("Time", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); @@ -1806,7 +1806,7 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(COLLISION_MAX); } -ParticlesMaterial::ParticlesMaterial() : +ParticleProcessMaterial::ParticleProcessMaterial() : element(this) { set_direction(Vector3(1, 0, 0)); set_spread(45); @@ -1879,7 +1879,7 @@ ParticlesMaterial::ParticlesMaterial() : _queue_shader_change(); } -ParticlesMaterial::~ParticlesMaterial() { +ParticleProcessMaterial::~ParticleProcessMaterial() { MutexLock lock(material_mutex); if (shader_map.has(current_key)) { diff --git a/scene/resources/particles_material.h b/scene/resources/particle_process_material.h index 2e94e7e01a..fe4741d6e5 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particle_process_material.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* particles_material.h */ +/* particle_process_material.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -31,8 +31,8 @@ #include "core/templates/rid.h" #include "scene/resources/material.h" -#ifndef PARTICLES_MATERIAL_H -#define PARTICLES_MATERIAL_H +#ifndef PARTICLE_PROCESS_MATERIAL_H +#define PARTICLE_PROCESS_MATERIAL_H /* TODO: @@ -41,8 +41,8 @@ -Proper trails */ -class ParticlesMaterial : public Material { - GDCLASS(ParticlesMaterial, Material); +class ParticleProcessMaterial : public Material { + GDCLASS(ParticleProcessMaterial, Material); public: enum Parameter { @@ -170,7 +170,7 @@ private: } static Mutex material_mutex; - static SelfList<ParticlesMaterial>::List *dirty_materials; + static SelfList<ParticleProcessMaterial>::List *dirty_materials; struct ShaderNames { StringName direction; @@ -254,7 +254,7 @@ private: static ShaderNames *shader_names; - SelfList<ParticlesMaterial> element; + SelfList<ParticleProcessMaterial> element; void _update_shader(); _FORCE_INLINE_ void _queue_shader_change(); @@ -425,14 +425,14 @@ public: virtual Shader::Mode get_shader_mode() const override; - ParticlesMaterial(); - ~ParticlesMaterial(); + ParticleProcessMaterial(); + ~ParticleProcessMaterial(); }; -VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) -VARIANT_ENUM_CAST(ParticlesMaterial::ParticleFlags) -VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) -VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode) -VARIANT_ENUM_CAST(ParticlesMaterial::CollisionMode) +VARIANT_ENUM_CAST(ParticleProcessMaterial::Parameter) +VARIANT_ENUM_CAST(ParticleProcessMaterial::ParticleFlags) +VARIANT_ENUM_CAST(ParticleProcessMaterial::EmissionShape) +VARIANT_ENUM_CAST(ParticleProcessMaterial::SubEmitterMode) +VARIANT_ENUM_CAST(ParticleProcessMaterial::CollisionMode) -#endif // PARTICLES_MATERIAL_H +#endif // PARTICLE_PROCESS_MATERIAL_H diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 7847acb318..fc5cf2a028 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -32,6 +32,7 @@ #include "core/core_string_names.h" #include "scene/resources/theme.h" +#include "scene/theme/theme_db.h" #include "servers/rendering_server.h" #include "thirdparty/misc/clipper.hpp" #include "thirdparty/misc/polypartition.h" @@ -2458,9 +2459,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { dirty_text = false; dirty_font = false; - if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - TS->shaped_text_fit_to_width(text_rid, width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); - } + dirty_lines = true; } else if (dirty_font) { int spans = TS->shaped_get_span_count(text_rid); for (int i = 0; i < spans; i++) { @@ -2471,81 +2470,138 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { } dirty_font = false; + dirty_lines = true; + } + + if (dirty_lines) { + for (int i = 0; i < lines_rid.size(); i++) { + TS->free_rid(lines_rid[i]); + } + lines_rid.clear(); + + BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY; + switch (autowrap_mode) { + case TextServer::AUTOWRAP_WORD_SMART: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_WORD: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_ARBITRARY: + autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_OFF: + break; + } + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + + float max_line_w = 0.0; + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); + max_line_w = MAX(max_line_w, TS->shaped_text_get_width(line)); + lines_rid.push_back(line); + } + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - TS->shaped_text_fit_to_width(text_rid, width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); + for (int i = 0; i < lines_rid.size() - 1; i++) { + TS->shaped_text_fit_to_width(lines_rid[i], (width > 0) ? width : max_line_w, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA); + } } + dirty_lines = false; } - Vector2 offset; - const Glyph *glyphs = TS->shaped_text_get_glyphs(text_rid); - int gl_size = TS->shaped_text_get_glyph_count(text_rid); - float line_width = TS->shaped_text_get_width(text_rid) * pixel_size; - - switch (horizontal_alignment) { - case HORIZONTAL_ALIGNMENT_LEFT: - offset.x = 0.0; - break; - case HORIZONTAL_ALIGNMENT_FILL: - case HORIZONTAL_ALIGNMENT_CENTER: { - offset.x = -line_width / 2.0; + float total_h = 0.0; + for (int i = 0; i < lines_rid.size(); i++) { + total_h += (TS->shaped_text_get_size(lines_rid[i]).y + line_spacing) * pixel_size; + } + + float vbegin = 0.0; + switch (vertical_alignment) { + case VERTICAL_ALIGNMENT_FILL: + case VERTICAL_ALIGNMENT_TOP: { + // Nothing. + } break; + case VERTICAL_ALIGNMENT_CENTER: { + vbegin = (total_h - line_spacing * pixel_size) / 2.0; } break; - case HORIZONTAL_ALIGNMENT_RIGHT: { - offset.x = -line_width; + case VERTICAL_ALIGNMENT_BOTTOM: { + vbegin = (total_h - line_spacing * pixel_size); } break; } - bool has_depth = !Math::is_zero_approx(depth); - - // Generate glyph data, precalculate size of the arrays and mesh bounds for UV. - int64_t p_size = 0; - int64_t i_size = 0; + Vector<Vector3> vertices; + Vector<Vector3> normals; + Vector<float> tangents; + Vector<Vector2> uvs; + Vector<int32_t> indices; Vector2 min_p = Vector2(INFINITY, INFINITY); Vector2 max_p = Vector2(-INFINITY, -INFINITY); - Vector2 offset_pre = offset; - for (int i = 0; i < gl_size; i++) { - if (glyphs[i].index == 0) { - offset.x += glyphs[i].advance * pixel_size * glyphs[i].repeat; - continue; + int32_t p_size = 0; + int32_t i_size = 0; + + Vector2 offset = Vector2(0, vbegin + lbl_offset.y * pixel_size); + for (int i = 0; i < lines_rid.size(); i++) { + const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); + int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]); + float line_width = TS->shaped_text_get_width(lines_rid[i]) * pixel_size; + + switch (horizontal_alignment) { + case HORIZONTAL_ALIGNMENT_LEFT: + offset.x = 0.0; + break; + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_CENTER: { + offset.x = -line_width / 2.0; + } break; + case HORIZONTAL_ALIGNMENT_RIGHT: { + offset.x = -line_width; + } break; } - if (glyphs[i].font_rid != RID()) { - GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index); - _generate_glyph_mesh_data(key, glyphs[i]); - GlyphMeshData &gl_data = cache[key]; - - p_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); - i_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); - - if (has_depth) { - for (int j = 0; j < gl_data.contours.size(); j++) { - p_size += glyphs[i].repeat * gl_data.contours[j].size() * 4; - i_size += glyphs[i].repeat * gl_data.contours[j].size() * 6; - } - } + offset.x += lbl_offset.x * pixel_size; + offset.y -= TS->shaped_text_get_ascent(lines_rid[i]) * pixel_size; - for (int j = 0; j < glyphs[i].repeat; j++) { - min_p.x = MIN(gl_data.min_p.x + offset_pre.x, min_p.x); - min_p.y = MIN(gl_data.min_p.y + offset_pre.y, min_p.y); - max_p.x = MAX(gl_data.max_p.x + offset_pre.x, max_p.x); - max_p.y = MAX(gl_data.max_p.y + offset_pre.y, max_p.y); + bool has_depth = !Math::is_zero_approx(depth); - offset_pre.x += glyphs[i].advance * pixel_size; + for (int j = 0; j < gl_size; j++) { + if (glyphs[j].index == 0) { + offset.x += glyphs[j].advance * pixel_size * glyphs[j].repeat; + continue; } - } else { - p_size += glyphs[i].repeat * 4; - i_size += glyphs[i].repeat * 6; + if (glyphs[j].font_rid != RID()) { + GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); + _generate_glyph_mesh_data(key, glyphs[j]); + GlyphMeshData &gl_data = cache[key]; + + p_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); + i_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); + + if (has_depth) { + for (int k = 0; k < gl_data.contours.size(); k++) { + p_size += glyphs[j].repeat * gl_data.contours[k].size() * 4; + i_size += glyphs[j].repeat * gl_data.contours[k].size() * 6; + } + } + + for (int r = 0; r < glyphs[j].repeat; r++) { + min_p.x = MIN(gl_data.min_p.x + offset.x, min_p.x); + min_p.y = MIN(gl_data.min_p.y - offset.y, min_p.y); + max_p.x = MAX(gl_data.max_p.x + offset.x, max_p.x); + max_p.y = MAX(gl_data.max_p.y - offset.y, max_p.y); - offset_pre.x += glyphs[i].advance * pixel_size * glyphs[i].repeat; + offset.x += glyphs[j].advance * pixel_size; + } + } else { + p_size += glyphs[j].repeat * 4; + i_size += glyphs[j].repeat * 6; + + offset.x += glyphs[j].advance * pixel_size * glyphs[j].repeat; + } } + offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing) * pixel_size; } - Vector<Vector3> vertices; - Vector<Vector3> normals; - Vector<float> tangents; - Vector<Vector2> uvs; - Vector<int32_t> indices; - vertices.resize(p_size); normals.resize(p_size); uvs.resize(p_size); @@ -2561,149 +2617,176 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { // Generate mesh. int32_t p_idx = 0; int32_t i_idx = 0; - for (int i = 0; i < gl_size; i++) { - if (glyphs[i].index == 0) { - offset.x += glyphs[i].advance * pixel_size * glyphs[i].repeat; - continue; + + offset = Vector2(0, vbegin + lbl_offset.y * pixel_size); + for (int i = 0; i < lines_rid.size(); i++) { + const Glyph *glyphs = TS->shaped_text_get_glyphs(lines_rid[i]); + int gl_size = TS->shaped_text_get_glyph_count(lines_rid[i]); + float line_width = TS->shaped_text_get_width(lines_rid[i]) * pixel_size; + + switch (horizontal_alignment) { + case HORIZONTAL_ALIGNMENT_LEFT: + offset.x = 0.0; + break; + case HORIZONTAL_ALIGNMENT_FILL: + case HORIZONTAL_ALIGNMENT_CENTER: { + offset.x = -line_width / 2.0; + } break; + case HORIZONTAL_ALIGNMENT_RIGHT: { + offset.x = -line_width; + } break; } - if (glyphs[i].font_rid != RID()) { - GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index); - _generate_glyph_mesh_data(key, glyphs[i]); - const GlyphMeshData &gl_data = cache[key]; - - int64_t ts = gl_data.triangles.size(); - const Vector2 *ts_ptr = gl_data.triangles.ptr(); - - for (int j = 0; j < glyphs[i].repeat; j++) { - for (int k = 0; k < ts; k += 3) { - // Add front face. - for (int l = 0; l < 3; l++) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, depth / 2.0); - vertices_ptr[p_idx] = point; - normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); - if (has_depth) { - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -min_p.y, -max_p.y, real_t(0.0), real_t(0.4))); - } else { - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -min_p.y, -max_p.y, real_t(0.0), real_t(1.0))); - } - tangents_ptr[p_idx * 4 + 0] = 1.0; - tangents_ptr[p_idx * 4 + 1] = 0.0; - tangents_ptr[p_idx * 4 + 2] = 0.0; - tangents_ptr[p_idx * 4 + 3] = 1.0; - indices_ptr[i_idx++] = p_idx; - p_idx++; - } - if (has_depth) { - // Add back face. - for (int l = 2; l >= 0; l--) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); + offset.x += lbl_offset.x * pixel_size; + offset.y -= TS->shaped_text_get_ascent(lines_rid[i]) * pixel_size; + + bool has_depth = !Math::is_zero_approx(depth); + + // Generate glyph data, precalculate size of the arrays and mesh bounds for UV. + for (int j = 0; j < gl_size; j++) { + if (glyphs[j].index == 0) { + offset.x += glyphs[j].advance * pixel_size * glyphs[j].repeat; + continue; + } + if (glyphs[j].font_rid != RID()) { + GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); + _generate_glyph_mesh_data(key, glyphs[j]); + const GlyphMeshData &gl_data = cache[key]; + + int64_t ts = gl_data.triangles.size(); + const Vector2 *ts_ptr = gl_data.triangles.ptr(); + + for (int r = 0; r < glyphs[j].repeat; r++) { + for (int k = 0; k < ts; k += 3) { + // Add front face. + for (int l = 0; l < 3; l++) { + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, depth / 2.0); vertices_ptr[p_idx] = point; - normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); - uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -min_p.y, -max_p.y, real_t(0.4), real_t(0.8))); - tangents_ptr[p_idx * 4 + 0] = -1.0; + normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); + if (has_depth) { + uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); + } else { + uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); + } + tangents_ptr[p_idx * 4 + 0] = 1.0; tangents_ptr[p_idx * 4 + 1] = 0.0; tangents_ptr[p_idx * 4 + 2] = 0.0; tangents_ptr[p_idx * 4 + 3] = 1.0; indices_ptr[i_idx++] = p_idx; p_idx++; } - } - } - // Add sides. - if (has_depth) { - for (int k = 0; k < gl_data.contours.size(); k++) { - int64_t ps = gl_data.contours[k].size(); - const ContourPoint *ps_ptr = gl_data.contours[k].ptr(); - const ContourInfo &ps_info = gl_data.contours_info[k]; - real_t length = 0.0; - for (int l = 0; l < ps; l++) { - int prev = (l == 0) ? (ps - 1) : (l - 1); - int next = (l + 1 == ps) ? 0 : (l + 1); - Vector2 d1; - Vector2 d2 = (ps_ptr[next].point - ps_ptr[l].point).normalized(); - if (ps_ptr[l].sharp) { - d1 = d2; - } else { - d1 = (ps_ptr[l].point - ps_ptr[prev].point).normalized(); + if (has_depth) { + // Add back face. + for (int l = 2; l >= 0; l--) { + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); + vertices_ptr[p_idx] = point; + normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); + uvs_ptr[p_idx] = Vector2(Math::range_lerp(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); + tangents_ptr[p_idx * 4 + 0] = -1.0; + tangents_ptr[p_idx * 4 + 1] = 0.0; + tangents_ptr[p_idx * 4 + 2] = 0.0; + tangents_ptr[p_idx * 4 + 3] = 1.0; + indices_ptr[i_idx++] = p_idx; + p_idx++; } - real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); - - Vector3 quad_faces[4] = { - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, depth / 2.0), - }; - for (int m = 0; m < 4; m++) { - const Vector2 &d = ((m % 2) == 0) ? d1 : d2; - real_t u_pos = ((m % 2) == 0) ? length : length + seg_len; - vertices_ptr[p_idx + m] = quad_faces[m]; - normals_ptr[p_idx + m] = Vector3(d.y, d.x, 0.0); - if (m < 2) { - uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.8 : 0.9); + } + } + // Add sides. + if (has_depth) { + for (int k = 0; k < gl_data.contours.size(); k++) { + int64_t ps = gl_data.contours[k].size(); + const ContourPoint *ps_ptr = gl_data.contours[k].ptr(); + const ContourInfo &ps_info = gl_data.contours_info[k]; + real_t length = 0.0; + for (int l = 0; l < ps; l++) { + int prev = (l == 0) ? (ps - 1) : (l - 1); + int next = (l + 1 == ps) ? 0 : (l + 1); + Vector2 d1; + Vector2 d2 = (ps_ptr[next].point - ps_ptr[l].point).normalized(); + if (ps_ptr[l].sharp) { + d1 = d2; } else { - uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.9 : 1.0); + d1 = (ps_ptr[l].point - ps_ptr[prev].point).normalized(); + } + real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); + + Vector3 quad_faces[4] = { + Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, -depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, -depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, depth / 2.0), + }; + for (int m = 0; m < 4; m++) { + const Vector2 &d = ((m % 2) == 0) ? d1 : d2; + real_t u_pos = ((m % 2) == 0) ? length : length + seg_len; + vertices_ptr[p_idx + m] = quad_faces[m]; + normals_ptr[p_idx + m] = Vector3(d.y, d.x, 0.0); + if (m < 2) { + uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.8 : 0.9); + } else { + uvs_ptr[p_idx + m] = Vector2(Math::range_lerp(u_pos, 0, ps_info.length, real_t(0.0), real_t(1.0)), (ps_info.ccw) ? 0.9 : 1.0); + } + tangents_ptr[(p_idx + m) * 4 + 0] = d.x; + tangents_ptr[(p_idx + m) * 4 + 1] = -d.y; + tangents_ptr[(p_idx + m) * 4 + 2] = 0.0; + tangents_ptr[(p_idx + m) * 4 + 3] = 1.0; } - tangents_ptr[(p_idx + m) * 4 + 0] = d.x; - tangents_ptr[(p_idx + m) * 4 + 1] = -d.y; - tangents_ptr[(p_idx + m) * 4 + 2] = 0.0; - tangents_ptr[(p_idx + m) * 4 + 3] = 1.0; - } - indices_ptr[i_idx++] = p_idx; - indices_ptr[i_idx++] = p_idx + 1; - indices_ptr[i_idx++] = p_idx + 2; + indices_ptr[i_idx++] = p_idx; + indices_ptr[i_idx++] = p_idx + 1; + indices_ptr[i_idx++] = p_idx + 2; - indices_ptr[i_idx++] = p_idx + 1; - indices_ptr[i_idx++] = p_idx + 3; - indices_ptr[i_idx++] = p_idx + 2; + indices_ptr[i_idx++] = p_idx + 1; + indices_ptr[i_idx++] = p_idx + 3; + indices_ptr[i_idx++] = p_idx + 2; - length += seg_len; - p_idx += 4; + length += seg_len; + p_idx += 4; + } } } + offset.x += glyphs[j].advance * pixel_size; } - offset.x += glyphs[i].advance * pixel_size; - } - } else { - // Add fallback quad for missing glyphs. - for (int j = 0; j < glyphs[i].repeat; j++) { - Size2 sz = TS->get_hex_code_box_size(glyphs[i].font_size, glyphs[i].index) * pixel_size; - Vector3 quad_faces[4] = { - Vector3(offset.x, offset.y, 0.0), - Vector3(offset.x, sz.y + offset.y, 0.0), - Vector3(sz.x + offset.x, sz.y + offset.y, 0.0), - Vector3(sz.x + offset.x, offset.y, 0.0), - }; - for (int k = 0; k < 4; k++) { - vertices_ptr[p_idx + k] = quad_faces[k]; - normals_ptr[p_idx + k] = Vector3(0.0, 0.0, 1.0); - if (has_depth) { - uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -min_p.y, -max_p.y, real_t(0.0), real_t(0.4))); - } else { - uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -min_p.y, -max_p.y, real_t(0.0), real_t(1.0))); + } else { + // Add fallback quad for missing glyphs. + for (int r = 0; r < glyphs[j].repeat; r++) { + Size2 sz = TS->get_hex_code_box_size(glyphs[j].font_size, glyphs[j].index) * pixel_size; + Vector3 quad_faces[4] = { + Vector3(offset.x, offset.y, 0.0), + Vector3(offset.x, sz.y + offset.y, 0.0), + Vector3(sz.x + offset.x, sz.y + offset.y, 0.0), + Vector3(sz.x + offset.x, offset.y, 0.0), + }; + for (int k = 0; k < 4; k++) { + vertices_ptr[p_idx + k] = quad_faces[k]; + normals_ptr[p_idx + k] = Vector3(0.0, 0.0, 1.0); + if (has_depth) { + uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -max_p.y, -min_p.y, real_t(0.4), real_t(0.0))); + } else { + uvs_ptr[p_idx + k] = Vector2(Math::range_lerp(quad_faces[k].x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::range_lerp(quad_faces[k].y, -max_p.y, -min_p.y, real_t(1.0), real_t(0.0))); + } + tangents_ptr[(p_idx + k) * 4 + 0] = 1.0; + tangents_ptr[(p_idx + k) * 4 + 1] = 0.0; + tangents_ptr[(p_idx + k) * 4 + 2] = 0.0; + tangents_ptr[(p_idx + k) * 4 + 3] = 1.0; } - tangents_ptr[(p_idx + k) * 4 + 0] = 1.0; - tangents_ptr[(p_idx + k) * 4 + 1] = 0.0; - tangents_ptr[(p_idx + k) * 4 + 2] = 0.0; - tangents_ptr[(p_idx + k) * 4 + 3] = 1.0; - } - indices_ptr[i_idx++] = p_idx; - indices_ptr[i_idx++] = p_idx + 1; - indices_ptr[i_idx++] = p_idx + 2; + indices_ptr[i_idx++] = p_idx; + indices_ptr[i_idx++] = p_idx + 1; + indices_ptr[i_idx++] = p_idx + 2; - indices_ptr[i_idx++] = p_idx + 0; - indices_ptr[i_idx++] = p_idx + 2; - indices_ptr[i_idx++] = p_idx + 3; - p_idx += 4; + indices_ptr[i_idx++] = p_idx + 0; + indices_ptr[i_idx++] = p_idx + 2; + indices_ptr[i_idx++] = p_idx + 3; + p_idx += 4; - offset.x += glyphs[i].advance * pixel_size; + offset.x += glyphs[j].advance * pixel_size; + } } } + offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing) * pixel_size; } - if (p_size == 0) { + if (indices.is_empty()) { // If empty, add single triangle to suppress errors. vertices.push_back(Vector3()); normals.push_back(Vector3()); @@ -2728,6 +2811,9 @@ void TextMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &TextMesh::set_horizontal_alignment); ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &TextMesh::get_horizontal_alignment); + ClassDB::bind_method(D_METHOD("set_vertical_alignment", "alignment"), &TextMesh::set_vertical_alignment); + ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &TextMesh::get_vertical_alignment); + ClassDB::bind_method(D_METHOD("set_text", "text"), &TextMesh::set_text); ClassDB::bind_method(D_METHOD("get_text"), &TextMesh::get_text); @@ -2737,6 +2823,12 @@ void TextMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_font_size", "font_size"), &TextMesh::set_font_size); ClassDB::bind_method(D_METHOD("get_font_size"), &TextMesh::get_font_size); + ClassDB::bind_method(D_METHOD("set_line_spacing", "line_spacing"), &TextMesh::set_line_spacing); + ClassDB::bind_method(D_METHOD("get_line_spacing"), &TextMesh::get_line_spacing); + + ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &TextMesh::set_autowrap_mode); + ClassDB::bind_method(D_METHOD("get_autowrap_mode"), &TextMesh::get_autowrap_mode); + ClassDB::bind_method(D_METHOD("set_depth", "depth"), &TextMesh::set_depth); ClassDB::bind_method(D_METHOD("get_depth"), &TextMesh::get_depth); @@ -2746,6 +2838,9 @@ void TextMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &TextMesh::set_pixel_size); ClassDB::bind_method(D_METHOD("get_pixel_size"), &TextMesh::get_pixel_size); + ClassDB::bind_method(D_METHOD("set_offset", "offset"), &TextMesh::set_offset); + ClassDB::bind_method(D_METHOD("get_offset"), &TextMesh::get_offset); + ClassDB::bind_method(D_METHOD("set_curve_step", "curve_step"), &TextMesh::set_curve_step); ClassDB::bind_method(D_METHOD("get_curve_step"), &TextMesh::get_curve_step); @@ -2768,17 +2863,21 @@ void TextMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("_request_update"), &TextMesh::_request_update); ADD_GROUP("Text", ""); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, ""), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font"); ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom"), "set_vertical_alignment", "get_vertical_alignment"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uppercase"), "set_uppercase", "is_uppercase"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); ADD_GROUP("Mesh", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001,suffix:m"), "set_pixel_size", "get_pixel_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "curve_step", PROPERTY_HINT_RANGE, "0.1,10,0.1,suffix:px"), "set_curve_step", "get_curve_step"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.0,100.0,0.001,or_greater,suffix:m"), "set_depth", "get_depth"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:m"), "set_width", "get_width"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "set_text_direction", "get_text_direction"); @@ -2807,6 +2906,11 @@ TextMesh::TextMesh() { } TextMesh::~TextMesh() { + for (int i = 0; i < lines_rid.size(); i++) { + TS->free_rid(lines_rid[i]); + } + lines_rid.clear(); + TS->free_rid(text_rid); } @@ -2814,7 +2918,7 @@ void TextMesh::set_horizontal_alignment(HorizontalAlignment p_alignment) { ERR_FAIL_INDEX((int)p_alignment, 4); if (horizontal_alignment != p_alignment) { if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL || p_alignment == HORIZONTAL_ALIGNMENT_FILL) { - dirty_text = true; + dirty_lines = true; } horizontal_alignment = p_alignment; _request_update(); @@ -2825,6 +2929,18 @@ HorizontalAlignment TextMesh::get_horizontal_alignment() const { return horizontal_alignment; } +void TextMesh::set_vertical_alignment(VerticalAlignment p_alignment) { + ERR_FAIL_INDEX((int)p_alignment, 4); + if (vertical_alignment != p_alignment) { + vertical_alignment = p_alignment; + _request_update(); + } +} + +VerticalAlignment TextMesh::get_vertical_alignment() const { + return vertical_alignment; +} + void TextMesh::set_text(const String &p_string) { if (text != p_string) { text = p_string; @@ -2869,13 +2985,13 @@ Ref<Font> TextMesh::_get_font_or_default() const { } // Check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { + if (ThemeDB::get_singleton()->get_project_theme().is_valid()) { List<StringName> theme_types; - Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_project_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - return Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_project_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + return ThemeDB::get_singleton()->get_project_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); } } } @@ -2883,17 +2999,17 @@ Ref<Font> TextMesh::_get_font_or_default() const { // Lastly, fall back on the items defined in the default Theme, if they exist. { List<StringName> theme_types; - Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + ThemeDB::get_singleton()->get_default_theme()->get_type_dependencies(get_class_name(), StringName(), &theme_types); for (const StringName &E : theme_types) { - if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { - return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (ThemeDB::get_singleton()->get_default_theme()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); } } } // If they don't exist, use any type to return the default/empty value. - return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + return ThemeDB::get_singleton()->get_default_theme()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); } void TextMesh::set_font_size(int p_size) { @@ -2909,6 +3025,29 @@ int TextMesh::get_font_size() const { return font_size; } +void TextMesh::set_line_spacing(float p_line_spacing) { + if (line_spacing != p_line_spacing) { + line_spacing = p_line_spacing; + _request_update(); + } +} + +float TextMesh::get_line_spacing() const { + return line_spacing; +} + +void TextMesh::set_autowrap_mode(TextServer::AutowrapMode p_mode) { + if (autowrap_mode != p_mode) { + autowrap_mode = p_mode; + dirty_lines = true; + _request_update(); + } +} + +TextServer::AutowrapMode TextMesh::get_autowrap_mode() const { + return autowrap_mode; +} + void TextMesh::set_depth(real_t p_depth) { if (depth != p_depth) { depth = MAX(p_depth, 0.0); @@ -2923,9 +3062,7 @@ real_t TextMesh::get_depth() const { void TextMesh::set_width(real_t p_width) { if (width != p_width) { width = p_width; - if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - dirty_text = true; - } + dirty_lines = true; _request_update(); } } @@ -2946,6 +3083,17 @@ real_t TextMesh::get_pixel_size() const { return pixel_size; } +void TextMesh::set_offset(const Point2 &p_offset) { + if (lbl_offset != p_offset) { + lbl_offset = p_offset; + _request_update(); + } +} + +Point2 TextMesh::get_offset() const { + return lbl_offset; +} + void TextMesh::set_curve_step(real_t p_step) { if (curve_step != p_step) { curve_step = CLAMP(p_step, 0.1, 10.0); diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 3cf161db00..280477ebfa 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -534,14 +534,21 @@ private: mutable HashMap<GlyphMeshKey, GlyphMeshData, GlyphMeshKeyHasher> cache; RID text_rid; + mutable Vector<RID> lines_rid; + String text; String xl_text; int font_size = 16; Ref<Font> font_override; + + TextServer::AutowrapMode autowrap_mode = TextServer::AUTOWRAP_OFF; float width = 500.0; + float line_spacing = 0.f; + Point2 lbl_offset; HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER; + VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER; bool uppercase = false; String language; TextServer::Direction text_direction = TextServer::DIRECTION_AUTO; @@ -552,6 +559,7 @@ private: real_t pixel_size = 0.01; real_t curve_step = 0.5; + mutable bool dirty_lines = true; mutable bool dirty_text = true; mutable bool dirty_font = true; mutable bool dirty_cache = true; @@ -574,6 +582,9 @@ public: void set_horizontal_alignment(HorizontalAlignment p_alignment); HorizontalAlignment get_horizontal_alignment() const; + void set_vertical_alignment(VerticalAlignment p_alignment); + VerticalAlignment get_vertical_alignment() const; + void set_text(const String &p_string); String get_text() const; @@ -584,6 +595,12 @@ public: void set_font_size(int p_size); int get_font_size() const; + void set_line_spacing(float p_size); + float get_line_spacing() const; + + void set_autowrap_mode(TextServer::AutowrapMode p_mode); + TextServer::AutowrapMode get_autowrap_mode() const; + void set_text_direction(TextServer::Direction p_text_direction); TextServer::Direction get_text_direction() const; @@ -610,6 +627,9 @@ public: void set_pixel_size(real_t p_amount); real_t get_pixel_size() const; + + void set_offset(const Point2 &p_offset); + Point2 get_offset() const; }; VARIANT_ENUM_CAST(RibbonTrailMesh::Shape) diff --git a/scene/resources/skeleton_modification_2d_ccdik.cpp b/scene/resources/skeleton_modification_2d_ccdik.cpp index 7adaf1452c..96961a1fe4 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.cpp +++ b/scene/resources/skeleton_modification_2d_ccdik.cpp @@ -52,9 +52,9 @@ bool SkeletonModification2DCCDIK::_set(const StringName &p_path, const Variant & } else if (what == "enable_constraint") { set_ccdik_joint_enable_constraint(which, p_value); } else if (what == "constraint_angle_min") { - set_ccdik_joint_constraint_angle_min(which, Math::deg2rad(float(p_value))); + set_ccdik_joint_constraint_angle_min(which, Math::deg_to_rad(float(p_value))); } else if (what == "constraint_angle_max") { - set_ccdik_joint_constraint_angle_max(which, Math::deg2rad(float(p_value))); + set_ccdik_joint_constraint_angle_max(which, Math::deg_to_rad(float(p_value))); } else if (what == "constraint_angle_invert") { set_ccdik_joint_constraint_angle_invert(which, p_value); } else if (what == "constraint_in_localspace") { @@ -96,9 +96,9 @@ bool SkeletonModification2DCCDIK::_get(const StringName &p_path, Variant &r_ret) } else if (what == "enable_constraint") { r_ret = get_ccdik_joint_enable_constraint(which); } else if (what == "constraint_angle_min") { - r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_min(which)); + r_ret = Math::rad_to_deg(get_ccdik_joint_constraint_angle_min(which)); } else if (what == "constraint_angle_max") { - r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_max(which)); + r_ret = Math::rad_to_deg(get_ccdik_joint_constraint_angle_max(which)); } else if (what == "constraint_angle_invert") { r_ret = get_ccdik_joint_constraint_angle_invert(which); } else if (what == "constraint_in_localspace") { diff --git a/scene/resources/skeleton_modification_2d_lookat.cpp b/scene/resources/skeleton_modification_2d_lookat.cpp index 23e1c579dc..d3cfffb1de 100644 --- a/scene/resources/skeleton_modification_2d_lookat.cpp +++ b/scene/resources/skeleton_modification_2d_lookat.cpp @@ -41,15 +41,15 @@ bool SkeletonModification2DLookAt::_set(const StringName &p_path, const Variant if (path.begins_with("enable_constraint")) { set_enable_constraint(p_value); } else if (path.begins_with("constraint_angle_min")) { - set_constraint_angle_min(Math::deg2rad(float(p_value))); + set_constraint_angle_min(Math::deg_to_rad(float(p_value))); } else if (path.begins_with("constraint_angle_max")) { - set_constraint_angle_max(Math::deg2rad(float(p_value))); + set_constraint_angle_max(Math::deg_to_rad(float(p_value))); } else if (path.begins_with("constraint_angle_invert")) { set_constraint_angle_invert(p_value); } else if (path.begins_with("constraint_in_localspace")) { set_constraint_in_localspace(p_value); } else if (path.begins_with("additional_rotation")) { - set_additional_rotation(Math::deg2rad(float(p_value))); + set_additional_rotation(Math::deg_to_rad(float(p_value))); } #ifdef TOOLS_ENABLED @@ -67,15 +67,15 @@ bool SkeletonModification2DLookAt::_get(const StringName &p_path, Variant &r_ret if (path.begins_with("enable_constraint")) { r_ret = get_enable_constraint(); } else if (path.begins_with("constraint_angle_min")) { - r_ret = Math::rad2deg(get_constraint_angle_min()); + r_ret = Math::rad_to_deg(get_constraint_angle_min()); } else if (path.begins_with("constraint_angle_max")) { - r_ret = Math::rad2deg(get_constraint_angle_max()); + r_ret = Math::rad_to_deg(get_constraint_angle_max()); } else if (path.begins_with("constraint_angle_invert")) { r_ret = get_constraint_angle_invert(); } else if (path.begins_with("constraint_in_localspace")) { r_ret = get_constraint_in_localspace(); } else if (path.begins_with("additional_rotation")) { - r_ret = Math::rad2deg(get_additional_rotation()); + r_ret = Math::rad_to_deg(get_additional_rotation()); } #ifdef TOOLS_ENABLED diff --git a/scene/resources/skeleton_modification_3d_ccdik.cpp b/scene/resources/skeleton_modification_3d_ccdik.cpp index f19be47db2..3251ee4189 100644 --- a/scene/resources/skeleton_modification_3d_ccdik.cpp +++ b/scene/resources/skeleton_modification_3d_ccdik.cpp @@ -50,9 +50,9 @@ bool SkeletonModification3DCCDIK::_set(const StringName &p_path, const Variant & } else if (what == "enable_joint_constraint") { set_ccdik_joint_enable_constraint(which, p_value); } else if (what == "joint_constraint_angle_min") { - set_ccdik_joint_constraint_angle_min(which, Math::deg2rad(real_t(p_value))); + set_ccdik_joint_constraint_angle_min(which, Math::deg_to_rad(real_t(p_value))); } else if (what == "joint_constraint_angle_max") { - set_ccdik_joint_constraint_angle_max(which, Math::deg2rad(real_t(p_value))); + set_ccdik_joint_constraint_angle_max(which, Math::deg_to_rad(real_t(p_value))); } else if (what == "joint_constraint_angles_invert") { set_ccdik_joint_constraint_invert(which, p_value); } @@ -79,9 +79,9 @@ bool SkeletonModification3DCCDIK::_get(const StringName &p_path, Variant &r_ret) } else if (what == "enable_joint_constraint") { r_ret = get_ccdik_joint_enable_constraint(which); } else if (what == "joint_constraint_angle_min") { - r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_min(which)); + r_ret = Math::rad_to_deg(get_ccdik_joint_constraint_angle_min(which)); } else if (what == "joint_constraint_angle_max") { - r_ret = Math::rad2deg(get_ccdik_joint_constraint_angle_max(which)); + r_ret = Math::rad_to_deg(get_ccdik_joint_constraint_angle_max(which)); } else if (what == "joint_constraint_angles_invert") { r_ret = get_ccdik_joint_constraint_invert(which); } diff --git a/scene/resources/skeleton_modification_3d_fabrik.cpp b/scene/resources/skeleton_modification_3d_fabrik.cpp index b62dda3f4f..4099208f44 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.cpp +++ b/scene/resources/skeleton_modification_3d_fabrik.cpp @@ -58,7 +58,7 @@ bool SkeletonModification3DFABRIK::_set(const StringName &p_path, const Variant } else if (what == "use_target_basis") { set_fabrik_joint_use_target_basis(which, p_value); } else if (what == "roll") { - set_fabrik_joint_roll(which, Math::deg2rad(real_t(p_value))); + set_fabrik_joint_roll(which, Math::deg_to_rad(real_t(p_value))); } return true; } @@ -91,7 +91,7 @@ bool SkeletonModification3DFABRIK::_get(const StringName &p_path, Variant &r_ret } else if (what == "use_target_basis") { r_ret = get_fabrik_joint_use_target_basis(which); } else if (what == "roll") { - r_ret = Math::rad2deg(get_fabrik_joint_roll(which)); + r_ret = Math::rad_to_deg(get_fabrik_joint_roll(which)); } return true; } diff --git a/scene/resources/skeleton_modification_3d_jiggle.cpp b/scene/resources/skeleton_modification_3d_jiggle.cpp index 3e36c241f7..64f26f3fda 100644 --- a/scene/resources/skeleton_modification_3d_jiggle.cpp +++ b/scene/resources/skeleton_modification_3d_jiggle.cpp @@ -58,7 +58,7 @@ bool SkeletonModification3DJiggle::_set(const StringName &p_path, const Variant } else if (what == "gravity") { set_jiggle_joint_gravity(which, p_value); } else if (what == "roll") { - set_jiggle_joint_roll(which, Math::deg2rad(real_t(p_value))); + set_jiggle_joint_roll(which, Math::deg_to_rad(real_t(p_value))); } return true; } else { @@ -98,7 +98,7 @@ bool SkeletonModification3DJiggle::_get(const StringName &p_path, Variant &r_ret } else if (what == "gravity") { r_ret = get_jiggle_joint_gravity(which); } else if (what == "roll") { - r_ret = Math::rad2deg(get_jiggle_joint_roll(which)); + r_ret = Math::rad_to_deg(get_jiggle_joint_roll(which)); } return true; } else { diff --git a/scene/resources/skeleton_modification_3d_lookat.cpp b/scene/resources/skeleton_modification_3d_lookat.cpp index 3e8c1e3a77..69167cb308 100644 --- a/scene/resources/skeleton_modification_3d_lookat.cpp +++ b/scene/resources/skeleton_modification_3d_lookat.cpp @@ -39,9 +39,9 @@ bool SkeletonModification3DLookAt::_set(const StringName &p_path, const Variant set_lock_rotation_plane(p_value); } else if (p_path == "additional_rotation") { Vector3 tmp = p_value; - tmp.x = Math::deg2rad(tmp.x); - tmp.y = Math::deg2rad(tmp.y); - tmp.z = Math::deg2rad(tmp.z); + tmp.x = Math::deg_to_rad(tmp.x); + tmp.y = Math::deg_to_rad(tmp.y); + tmp.z = Math::deg_to_rad(tmp.z); set_additional_rotation(tmp); } @@ -55,9 +55,9 @@ bool SkeletonModification3DLookAt::_get(const StringName &p_path, Variant &r_ret r_ret = get_lock_rotation_plane(); } else if (p_path == "additional_rotation") { Vector3 tmp = get_additional_rotation(); - tmp.x = Math::rad2deg(tmp.x); - tmp.y = Math::rad2deg(tmp.y); - tmp.z = Math::rad2deg(tmp.z); + tmp.x = Math::rad_to_deg(tmp.x); + tmp.y = Math::rad_to_deg(tmp.y); + tmp.z = Math::rad_to_deg(tmp.z); r_ret = tmp; } diff --git a/scene/resources/skeleton_modification_3d_twoboneik.cpp b/scene/resources/skeleton_modification_3d_twoboneik.cpp index acc5ff716c..366fcc30b7 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.cpp +++ b/scene/resources/skeleton_modification_3d_twoboneik.cpp @@ -54,13 +54,13 @@ bool SkeletonModification3DTwoBoneIK::_set(const StringName &p_path, const Varia } else if (path == "joint_one/bone_idx") { set_joint_one_bone_idx(p_value); } else if (path == "joint_one/roll") { - set_joint_one_roll(Math::deg2rad(real_t(p_value))); + set_joint_one_roll(Math::deg_to_rad(real_t(p_value))); } else if (path == "joint_two/bone_name") { set_joint_two_bone_name(p_value); } else if (path == "joint_two/bone_idx") { set_joint_two_bone_idx(p_value); } else if (path == "joint_two/roll") { - set_joint_two_roll(Math::deg2rad(real_t(p_value))); + set_joint_two_roll(Math::deg_to_rad(real_t(p_value))); } return true; @@ -88,13 +88,13 @@ bool SkeletonModification3DTwoBoneIK::_get(const StringName &p_path, Variant &r_ } else if (path == "joint_one/bone_idx") { r_ret = get_joint_one_bone_idx(); } else if (path == "joint_one/roll") { - r_ret = Math::rad2deg(get_joint_one_roll()); + r_ret = Math::rad_to_deg(get_joint_one_roll()); } else if (path == "joint_two/bone_name") { r_ret = get_joint_two_bone_name(); } else if (path == "joint_two/bone_idx") { r_ret = get_joint_two_bone_idx(); } else if (path == "joint_two/roll") { - r_ret = Math::rad2deg(get_joint_two_roll()); + r_ret = Math::rad_to_deg(get_joint_two_roll()); } return true; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 5d1a223cc7..737c50e570 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -128,7 +128,7 @@ float ProceduralSkyMaterial::get_ground_energy() const { void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) { sun_angle_max = p_angle; - RS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg2rad(sun_angle_max)); + RS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg_to_rad(sun_angle_max)); } float ProceduralSkyMaterial::get_sun_angle_max() const { diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index 92efe3ce6f..340d0fe370 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -38,8 +38,8 @@ Vector<Vector3> SphereShape3D::get_debug_mesh_lines() const { Vector<Vector3> points; for (int i = 0; i <= 360; i++) { - float ra = Math::deg2rad((float)i); - float rb = Math::deg2rad((float)i + 1); + float ra = Math::deg_to_rad((float)i); + float rb = Math::deg_to_rad((float)i + 1); Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 3f6eec8497..3321392821 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -31,17 +31,7 @@ #include "theme.h" #include "core/string/print_string.h" - -// Universal Theme resources used when no other theme has the item. -Ref<Theme> Theme::default_theme; -Ref<Theme> Theme::project_default_theme; - -// Universal default values, final fallback for every theme. -float Theme::fallback_base_scale = 1.0; -Ref<Texture2D> Theme::fallback_icon; -Ref<StyleBox> Theme::fallback_style; -Ref<Font> Theme::fallback_font; -int Theme::fallback_font_size = 16; +#include "scene/theme/theme_db.h" // Dynamic properties. bool Theme::_set(const StringName &p_name, const Variant &p_value) { @@ -185,64 +175,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const { } } -// Universal fallback Theme resources. -Ref<Theme> Theme::get_default() { - return default_theme; -} - -void Theme::set_default(const Ref<Theme> &p_default) { - default_theme = p_default; -} - -Ref<Theme> Theme::get_project_default() { - return project_default_theme; -} - -void Theme::set_project_default(const Ref<Theme> &p_project_default) { - project_default_theme = p_project_default; -} - -// Universal fallback values for theme item types. -void Theme::set_fallback_base_scale(float p_base_scale) { - fallback_base_scale = p_base_scale; -} - -void Theme::set_fallback_icon(const Ref<Texture2D> &p_icon) { - fallback_icon = p_icon; -} - -void Theme::set_fallback_style(const Ref<StyleBox> &p_style) { - fallback_style = p_style; -} - -void Theme::set_fallback_font(const Ref<Font> &p_font) { - fallback_font = p_font; -} - -void Theme::set_fallback_font_size(int p_font_size) { - fallback_font_size = p_font_size; -} - -float Theme::get_fallback_base_scale() { - return fallback_base_scale; -} - -Ref<Texture2D> Theme::get_fallback_icon() { - return fallback_icon; -} - -Ref<StyleBox> Theme::get_fallback_style() { - return fallback_style; -} - -Ref<Font> Theme::get_fallback_font() { - return fallback_font; -} - -int Theme::get_fallback_font_size() { - return fallback_font_size; -} - +// Static helpers. bool Theme::is_valid_type_name(const String &p_name) { for (int i = 0; i < p_name.length(); i++) { if (!is_ascii_identifier_char(p_name[i])) { @@ -351,7 +284,7 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_the if (icon_map.has(p_theme_type) && icon_map[p_theme_type].has(p_name) && icon_map[p_theme_type][p_name].is_valid()) { return icon_map[p_theme_type][p_name]; } else { - return fallback_icon; + return ThemeDB::get_singleton()->get_fallback_icon(); } } @@ -461,7 +394,7 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_ if (style_map.has(p_theme_type) && style_map[p_theme_type].has(p_name) && style_map[p_theme_type][p_name].is_valid()) { return style_map[p_theme_type][p_name]; } else { - return fallback_style; + return ThemeDB::get_singleton()->get_fallback_stylebox(); } } @@ -573,7 +506,7 @@ Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_theme_ty } else if (has_default_font()) { return default_font; } else { - return fallback_font; + return ThemeDB::get_singleton()->get_fallback_font(); } } @@ -676,7 +609,7 @@ int Theme::get_font_size(const StringName &p_name, const StringName &p_theme_typ } else if (has_default_font_size()) { return default_font_size; } else { - return fallback_font_size; + return ThemeDB::get_singleton()->get_fallback_font_size(); } } diff --git a/scene/resources/theme.h b/scene/resources/theme.h index a2aca5e61f..ed1dc7c938 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -102,17 +102,6 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - // Universal Theme resources used when no other theme has the item. - static Ref<Theme> default_theme; - static Ref<Theme> project_default_theme; - - // Universal default values, final fallback for every theme. - static float fallback_base_scale; - static Ref<Texture2D> fallback_icon; - static Ref<StyleBox> fallback_style; - static Ref<Font> fallback_font; - static int fallback_font_size; - // Default values configurable for each individual theme. float default_base_scale = 0.0; Ref<Font> default_font; @@ -126,24 +115,6 @@ protected: virtual void reset_state() override; public: - static Ref<Theme> get_default(); - static void set_default(const Ref<Theme> &p_default); - - static Ref<Theme> get_project_default(); - static void set_project_default(const Ref<Theme> &p_project_default); - - static void set_fallback_base_scale(float p_base_scale); - static void set_fallback_icon(const Ref<Texture2D> &p_icon); - static void set_fallback_style(const Ref<StyleBox> &p_style); - static void set_fallback_font(const Ref<Font> &p_font); - static void set_fallback_font_size(int p_font_size); - - static float get_fallback_base_scale(); - static Ref<Texture2D> get_fallback_icon(); - static Ref<StyleBox> get_fallback_style(); - static Ref<Font> get_fallback_font(); - static int get_fallback_font_size(); - static bool is_valid_type_name(const String &p_name); static bool is_valid_item_name(const String &p_name); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2911d726b4..3b2b58516d 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1606,6 +1606,51 @@ VisualShaderNodeCubemap::VisualShaderNodeCubemap() { simple_decl = false; } +////////////// Linear Depth + +String VisualShaderNodeLinearSceneDepth::get_caption() const { + return "LinearSceneDepth"; +} + +int VisualShaderNodeLinearSceneDepth::get_input_port_count() const { + return 0; +} + +VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeLinearSceneDepth::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeLinearSceneDepth::get_output_port_count() const { + return 1; +} + +VisualShaderNodeLinearSceneDepth::PortType VisualShaderNodeLinearSceneDepth::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeLinearSceneDepth::get_output_port_name(int p_port) const { + return "linear depth"; +} + +String VisualShaderNodeLinearSceneDepth::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; + + code += " float _log_depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;\n"; + code += " vec3 _depth_ndc = vec3(SCREEN_UV * 2.0 - 1.0, _log_depth);\n"; + code += " vec4 _depth_view = INV_PROJECTION_MATRIX * vec4(_depth_ndc, 1.0);\n"; + code += " _depth_view.xyz /= _depth_view.w;"; + code += vformat(" %s = -_depth_view.z;", p_output_vars[0]); + + return code; +} + +VisualShaderNodeLinearSceneDepth::VisualShaderNodeLinearSceneDepth() { +} + ////////////// Float Op String VisualShaderNodeFloatOp::get_caption() const { @@ -3090,6 +3135,107 @@ VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() { set_input_port_default_value(2, Vector2()); // offset } +////////////// UV PolarCoord + +String VisualShaderNodeUVPolarCoord::get_caption() const { + return "UVPolarCoord"; +} + +int VisualShaderNodeUVPolarCoord::get_input_port_count() const { + return 4; +} + +VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR_2D; // uv + case 1: + return PORT_TYPE_VECTOR_2D; // center + case 2: + return PORT_TYPE_SCALAR; // zoom + case 3: + return PORT_TYPE_SCALAR; // repeat + default: + break; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeUVPolarCoord::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "uv"; + case 1: + return "scale"; + case 2: + return "zoom strength"; + case 3: + return "repeat"; + default: + break; + } + return ""; +} + +bool VisualShaderNodeUVPolarCoord::is_input_port_default(int p_port, Shader::Mode p_mode) const { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + if (p_port == 0) { + return true; + } + } + return false; +} + +int VisualShaderNodeUVPolarCoord::get_output_port_count() const { + return 1; +} + +VisualShaderNodeUVPolarCoord::PortType VisualShaderNodeUVPolarCoord::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR_2D; +} + +String VisualShaderNodeUVPolarCoord::get_output_port_name(int p_port) const { + return "uv"; +} + +String VisualShaderNodeUVPolarCoord::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 uv; + if (p_input_vars[0].is_empty()) { + if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) { + uv = "UV"; + } else { + uv = "vec2(0.0)"; + } + } else { + uv = vformat("%s", p_input_vars[0]); + } + String center = vformat("%s", p_input_vars[1]); + String zoom = vformat("%s", p_input_vars[2]); + String repeat = vformat("%s", p_input_vars[3]); + + if (p_mode == Shader::MODE_CANVAS_ITEM) { + code += vformat(" vec2 __dir = %s - %s;\n", uv, center); + code += " float __radius = length(__dir) * 2.0;\n"; + code += " float __angle = atan(__dir.y, __dir.x) * 1.0/(PI * 2.0);\n"; + code += vformat(" %s = mod(vec2(__radius * %s, __angle * %s), 1.0);\n", p_output_vars[0], zoom, repeat); + } else { + code += vformat(" vec2 __dir = %s - %s;\n", uv, center); + code += " float __radius = length(__dir) * 2.0;\n"; + code += " float __angle = atan(__dir.y, __dir.x) * 1.0/(PI * 2.0);\n"; + code += vformat(" %s = vec2(__radius * %s, __angle * %s);\n", p_output_vars[0], zoom, repeat); + } + + return code; +} + +VisualShaderNodeUVPolarCoord::VisualShaderNodeUVPolarCoord() { + set_input_port_default_value(1, Vector2(0.5, 0.5)); // center + set_input_port_default_value(2, 1.0); // zoom + set_input_port_default_value(3, 1.0); // repeat +} + ////////////// Dot Product String VisualShaderNodeDotProduct::get_caption() const { @@ -7010,3 +7156,261 @@ void VisualShaderNodeBillboard::_bind_methods() { VisualShaderNodeBillboard::VisualShaderNodeBillboard() { simple_decl = false; } + +////////////// DistanceFade + +String VisualShaderNodeDistanceFade::get_caption() const { + return "DistanceFade"; +} + +int VisualShaderNodeDistanceFade::get_input_port_count() const { + return 2; +} + +VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_SCALAR; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeDistanceFade::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "min"; + case 1: + return "max"; + } + + return ""; +} + +int VisualShaderNodeDistanceFade::get_output_port_count() const { + return 1; +} + +VisualShaderNodeDistanceFade::PortType VisualShaderNodeDistanceFade::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeDistanceFade::get_output_port_name(int p_port) const { + return "amount"; +} + +String VisualShaderNodeDistanceFade::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; + code += vformat(" %s = clamp(smoothstep(%s, %s,-VERTEX.z),0.0,1.0);\n", p_output_vars[0], p_input_vars[0], p_input_vars[1]); + return code; +} + +VisualShaderNodeDistanceFade::VisualShaderNodeDistanceFade() { + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 10.0); +} + +////////////// ProximityFade + +String VisualShaderNodeProximityFade::get_caption() const { + return "ProximityFade"; +} + +int VisualShaderNodeProximityFade::get_input_port_count() const { + return 1; +} + +VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeProximityFade::get_input_port_name(int p_port) const { + return "distance"; +} + +int VisualShaderNodeProximityFade::get_output_port_count() const { + return 1; +} + +VisualShaderNodeProximityFade::PortType VisualShaderNodeProximityFade::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeProximityFade::get_output_port_name(int p_port) const { + return "fade"; +} + +String VisualShaderNodeProximityFade::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 proximity_fade_distance = vformat("%s", p_input_vars[0]); + code += " float __depth_tex = textureLod(DEPTH_TEXTURE, SCREEN_UV, 0.0).r;\n"; + code += " vec4 __depth_world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, __depth_tex, 1.0);\n"; + code += " __depth_world_pos.xyz /= __depth_world_pos.z;\n"; + code += vformat(" %s = clamp(1.0 - smoothstep(__depth_world_pos.z + %s, __depth_world_pos.z, VERTEX.z), 0.0, 1.0);\n", p_output_vars[0], p_input_vars[0]); + + return code; +} + +VisualShaderNodeProximityFade::VisualShaderNodeProximityFade() { + set_input_port_default_value(0, 1.0); +} + +////////////// Random Range + +String VisualShaderNodeRandomRange::get_caption() const { + return "RandomRange"; +} + +int VisualShaderNodeRandomRange::get_input_port_count() const { + return 3; +} + +VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR_3D; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SCALAR; + default: + break; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRandomRange::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "seed"; + case 1: + return "min"; + case 2: + return "max"; + default: + break; + } + + return ""; +} + +int VisualShaderNodeRandomRange::get_output_port_count() const { + return 1; +} + +VisualShaderNodeRandomRange::PortType VisualShaderNodeRandomRange::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRandomRange::get_output_port_name(int p_port) const { + return "value"; +} + +String VisualShaderNodeRandomRange::generate_global_per_node(Shader::Mode p_mode, int p_id) const { + String code; + + code += "\n\n"; + code += "// 3D Noise with friendly permission by Inigo Quilez\n"; + code += "vec3 hash_noise_range( vec3 p ) {\n"; + code += " p *= mat3(vec3(127.1, 311.7, -53.7), vec3(269.5, 183.3, 77.1), vec3(-301.7, 27.3, 215.3));\n"; + code += " return 2.0 * fract(fract(p)*4375.55) -1.;\n"; + code += "}\n"; + code += "\n"; + + return code; +} + +String VisualShaderNodeRandomRange::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; + + code += vformat(" %s = mix(%s, %s, hash_noise_range(%s).x);\n", p_output_vars[0], p_input_vars[1], p_input_vars[2], p_input_vars[0]); + + return code; +} + +VisualShaderNodeRandomRange::VisualShaderNodeRandomRange() { + set_input_port_default_value(0, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); +} + +////////////// Remap + +String VisualShaderNodeRemap::get_caption() const { + return "Remap"; +} + +int VisualShaderNodeRemap::get_input_port_count() const { + return 5; +} + +VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_input_port_type(int p_port) const { + switch (p_port) { + case 0: + return PORT_TYPE_SCALAR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SCALAR; + case 3: + return PORT_TYPE_SCALAR; + case 4: + return PORT_TYPE_SCALAR; + default: + break; + } + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRemap::get_input_port_name(int p_port) const { + switch (p_port) { + case 0: + return "value"; + case 1: + return "input min"; + case 2: + return "input max"; + case 3: + return "output min"; + case 4: + return "output max"; + default: + break; + } + + return ""; +} + +int VisualShaderNodeRemap::get_output_port_count() const { + return 1; +} + +VisualShaderNodeRemap::PortType VisualShaderNodeRemap::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeRemap::get_output_port_name(int p_port) const { + return "value"; +} + +String VisualShaderNodeRemap::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; + + code += vformat(" float _input_range = %s - %s;\n", p_input_vars[2], p_input_vars[1]); + code += vformat(" float _output_range = %s - %s;\n", p_input_vars[4], p_input_vars[3]); + code += vformat(" %s = %s + _output_range * ((%s - %s) / _input_range);\n", p_output_vars[0], p_input_vars[3], p_input_vars[0], p_input_vars[1]); + + return code; +} + +VisualShaderNodeRemap::VisualShaderNodeRemap() { + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, 1.0); + set_input_port_default_value(3, 0.0); + set_input_port_default_value(4, 1.0); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index ffcb41072d..c603a10eae 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -622,6 +622,27 @@ VARIANT_ENUM_CAST(VisualShaderNodeCubemap::TextureType) VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source) /////////////////////////////////////// + +class VisualShaderNodeLinearSceneDepth : public VisualShaderNode { + GDCLASS(VisualShaderNodeLinearSceneDepth, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeLinearSceneDepth(); +}; + +/////////////////////////////////////// /// OPS /////////////////////////////////////// @@ -1231,6 +1252,30 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeUVFunc::Function) /////////////////////////////////////// +/// UV POLARCOORD +/////////////////////////////////////// + +class VisualShaderNodeUVPolarCoord : public VisualShaderNode { + GDCLASS(VisualShaderNodeUVPolarCoord, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeUVPolarCoord(); +}; + +/////////////////////////////////////// /// DOT /////////////////////////////////////// @@ -2574,4 +2619,85 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeBillboard::BillboardType) +/////////////////////////////////////// +/// DistanceFade +/////////////////////////////////////// + +class VisualShaderNodeDistanceFade : public VisualShaderNode { + GDCLASS(VisualShaderNodeDistanceFade, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeDistanceFade(); +}; + +class VisualShaderNodeProximityFade : public VisualShaderNode { + GDCLASS(VisualShaderNodeProximityFade, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeProximityFade(); +}; + +class VisualShaderNodeRandomRange : public VisualShaderNode { + GDCLASS(VisualShaderNodeRandomRange, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeRandomRange(); +}; + +class VisualShaderNodeRemap : public VisualShaderNode { + GDCLASS(VisualShaderNodeRemap, VisualShaderNode); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeRemap(); +}; + #endif // VISUAL_SHADER_NODES_H diff --git a/scene/theme/SCsub b/scene/theme/SCsub new file mode 100644 index 0000000000..fc61250247 --- /dev/null +++ b/scene/theme/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp new file mode 100644 index 0000000000..d6e892cd93 --- /dev/null +++ b/scene/theme/theme_db.cpp @@ -0,0 +1,237 @@ +/*************************************************************************/ +/* theme_db.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "theme_db.h" + +#include "core/config/project_settings.h" +#include "core/io/resource_loader.h" +#include "scene/resources/default_theme/default_theme.h" +#include "scene/resources/font.h" +#include "scene/resources/style_box.h" +#include "scene/resources/texture.h" +#include "scene/resources/theme.h" +#include "servers/text_server.h" + +// Default engine theme creation and configuration. +void ThemeDB::initialize_theme() { + // Allow creating the default theme at a different scale to suit higher/lower base resolutions. + float default_theme_scale = GLOBAL_DEF("gui/theme/default_theme_scale", 1.0); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_theme_scale", PropertyInfo(Variant::FLOAT, "gui/theme/default_theme_scale", PROPERTY_HINT_RANGE, "0.5,8,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + String theme_path = GLOBAL_DEF_RST("gui/theme/custom", ""); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", ""); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + TextServer::FontAntialiasing font_antialiasing = (TextServer::FontAntialiasing)(int)GLOBAL_DEF_RST("gui/theme/default_font_antialiasing", 1); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_antialiasing", PropertyInfo(Variant::INT, "gui/theme/default_font_antialiasing", PROPERTY_HINT_ENUM, "None,Grayscale,LCD sub-pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + TextServer::Hinting font_hinting = (TextServer::Hinting)(int)GLOBAL_DEF_RST("gui/theme/default_font_hinting", TextServer::HINTING_LIGHT); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_hinting", PropertyInfo(Variant::INT, "gui/theme/default_font_hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + TextServer::SubpixelPositioning font_subpixel_positioning = (TextServer::SubpixelPositioning)(int)GLOBAL_DEF_RST("gui/theme/default_font_subpixel_positioning", TextServer::SUBPIXEL_POSITIONING_AUTO); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/default_font_subpixel_positioning", PropertyInfo(Variant::INT, "gui/theme/default_font_subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + + const bool font_msdf = GLOBAL_DEF_RST("gui/theme/default_font_multichannel_signed_distance_field", false); + const bool font_generate_mipmaps = GLOBAL_DEF_RST("gui/theme/default_font_generate_mipmaps", false); + + GLOBAL_DEF_RST("gui/theme/lcd_subpixel_layout", 1); + ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/lcd_subpixel_layout", PropertyInfo(Variant::INT, "gui/theme/lcd_subpixel_layout", PROPERTY_HINT_ENUM, "Disabled,Horizontal RGB,Horizontal BGR,Vertical RGB,Vertical BGR")); + ProjectSettings::get_singleton()->set_restart_if_changed("gui/theme/lcd_subpixel_layout", false); + + Ref<Font> font; + if (!font_path.is_empty()) { + font = ResourceLoader::load(font_path); + if (!font.is_valid()) { + ERR_PRINT("Error loading custom font '" + font_path + "'"); + } + } + + // Always make the default theme to avoid invalid default font/icon/style in the given theme. + if (RenderingServer::get_singleton()) { + make_default_theme(default_theme_scale, font, font_subpixel_positioning, font_hinting, font_antialiasing, font_msdf, font_generate_mipmaps); + } + + if (!theme_path.is_empty()) { + Ref<Theme> theme = ResourceLoader::load(theme_path); + if (theme.is_valid()) { + set_project_theme(theme); + if (font.is_valid()) { + set_fallback_font(font); + } + } else { + ERR_PRINT("Error loading custom theme '" + theme_path + "'"); + } + } +} + +void ThemeDB::initialize_theme_noproject() { + if (RenderingServer::get_singleton()) { + make_default_theme(1.0, Ref<Font>()); + } +} + +// Universal fallback Theme resources. + +void ThemeDB::set_default_theme(const Ref<Theme> &p_default) { + default_theme = p_default; +} + +Ref<Theme> ThemeDB::get_default_theme() { + return default_theme; +} + +void ThemeDB::set_project_theme(const Ref<Theme> &p_project_default) { + project_theme = p_project_default; +} + +Ref<Theme> ThemeDB::get_project_theme() { + return project_theme; +} + +// Universal fallback values for theme item types. + +void ThemeDB::set_fallback_base_scale(float p_base_scale) { + if (fallback_base_scale == p_base_scale) { + return; + } + + fallback_base_scale = p_base_scale; + emit_signal(SNAME("fallback_changed")); +} + +float ThemeDB::get_fallback_base_scale() { + return fallback_base_scale; +} + +void ThemeDB::set_fallback_font(const Ref<Font> &p_font) { + if (fallback_font == p_font) { + return; + } + + fallback_font = p_font; + emit_signal(SNAME("fallback_changed")); +} + +Ref<Font> ThemeDB::get_fallback_font() { + return fallback_font; +} + +void ThemeDB::set_fallback_font_size(int p_font_size) { + if (fallback_font_size == p_font_size) { + return; + } + + fallback_font_size = p_font_size; + emit_signal(SNAME("fallback_changed")); +} + +int ThemeDB::get_fallback_font_size() { + return fallback_font_size; +} + +void ThemeDB::set_fallback_icon(const Ref<Texture2D> &p_icon) { + if (fallback_icon == p_icon) { + return; + } + + fallback_icon = p_icon; + emit_signal(SNAME("fallback_changed")); +} + +Ref<Texture2D> ThemeDB::get_fallback_icon() { + return fallback_icon; +} + +void ThemeDB::set_fallback_stylebox(const Ref<StyleBox> &p_stylebox) { + if (fallback_stylebox == p_stylebox) { + return; + } + + fallback_stylebox = p_stylebox; + emit_signal(SNAME("fallback_changed")); +} + +Ref<StyleBox> ThemeDB::get_fallback_stylebox() { + return fallback_stylebox; +} + +// Object methods. +void ThemeDB::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_default_theme"), &ThemeDB::get_default_theme); + ClassDB::bind_method(D_METHOD("get_project_theme"), &ThemeDB::get_project_theme); + + ClassDB::bind_method(D_METHOD("set_fallback_base_scale", "base_scale"), &ThemeDB::set_fallback_base_scale); + ClassDB::bind_method(D_METHOD("get_fallback_base_scale"), &ThemeDB::get_fallback_base_scale); + ClassDB::bind_method(D_METHOD("set_fallback_font", "font"), &ThemeDB::set_fallback_font); + ClassDB::bind_method(D_METHOD("get_fallback_font"), &ThemeDB::get_fallback_font); + ClassDB::bind_method(D_METHOD("set_fallback_font_size", "font_size"), &ThemeDB::set_fallback_font_size); + ClassDB::bind_method(D_METHOD("get_fallback_font_size"), &ThemeDB::get_fallback_font_size); + ClassDB::bind_method(D_METHOD("set_fallback_icon", "icon"), &ThemeDB::set_fallback_icon); + ClassDB::bind_method(D_METHOD("get_fallback_icon"), &ThemeDB::get_fallback_icon); + ClassDB::bind_method(D_METHOD("set_fallback_stylebox", "stylebox"), &ThemeDB::set_fallback_stylebox); + ClassDB::bind_method(D_METHOD("get_fallback_stylebox"), &ThemeDB::get_fallback_stylebox); + + ADD_GROUP("Fallback values", "fallback_"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fallback_base_scale", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,or_greater"), "set_fallback_base_scale", "get_fallback_base_scale"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_font", PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_NONE), "set_fallback_font", "get_fallback_font"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fallback_font_size", PROPERTY_HINT_RANGE, "0,256,1,or_greater,suffix:px"), "set_fallback_font_size", "get_fallback_font_size"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NONE), "set_fallback_icon", "get_fallback_icon"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_stylebox", PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_NONE), "set_fallback_stylebox", "get_fallback_stylebox"); + + ADD_SIGNAL(MethodInfo("fallback_changed")); +} + +// Memory management, reference, and initialization +ThemeDB *ThemeDB::singleton = nullptr; + +ThemeDB *ThemeDB::get_singleton() { + return singleton; +} + +ThemeDB::ThemeDB() { + singleton = this; + + // Universal default values, final fallback for every theme. + fallback_base_scale = 1.0; + fallback_font_size = 16; +} + +ThemeDB::~ThemeDB() { + default_theme.unref(); + project_theme.unref(); + + fallback_font.unref(); + fallback_icon.unref(); + fallback_stylebox.unref(); + + singleton = nullptr; +} diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h new file mode 100644 index 0000000000..aace33d82c --- /dev/null +++ b/scene/theme/theme_db.h @@ -0,0 +1,95 @@ +/*************************************************************************/ +/* theme_db.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef THEME_DB_H +#define THEME_DB_H + +#include "core/object/class_db.h" +#include "core/object/ref_counted.h" + +class Font; +class StyleBox; +class Texture2D; +class Theme; + +class ThemeDB : public Object { + GDCLASS(ThemeDB, Object); + + static ThemeDB *singleton; + + // Universal Theme resources used when no other theme has the item. + Ref<Theme> default_theme; + Ref<Theme> project_theme; + + // Universal default values, final fallback for every theme. + float fallback_base_scale; + Ref<Font> fallback_font; + int fallback_font_size; + Ref<Texture2D> fallback_icon; + Ref<StyleBox> fallback_stylebox; + +protected: + static void _bind_methods(); + +public: + void initialize_theme(); + void initialize_theme_noproject(); + + // Universal Theme resources + + void set_default_theme(const Ref<Theme> &p_default); + Ref<Theme> get_default_theme(); + + void set_project_theme(const Ref<Theme> &p_project_default); + Ref<Theme> get_project_theme(); + + // Universal default values. + + void set_fallback_base_scale(float p_base_scale); + float get_fallback_base_scale(); + + void set_fallback_font(const Ref<Font> &p_font); + Ref<Font> get_fallback_font(); + + void set_fallback_font_size(int p_font_size); + int get_fallback_font_size(); + + void set_fallback_icon(const Ref<Texture2D> &p_icon); + Ref<Texture2D> get_fallback_icon(); + + void set_fallback_stylebox(const Ref<StyleBox> &p_stylebox); + Ref<StyleBox> get_fallback_stylebox(); + + static ThemeDB *get_singleton(); + ThemeDB(); + ~ThemeDB(); +}; + +#endif // THEME_DB_H |