diff options
Diffstat (limited to 'scene')
27 files changed, 167 insertions, 104 deletions
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index cd2153b132..dd9df3c485 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -500,7 +500,7 @@ bool CPUParticles2D::get_split_scale() { } void CPUParticles2D::_validate_property(PropertyInfo &property) const { - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { + if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { property.usage = PROPERTY_USAGE_NONE; } @@ -762,6 +762,11 @@ void CPUParticles2D::_particles_process(double p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { + real_t t = Math_TAU * Math::randf(); + real_t radius = emission_sphere_radius * Math::randf(); + p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius; + } break; + case EMISSION_SHAPE_SPHERE_SURFACE: { real_t s = Math::randf(), t = Math_TAU * Math::randf(); real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform[2] = Vector2(Math::cos(t), Math::sin(t)) * radius; @@ -1357,7 +1362,7 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles); ADD_GROUP("Emission Shape", "emission_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "emission_rect_extents"), "set_emission_rect_extents", "get_emission_rect_extents"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); @@ -1447,6 +1452,7 @@ void CPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE_SURFACE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 8c8f161d74..7ae51e3966 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -69,6 +69,7 @@ public: enum EmissionShape { EMISSION_SHAPE_POINT, EMISSION_SHAPE_SPHERE, + EMISSION_SHAPE_SPHERE_SURFACE, EMISSION_SHAPE_RECTANGLE, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index ab28a83806..8c8596fc2e 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -508,7 +508,7 @@ bool CPUParticles3D::get_split_scale() { } void CPUParticles3D::_validate_property(PropertyInfo &property) const { - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { + if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { property.usage = PROPERTY_USAGE_NONE; } @@ -804,6 +804,13 @@ void CPUParticles3D::_particles_process(double p_delta) { case EMISSION_SHAPE_SPHERE: { real_t s = 2.0 * Math::randf() - 1.0; real_t t = Math_TAU * Math::randf(); + real_t x = Math::randf(); + real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); + p.transform.origin = Vector3(0, 0, 0).lerp(Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s), x); + } break; + case EMISSION_SHAPE_SPHERE_SURFACE: { + real_t s = 2.0 * Math::randf() - 1.0; + real_t t = Math_TAU * Math::randf(); real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s); } break; @@ -1530,7 +1537,7 @@ void CPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles); ADD_GROUP("Emission Shape", "emission_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); @@ -1627,6 +1634,7 @@ void CPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE_SURFACE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 5eeb5e75d3..521b6c615e 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -71,6 +71,7 @@ public: enum EmissionShape { EMISSION_SHAPE_POINT, EMISSION_SHAPE_SPHERE, + EMISSION_SHAPE_SPHERE_SURFACE, EMISSION_SHAPE_BOX, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index e7e164d7da..8396c23af7 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -408,13 +408,13 @@ bool DirectionalLight3D::is_blend_splits_enabled() const { return blend_splits; } -void DirectionalLight3D::set_sky_only(bool p_sky_only) { - sky_only = p_sky_only; - RS::get_singleton()->light_directional_set_sky_only(light, p_sky_only); +void DirectionalLight3D::set_sky_mode(SkyMode p_mode) { + sky_mode = p_mode; + RS::get_singleton()->light_directional_set_sky_mode(light, RS::LightDirectionalSkyMode(p_mode)); } -bool DirectionalLight3D::is_sky_only() const { - return sky_only; +DirectionalLight3D::SkyMode DirectionalLight3D::get_sky_mode() const { + return sky_mode; } void DirectionalLight3D::_validate_property(PropertyInfo &property) const { @@ -449,8 +449,8 @@ void DirectionalLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight3D::set_blend_splits); ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight3D::is_blend_splits_enabled); - ClassDB::bind_method(D_METHOD("set_sky_only", "priority"), &DirectionalLight3D::set_sky_only); - ClassDB::bind_method(D_METHOD("is_sky_only"), &DirectionalLight3D::is_sky_only); + ClassDB::bind_method(D_METHOD("set_sky_mode", "mode"), &DirectionalLight3D::set_sky_mode); + ClassDB::bind_method(D_METHOD("get_sky_mode"), &DirectionalLight3D::get_sky_mode); ADD_GROUP("Directional Shadow", "directional_shadow_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode"); @@ -462,11 +462,15 @@ void DirectionalLight3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,8192,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_RANGE, "0,1024,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_in_sky_only"), "set_sky_only", "is_sky_only"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sky_mode", PROPERTY_HINT_ENUM, "Light and Sky,Light Only,Sky Only"), "set_sky_mode", "get_sky_mode"); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS); + + BIND_ENUM_CONSTANT(SKY_MODE_LIGHT_AND_SKY); + BIND_ENUM_CONSTANT(SKY_MODE_LIGHT_ONLY); + BIND_ENUM_CONSTANT(SKY_MODE_SKY_ONLY); } DirectionalLight3D::DirectionalLight3D() : @@ -477,6 +481,7 @@ DirectionalLight3D::DirectionalLight3D() : set_param(PARAM_SHADOW_BIAS, 0.1); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); blend_splits = false; + set_sky_mode(SKY_MODE_LIGHT_AND_SKY); } void OmniLight3D::set_shadow_mode(ShadowMode p_mode) { diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index ed9e0bdfff..81c25f01c3 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -156,10 +156,16 @@ public: SHADOW_PARALLEL_4_SPLITS, }; + enum SkyMode { + SKY_MODE_LIGHT_AND_SKY, + SKY_MODE_LIGHT_ONLY, + SKY_MODE_SKY_ONLY, + }; + private: bool blend_splits; ShadowMode shadow_mode; - bool sky_only = false; + SkyMode sky_mode = SKY_MODE_LIGHT_AND_SKY; protected: static void _bind_methods(); @@ -172,13 +178,14 @@ public: void set_blend_splits(bool p_enable); bool is_blend_splits_enabled() const; - void set_sky_only(bool p_sky_only); - bool is_sky_only() const; + void set_sky_mode(SkyMode p_mode); + SkyMode get_sky_mode() const; DirectionalLight3D(); }; VARIANT_ENUM_CAST(DirectionalLight3D::ShadowMode) +VARIANT_ENUM_CAST(DirectionalLight3D::SkyMode) class OmniLight3D : public Light3D { GDCLASS(OmniLight3D, Light3D); diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 8ee777bcbf..eafb74f203 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -417,8 +417,8 @@ void SoftDynamicBody3D::_draw_soft_mesh() { PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); } - if (!rendering_server_handler.is_ready(mesh_rid)) { - rendering_server_handler.prepare(mesh_rid, 0); + if (!rendering_server_handler->is_ready(mesh_rid)) { + rendering_server_handler->prepare(mesh_rid, 0); /// Necessary in order to render the mesh correctly (Soft body nodes are in global space) simulation_started = true; @@ -428,11 +428,11 @@ void SoftDynamicBody3D::_draw_soft_mesh() { _update_physics_server(); - rendering_server_handler.open(); - PhysicsServer3D::get_singleton()->soft_body_update_rendering_server(physics_rid, &rendering_server_handler); - rendering_server_handler.close(); + rendering_server_handler->open(); + PhysicsServer3D::get_singleton()->soft_body_update_rendering_server(physics_rid, rendering_server_handler); + rendering_server_handler->close(); - rendering_server_handler.commit_changes(); + rendering_server_handler->commit_changes(); } void SoftDynamicBody3D::_prepare_physics_server() { @@ -688,10 +688,12 @@ bool SoftDynamicBody3D::is_ray_pickable() const { SoftDynamicBody3D::SoftDynamicBody3D() : physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) { + rendering_server_handler = memnew(SoftDynamicBodyRenderingServerHandler); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); } SoftDynamicBody3D::~SoftDynamicBody3D() { + memdelete(rendering_server_handler); PhysicsServer3D::get_singleton()->free(physics_rid); } diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index c30ec701c7..e11e5c73df 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -36,7 +36,7 @@ class SoftDynamicBody3D; -class SoftDynamicBodyRenderingServerHandler : public RenderingServerHandler { +class SoftDynamicBodyRenderingServerHandler : public PhysicsServer3DRenderingServerHandler { friend class SoftDynamicBody3D; RID mesh; @@ -84,7 +84,7 @@ public: }; private: - SoftDynamicBodyRenderingServerHandler rendering_server_handler; + SoftDynamicBodyRenderingServerHandler *rendering_server_handler = nullptr; RID physics_rid; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index f56e3caa4b..bda3868fbb 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -872,7 +872,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { if (d == 0) { w[i] = 0; } else { - w[i] = MIN(d, 254) + 1; + w[i] = MIN(d, 254u) + 1; } } } diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 3d0ac291b8..433f21f91f 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -376,7 +376,7 @@ void AnimationNodeOneShot::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time"); - ADD_GROUP("autorestart_", "Auto Restart"); + ADD_GROUP("Auto Restart", "autorestart_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autorestart"), "set_autorestart", "has_autorestart"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "autorestart_delay", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_autorestart_delay", "get_autorestart_delay"); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index e0e94d8632..309c2b5245 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -273,10 +273,6 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri } } - if (!p_seek && p_optimize && !any_valid) { //pointless to go on, all are zero - return 0; - } - String new_path; AnimationNode *new_parent; @@ -289,6 +285,10 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri new_parent = parent; new_path = String(parent->base_path) + String(p_subpath) + "/"; } + + if (!p_seek && p_optimize && !any_valid) { + return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_connections); + } return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_connections); } @@ -618,6 +618,11 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { int bone_idx = sk->find_bone(path.get_subname(0)); if (bone_idx != -1) { track_xform->bone_idx = bone_idx; + Transform3D rest = sk->get_bone_rest(bone_idx); + track_xform->init_loc = rest.origin; + track_xform->ref_rot = rest.basis.get_rotation_quaternion(); + track_xform->init_rot = track_xform->ref_rot.log(); + track_xform->init_scale = rest.basis.get_scale(); } } @@ -644,7 +649,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) { } break; case Animation::TYPE_BLEND_SHAPE: { #ifndef _3D_DISABLED - if (path.get_subname_count() != 1) { ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track does not contain a blend shape subname: '" + String(path) + "'"); continue; @@ -942,23 +946,16 @@ void AnimationTree::_process_graph(double p_delta) { real_t blend = (*as.track_blends)[blend_idx] * weight; - if (blend < CMP_EPSILON) { - continue; //nothing to blend - } - switch (ttype) { case Animation::TYPE_POSITION_3D: { #ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); - if (t->process_pass != process_pass) { t->process_pass = process_pass; - t->loc = Vector3(); - t->rot = Quaternion(); - t->rot_blend_accum = 0; - t->scale = Vector3(1, 1, 1); + t->loc = t->init_loc; + t->rot = t->init_rot; + t->scale = t->init_scale; } - if (track->root_motion) { double prev_time = time - delta; if (!backward) { @@ -1036,22 +1033,19 @@ void AnimationTree::_process_graph(double p_delta) { continue; } - t->loc = t->loc.lerp(loc, blend); + t->loc += (loc - t->init_loc) * blend; } #endif // _3D_DISABLED } break; case Animation::TYPE_ROTATION_3D: { #ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); - if (t->process_pass != process_pass) { t->process_pass = process_pass; - t->loc = Vector3(); - t->rot = Quaternion(); - t->rot_blend_accum = 0; - t->scale = Vector3(1, 1, 1); + t->loc = t->init_loc; + t->rot = t->init_rot; + t->scale = t->init_scale; } - if (track->root_motion) { double prev_time = time - delta; if (!backward) { @@ -1097,8 +1091,7 @@ void AnimationTree::_process_graph(double p_delta) { continue; } a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]); - Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); - t->rot = (t->rot * q).normalized(); + t->rot += (rot[1].log() - rot[0].log()) * blend; prev_time = 0; } } else { @@ -1108,8 +1101,7 @@ void AnimationTree::_process_graph(double p_delta) { continue; } a->rotation_track_interpolate(i, 0, &rot[1]); - Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); - t->rot = (t->rot * q).normalized(); + t->rot += (rot[1].log() - rot[0].log()) * blend; prev_time = 0; } } @@ -1120,8 +1112,7 @@ void AnimationTree::_process_graph(double p_delta) { } a->rotation_track_interpolate(i, time, &rot[1]); - Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized(); - t->rot = (t->rot * q).normalized(); + t->rot += (rot[1].log() - rot[0].log()) * blend; prev_time = !backward ? 0 : (double)a->get_length(); } else { @@ -1132,29 +1123,22 @@ void AnimationTree::_process_graph(double p_delta) { continue; } - if (t->rot_blend_accum == 0) { - t->rot = rot; - t->rot_blend_accum = blend; - } else { - real_t rot_total = t->rot_blend_accum + blend; - t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized(); - t->rot_blend_accum = rot_total; + if (signbit(rot.dot(t->ref_rot))) { + rot = -rot; } + t->rot += (rot.log() - t->init_rot) * blend; } #endif // _3D_DISABLED } break; case Animation::TYPE_SCALE_3D: { #ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); - if (t->process_pass != process_pass) { t->process_pass = process_pass; - t->loc = Vector3(); - t->rot = Quaternion(); - t->rot_blend_accum = 0; - t->scale = Vector3(1, 1, 1); + t->loc = t->init_loc; + t->rot = t->init_rot; + t->scale = t->init_scale; } - if (track->root_motion) { double prev_time = time - delta; if (!backward) { @@ -1232,7 +1216,7 @@ void AnimationTree::_process_graph(double p_delta) { continue; } - t->scale = t->scale.lerp(scale, blend); + t->scale += (scale - t->init_scale) * blend; } #endif // _3D_DISABLED } break; @@ -1254,7 +1238,7 @@ void AnimationTree::_process_graph(double p_delta) { continue; } - t->value = Math::lerp(t->value, value, (float)blend); + t->value += value * blend; #endif // _3D_DISABLED } break; case Animation::TYPE_VALUE: { @@ -1271,13 +1255,16 @@ void AnimationTree::_process_graph(double p_delta) { } if (t->process_pass != process_pass) { - t->value = value; t->process_pass = process_pass; + t->value = value; + t->value.zero(); } - Variant::interpolate(t->value, value, blend, t->value); - + Variant::blend(t->value, value, blend, t->value); } else { + if (blend < CMP_EPSILON) { + continue; //nothing to blend + } List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices, pingponged); @@ -1289,7 +1276,10 @@ void AnimationTree::_process_graph(double p_delta) { } break; case Animation::TYPE_METHOD: { - if (delta == 0) { + if (blend < CMP_EPSILON) { + continue; //nothing to blend + } + if (!seeked && Math::is_zero_approx(delta)) { continue; } TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track); @@ -1312,14 +1302,16 @@ void AnimationTree::_process_graph(double p_delta) { real_t bezier = a->bezier_track_interpolate(i, time); if (t->process_pass != process_pass) { - t->value = bezier; t->process_pass = process_pass; + t->value = 0; } - t->value = Math::lerp(t->value, bezier, blend); - + t->value += bezier * blend; } break; case Animation::TYPE_AUDIO: { + if (blend < CMP_EPSILON) { + continue; //nothing to blend + } TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track); if (seeked) { @@ -1431,6 +1423,9 @@ void AnimationTree::_process_graph(double p_delta) { } } break; case Animation::TYPE_ANIMATION: { + if (blend < CMP_EPSILON) { + continue; //nothing to blend + } TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track); AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object); @@ -1521,6 +1516,7 @@ void AnimationTree::_process_graph(double p_delta) { case Animation::TYPE_POSITION_3D: { #ifndef _3D_DISABLED TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track); + t->rot = t->rot.exp(); if (t->root_motion) { Transform3D xform; diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 705ee91c76..3ccb6be073 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -197,9 +197,12 @@ private: bool loc_used = false; bool rot_used = false; bool scale_used = false; + Vector3 init_loc = Vector3(0, 0, 0); + Quaternion ref_rot = Quaternion(0, 0, 0, 1); + Quaternion init_rot = Quaternion(0, 0, 0, 0); + Vector3 init_scale = Vector3(1, 1, 1); Vector3 loc; Quaternion rot; - real_t rot_blend_accum = 0.0; Vector3 scale; TrackCacheTransform() { diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp index 3bd21f96b2..40aca555db 100644 --- a/scene/gui/flow_container.cpp +++ b/scene/gui/flow_container.cpp @@ -39,6 +39,11 @@ struct _LineData { }; void FlowContainer::_resort() { + // Avoid resorting if invisible. + if (!is_visible_in_tree()) { + return; + } + int separation_horizontal = get_theme_constant(SNAME("hseparation")); int separation_vertical = get_theme_constant(SNAME("vseparation")); @@ -58,7 +63,7 @@ void FlowContainer::_resort() { // First pass for line wrapping and minimum size calculation. for (int i = 0; i < get_child_count(); i++) { Control *child = Object::cast_to<Control>(get_child(i)); - if (!child || !child->is_visible_in_tree()) { + if (!child || !child->is_visible()) { continue; } if (child->is_set_as_top_level()) { @@ -128,7 +133,7 @@ void FlowContainer::_resort() { for (int i = 0; i < get_child_count(); i++) { Control *child = Object::cast_to<Control>(get_child(i)); - if (!child || !child->is_visible_in_tree()) { + if (!child || !child->is_visible()) { continue; } if (child->is_set_as_top_level()) { diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 419901d5ea..cd6fc168c2 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -115,7 +115,7 @@ void Label::_shape() { if (lines_dirty) { for (int i = 0; i < lines_rid.size(); i++) { - TS->free(lines_rid[i]); + TS->free_rid(lines_rid[i]); } lines_rid.clear(); @@ -960,8 +960,8 @@ Label::Label(const String &p_text) { Label::~Label() { for (int i = 0; i < lines_rid.size(); i++) { - TS->free(lines_rid[i]); + TS->free_rid(lines_rid[i]); } lines_rid.clear(); - TS->free(text_rid); + TS->free_rid(text_rid); } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index da39a3d387..e063d3aeba 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2458,5 +2458,5 @@ LineEdit::LineEdit(const String &p_placeholder) { } LineEdit::~LineEdit() { - TS->free(text_rid); + TS->free_rid(text_rid); } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index b3804e73d9..37d75cea6a 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -240,6 +240,10 @@ void OptionButton::set_item_metadata(int p_idx, const Variant &p_metadata) { popup->set_item_metadata(p_idx, p_metadata); } +void OptionButton::set_item_tooltip(int p_idx, const String &p_tooltip) { + popup->set_item_tooltip(p_idx, p_tooltip); +} + void OptionButton::set_item_disabled(int p_idx, bool p_disabled) { popup->set_item_disabled(p_idx, p_disabled); } @@ -268,6 +272,10 @@ Variant OptionButton::get_item_metadata(int p_idx) const { return popup->get_item_metadata(p_idx); } +String OptionButton::get_item_tooltip(int p_idx) const { + return popup->get_item_tooltip(p_idx); +} + bool OptionButton::is_item_disabled(int p_idx) const { return popup->is_item_disabled(p_idx); } @@ -385,11 +393,13 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_disabled", "idx", "disabled"), &OptionButton::set_item_disabled); ClassDB::bind_method(D_METHOD("set_item_id", "idx", "id"), &OptionButton::set_item_id); ClassDB::bind_method(D_METHOD("set_item_metadata", "idx", "metadata"), &OptionButton::set_item_metadata); + ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &OptionButton::set_item_tooltip); ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &OptionButton::get_item_text); ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &OptionButton::get_item_icon); ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &OptionButton::get_item_id); ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index); ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata); + ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &OptionButton::get_item_tooltip); ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled); ClassDB::bind_method(D_METHOD("add_separator"), &OptionButton::add_separator); ClassDB::bind_method(D_METHOD("clear"), &OptionButton::clear); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 5352fe18a6..0a3c8cdb17 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -68,6 +68,7 @@ public: void set_item_id(int p_idx, int p_id); void set_item_metadata(int p_idx, const Variant &p_metadata); void set_item_disabled(int p_idx, bool p_disabled); + void set_item_tooltip(int p_idx, const String &p_tooltip); String get_item_text(int p_idx) const; Ref<Texture2D> get_item_icon(int p_idx) const; @@ -75,6 +76,7 @@ public: int get_item_index(int p_id) const; Variant get_item_metadata(int p_idx) const; bool is_item_disabled(int p_idx) const; + String get_item_tooltip(int p_idx) const; void set_item_count(int p_count); int get_item_count() const; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 4220066b20..9fc1fb072c 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1003,8 +1003,12 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) { p_idx += get_item_count(); } ERR_FAIL_INDEX(p_idx, items.size()); + if (items[p_idx].text == p_text) { + return; + } items.write[p_idx].text = p_text; items.write[p_idx].xl_text = atr(p_text); + items.write[p_idx].dirty = true; _shape_item(p_idx); control->update(); diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h index 0f2184aca7..e0c4ba85ef 100644 --- a/scene/gui/tab_bar.h +++ b/scene/gui/tab_bar.h @@ -86,7 +86,7 @@ private: Vector<Tab> tabs; int current = 0; int previous = 0; - AlignmentMode tab_alignment = ALIGNMENT_CENTER; + AlignmentMode tab_alignment = ALIGNMENT_LEFT; bool clip_tabs = true; int rb_hover = -1; bool rb_pressing = false; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 1d263ba858..ec0821557b 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -995,12 +995,7 @@ Transform2D CanvasItem::get_viewport_transform() const { ERR_FAIL_COND_V(!is_inside_tree(), Transform2D()); if (canvas_layer) { - if (get_viewport()) { - return get_viewport()->get_final_transform() * canvas_layer->get_transform(); - } else { - return canvas_layer->get_transform(); - } - + return get_viewport()->get_final_transform() * canvas_layer->get_transform(); } else { return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform(); } diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index ce2a675854..15594109e9 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -40,7 +40,7 @@ _FORCE_INLINE_ void FontData::_clear_cache() { for (int i = 0; i < cache.size(); i++) { if (cache[i].is_valid()) { - TS->free(cache[i]); + TS->free_rid(cache[i]); cache.write[i] = RID(); } } @@ -1499,7 +1499,7 @@ void FontData::clear_cache() { void FontData::remove_cache(int p_cache_index) { ERR_FAIL_INDEX(p_cache_index, cache.size()); if (cache[p_cache_index].is_valid()) { - TS->free(cache.write[p_cache_index]); + TS->free_rid(cache.write[p_cache_index]); } cache.remove_at(p_cache_index); emit_changed(); @@ -1924,6 +1924,8 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("get_supported_chars"), &Font::get_supported_chars); ClassDB::bind_method(D_METHOD("update_changes"), &Font::update_changes); + + ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids); } bool Font::_set(const StringName &p_name, const Variant &p_value) { @@ -2427,11 +2429,15 @@ String Font::get_supported_chars() const { return chars; } -Vector<RID> Font::get_rids() const { +Array Font::get_rids() const { + Array _rids; for (int i = 0; i < data.size(); i++) { _ensure_rid(i); + if (rids[i].is_valid()) { + _rids.push_back(rids[i]); + } } - return rids; + return _rids; } void Font::update_changes() { diff --git a/scene/resources/font.h b/scene/resources/font.h index 0185b019f1..2aa12dd2de 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -311,7 +311,7 @@ public: virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE) const; virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const; - Vector<RID> get_rids() const; + Array get_rids() const; void update_changes(); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 1ef2b3496f..01a0411545 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -190,6 +190,9 @@ void ParticlesMaterial::_update_shader() { case EMISSION_SHAPE_SPHERE: { code += "uniform float emission_sphere_radius;\n"; } break; + case EMISSION_SHAPE_SPHERE_SURFACE: { + code += "uniform float emission_sphere_radius;\n"; + } break; case EMISSION_SHAPE_BOX: { code += "uniform vec3 emission_box_extents;\n"; } break; @@ -398,6 +401,13 @@ void ParticlesMaterial::_update_shader() { case EMISSION_SHAPE_SPHERE: { code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n"; code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n"; + code += " float p = rand_from_seed(alt_seed);\n"; + code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n"; + code += " TRANSFORM[3].xyz = mix(vec3(0.0, 0.0, 0.0), vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s), p);\n"; + } break; + case EMISSION_SHAPE_SPHERE_SURFACE: { + code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n"; + code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n"; code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n"; code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n"; } break; @@ -1165,7 +1175,7 @@ RID ParticlesMaterial::get_shader_rid() const { } void ParticlesMaterial::_validate_property(PropertyInfo &property) const { - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { + if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { property.usage = PROPERTY_USAGE_NONE; } @@ -1388,7 +1398,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_GROUP("Emission Shape", "emission_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points,Ring"), "set_emission_shape", "get_emission_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points,Ring"), "set_emission_shape", "get_emission_shape"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_point_texture", "get_emission_point_texture"); @@ -1496,6 +1506,7 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE_SURFACE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index fd00c58468..57da344ce0 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -73,6 +73,7 @@ public: enum EmissionShape { EMISSION_SHAPE_POINT, EMISSION_SHAPE_SPHERE, + EMISSION_SHAPE_SPHERE_SURFACE, EMISSION_SHAPE_BOX, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index c3b5bd3564..db5f1338db 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -411,5 +411,5 @@ TextLine::TextLine() { } TextLine::~TextLine() { - TS->free(rid); + TS->free_rid(rid); } diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 4d75874199..d74d7c88c6 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -140,7 +140,7 @@ void TextParagraph::_bind_methods() { void TextParagraph::_shape_lines() { if (lines_dirty) { for (int i = 0; i < lines_rid.size(); i++) { - TS->free(lines_rid[i]); + TS->free_rid(lines_rid[i]); } lines_rid.clear(); @@ -168,7 +168,7 @@ void TextParagraph::_shape_lines() { RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x; if (v_offset < h) { - TS->free(line); + TS->free_rid(line); break; } if (!tab_stops.is_empty()) { @@ -271,7 +271,7 @@ void TextParagraph::clear() { spacing_top = 0; spacing_bottom = 0; for (int i = 0; i < lines_rid.size(); i++) { - TS->free(lines_rid[i]); + TS->free_rid(lines_rid[i]); } lines_rid.clear(); TS->shaped_text_clear(rid); @@ -847,9 +847,9 @@ TextParagraph::TextParagraph() { TextParagraph::~TextParagraph() { for (int i = 0; i < lines_rid.size(); i++) { - TS->free(lines_rid[i]); + TS->free_rid(lines_rid[i]); } lines_rid.clear(); - TS->free(rid); - TS->free(dropcap_rid); + TS->free_rid(rid); + TS->free_rid(dropcap_rid); } diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 1930fa2682..3113987fbc 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -212,7 +212,7 @@ void ImageTexture::update(const Ref<Image> &p_image) { ERR_FAIL_COND_MSG(mipmaps != p_image->has_mipmaps(), "The new image mipmaps configuration must match the texture's image mipmaps configuration"); - RenderingServer::get_singleton()->texture_2d_update(texture, p_image); + RS::get_singleton()->texture_2d_update(texture, p_image); notify_property_list_changed(); emit_changed(); |