diff options
Diffstat (limited to 'scene')
28 files changed, 336 insertions, 131 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/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/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/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 0a36176c98..d585fb3a7a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -699,7 +699,6 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o Item *it_from = l.from; Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr; - Variant meta; if (it_from == nullptr) { return 0; @@ -1070,23 +1069,60 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } + Vector2 ul_start; + bool ul_started = false; + Color ul_color; + + Vector2 dot_ul_start; + bool dot_ul_started = false; + Color dot_ul_color; + + Vector2 st_start; + bool st_started = false; + Color st_color; + for (int i = 0; i < gl_size; i++) { bool selected = selection.active && (sel_start != -1) && (glyphs[i].start >= sel_start) && (glyphs[i].end <= sel_end); Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start); Color font_color = _find_color(it, p_base_color); - if (_find_underline(it) || (_find_meta(it, &meta) && underline_meta)) { - Color uc = font_color; - uc.a *= 0.5; + if (_find_underline(it) || (_find_meta(it, nullptr) && underline_meta)) { + if (!ul_started) { + ul_started = true; + ul_start = p_ofs + Vector2(off.x, off.y); + ul_color = font_color; + ul_color.a *= 0.5; + } + } else if (ul_started) { + ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); - draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); + draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); + } + if (_find_hint(it, nullptr) && underline_hint) { + if (!dot_ul_started) { + dot_ul_started = true; + dot_ul_start = p_ofs + Vector2(off.x, off.y); + dot_ul_color = font_color; + dot_ul_color.a *= 0.5; + } + } else if (dot_ul_started) { + dot_ul_started = false; + float y_off = TS->shaped_text_get_underline_position(rid); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); } if (_find_strikethrough(it)) { - Color uc = font_color; - uc.a *= 0.5; + if (!st_started) { + st_started = true; + st_start = p_ofs + Vector2(off.x, off.y); + st_color = font_color; + st_color.a *= 0.5; + } + } else if (st_started) { + st_started = false; float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); - draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width); + draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); } // Get FX. @@ -1222,6 +1258,24 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o off.x += glyphs[i].advance; } } + if (ul_started) { + ul_started = false; + float y_off = TS->shaped_text_get_underline_position(rid); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); + } + if (dot_ul_started) { + dot_ul_started = false; + float y_off = TS->shaped_text_get_underline_position(rid); + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); + } + if (st_started) { + st_started = false; + float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; + float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale(); + draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); + } // Draw foreground color box _draw_fbg_boxes(ci, rid, fbg_line_off, it_from, it_to, chr_range.x, chr_range.y, 1); @@ -1907,6 +1961,20 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) { } } +String RichTextLabel::get_tooltip(const Point2 &p_pos) const { + Item *c_item = nullptr; + bool outside; + + const_cast<RichTextLabel *>(this)->_find_click(main, p_pos, nullptr, nullptr, &c_item, nullptr, &outside); + + String description; + if (c_item && !outside && const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) { + return description; + } else { + return Control::get_tooltip(p_pos); + } +} + void RichTextLabel::_find_frame(Item *p_item, ItemFrame **r_frame, int *r_line) { if (r_frame != nullptr) { *r_frame = nullptr; @@ -2244,6 +2312,24 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) return false; } +bool RichTextLabel::_find_hint(Item *p_item, String *r_description) { + Item *item = p_item; + + while (item) { + if (item->type == ITEM_HINT) { + ItemHint *hint = static_cast<ItemHint *>(item); + if (r_description) { + *r_description = hint->description; + } + return true; + } + + item = item->parent; + } + + return false; +} + Color RichTextLabel::_find_bgcolor(Item *p_item) { Item *item = p_item; @@ -2736,6 +2822,14 @@ void RichTextLabel::push_meta(const Variant &p_meta) { _add_item(item, true); } +void RichTextLabel::push_hint(const String &p_string) { + ERR_FAIL_COND(current->type == ITEM_TABLE); + ItemHint *item = memnew(ItemHint); + + item->description = p_string; + _add_item(item, true); +} + void RichTextLabel::push_table(int p_columns, InlineAlignment p_alignment) { ERR_FAIL_COND(p_columns < 1); ItemTable *item = memnew(ItemTable); @@ -2930,6 +3024,15 @@ bool RichTextLabel::is_meta_underlined() const { return underline_meta; } +void RichTextLabel::set_hint_underline(bool p_underline) { + underline_hint = p_underline; + update(); +} + +bool RichTextLabel::is_hint_underlined() const { + return underline_hint; +} + void RichTextLabel::set_override_selected_font_color(bool p_override_selected_font_color) { override_selected_font_color = p_override_selected_font_color; } @@ -3367,6 +3470,11 @@ void RichTextLabel::append_text(const String &p_bbcode) { push_meta(url); pos = brk_end + 1; tag_stack.push_front("url"); + } else if (tag.begins_with("hint=")) { + String description = tag.substr(5, tag.length()); + push_hint(description); + pos = brk_end + 1; + tag_stack.push_front("hint"); } else if (tag.begins_with("dropcap")) { Vector<String> subtag = tag.substr(5, tag.length()).split(" "); Ref<Font> f = get_theme_font(SNAME("normal_font")); @@ -4287,6 +4395,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent); ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize"), &RichTextLabel::push_list); ClassDB::bind_method(D_METHOD("push_meta", "data"), &RichTextLabel::push_meta); + ClassDB::bind_method(D_METHOD("push_hint", "description"), &RichTextLabel::push_hint); ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline); ClassDB::bind_method(D_METHOD("push_strikethrough"), &RichTextLabel::push_strikethrough); ClassDB::bind_method(D_METHOD("push_table", "columns", "inline_align"), &RichTextLabel::push_table, DEFVAL(INLINE_ALIGNMENT_TOP)); @@ -4318,6 +4427,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_meta_underline", "enable"), &RichTextLabel::set_meta_underline); ClassDB::bind_method(D_METHOD("is_meta_underlined"), &RichTextLabel::is_meta_underlined); + ClassDB::bind_method(D_METHOD("set_hint_underline", "enable"), &RichTextLabel::set_hint_underline); + ClassDB::bind_method(D_METHOD("is_hint_underlined"), &RichTextLabel::is_hint_underlined); + ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &RichTextLabel::set_override_selected_font_color); ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &RichTextLabel::is_overriding_selected_font_color); @@ -4401,6 +4513,7 @@ void RichTextLabel::_bind_methods() { 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::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. @@ -4454,6 +4567,7 @@ void RichTextLabel::_bind_methods() { BIND_ENUM_CONSTANT(ITEM_BGCOLOR); BIND_ENUM_CONSTANT(ITEM_FGCOLOR); BIND_ENUM_CONSTANT(ITEM_META); + BIND_ENUM_CONSTANT(ITEM_HINT); BIND_ENUM_CONSTANT(ITEM_DROPCAP); BIND_ENUM_CONSTANT(ITEM_CUSTOMFX); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 076b68a0da..c9cbbe9d15 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -78,6 +78,7 @@ public: ITEM_BGCOLOR, ITEM_FGCOLOR, ITEM_META, + ITEM_HINT, ITEM_DROPCAP, ITEM_CUSTOMFX }; @@ -218,6 +219,11 @@ private: ItemMeta() { type = ITEM_META; } }; + struct ItemHint : public Item { + String description; + ItemHint() { type = ITEM_HINT; } + }; + struct ItemParagraph : public Item { HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; String language; @@ -369,6 +375,7 @@ private: int tab_size = 4; bool underline_meta = true; + bool underline_hint = true; bool override_selected_font_color = false; HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT; @@ -452,6 +459,7 @@ private: bool _find_underline(Item *p_item); bool _find_strikethrough(Item *p_item); bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = nullptr); + bool _find_hint(Item *p_item, String *r_description); Color _find_bgcolor(Item *p_item); Color _find_fgcolor(Item *p_item); bool _find_layout_subitem(Item *from, Item *to); @@ -462,6 +470,7 @@ private: void _scroll_changed(double); virtual void gui_input(const Ref<InputEvent> &p_event) override; + virtual String get_tooltip(const Point2 &p_pos) const override; Item *_get_next_item(Item *p_item, bool p_free = false) const; Item *_get_prev_item(Item *p_item, bool p_free = false) const; @@ -505,6 +514,7 @@ public: void push_indent(int p_level); void push_list(int p_level, ListType p_list, bool p_capitalize); void push_meta(const Variant &p_meta); + void push_hint(const String &p_string); void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP); void push_fade(int p_start_index, int p_length); void push_shake(int p_strength, float p_rate); @@ -530,6 +540,9 @@ public: void set_meta_underline(bool p_underline); bool is_meta_underlined() const; + void set_hint_underline(bool p_underline); + bool is_hint_underlined() const; + void set_override_selected_font_color(bool p_override_selected_font_color); bool is_overriding_selected_font_color() const; 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 ec0821557b..b50f7866af 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -444,6 +444,25 @@ void CanvasItem::item_rect_changed(bool p_size_changed) { emit_signal(SceneStringNames::get_singleton()->item_rect_changed); } +void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash) { + ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + + float length = (p_to - p_from).length(); + if (length < p_dash) { + RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); + return; + } + + Point2 off = p_from; + Vector2 step = p_dash * (p_to - p_from).normalized(); + int steps = length / p_dash / 2; + for (int i = 0; i < steps; i++) { + RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, off, (off + step), p_color, p_width); + off += 2 * step; + } + RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, off, p_to, p_color, p_width); +} + void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -868,6 +887,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_is_on_top"), &CanvasItem::_is_on_top); ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("draw_dashed_line", "from", "to", "color", "width", "dash"), &CanvasItem::draw_dashed_line, DEFVAL(1.0), DEFVAL(2.0)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_arc", "center", "radius", "start_angle", "end_angle", "point_count", "color", "width", "antialiased"), &CanvasItem::draw_arc, DEFVAL(1.0), DEFVAL(false)); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 1b2c188fc0..dbc833aa5b 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -217,6 +217,7 @@ public: /* DRAWING API */ + void draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0, real_t p_dash = 2.0); void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width = 1.0); void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, real_t p_width = 1.0, bool p_antialiased = false); void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, real_t p_width = 1.0, bool p_antialiased = false); 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/material.cpp b/scene/resources/material.cpp index a0e6cc28ce..430626b008 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -809,26 +809,26 @@ void BaseMaterial3D::_update_shader() { case BILLBOARD_DISABLED: { } break; case BILLBOARD_ENABLED: { - code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n"; + code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } } break; case BILLBOARD_FIXED_Y: { - code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), CAMERA_MATRIX[2].xyz)),0.0),vec4(0.0, 1.0, 0.0, 0.0),vec4(normalize(cross(CAMERA_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))),0.0),WORLD_MATRIX[3]);\n"; + code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), INV_VIEW_MATRIX[2].xyz)), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), MODEL_MATRIX[3]);\n"; if (flags[FLAG_BILLBOARD_KEEP_SCALE]) { - code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0),vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " MODELVIEW_MATRIX = MODELVIEW_MATRIX * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0),vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } } break; case BILLBOARD_PARTICLES: { //make billboard - code += " mat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n"; + code += " mat4 mat_world = mat4(normalize(INV_VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]),normalize(INV_VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), MODEL_MATRIX[3]);\n"; //rotate by rotation - code += " mat_world = mat_world * mat4( vec4(cos(INSTANCE_CUSTOM.x),-sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0),vec4(0.0, 0.0, 1.0, 0.0),vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " mat_world = mat_world * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; //set modelview - code += " MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; + code += " MODELVIEW_MATRIX = VIEW_MATRIX * mat_world;\n"; //handle animation code += " float h_frames = float(particles_anim_h_frames);\n"; @@ -883,8 +883,8 @@ void BaseMaterial3D::_update_shader() { if (flags[FLAG_UV1_USE_TRIPLANAR]) { if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) { - code += " uv1_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n"; - code += " uv1_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n"; + code += " uv1_power_normal=pow(abs(mat3(MODEL_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n"; + code += " uv1_triplanar_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n"; } else { code += " uv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n"; code += " uv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n"; @@ -895,8 +895,8 @@ void BaseMaterial3D::_update_shader() { if (flags[FLAG_UV2_USE_TRIPLANAR]) { if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) { - code += " uv2_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n"; - code += " uv2_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n"; + code += " uv2_power_normal=pow(abs(mat3(MODEL_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n"; + code += " uv2_triplanar_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n"; } else { code += " uv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n"; code += " uv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n"; @@ -1140,7 +1140,7 @@ void BaseMaterial3D::_update_shader() { if (!RenderingServer::get_singleton()->is_low_end()) { code += " {\n"; if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { - code += " float fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n"; + code += " float fade_distance = abs((VIEW_MATRIX * MODEL_MATRIX[3]).z);\n"; } else { code += " float fade_distance=-VERTEX.z;\n"; 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(); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index d3e61dbc84..997b523d2e 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -2576,10 +2576,10 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "instance_custom", "INSTANCE_CUSTOM.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "instance_custom_alpha", "INSTANCE_CUSTOM.a" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "modelview", "MODELVIEW_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_matrix", "MODEL_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "modelview_matrix", "MODELVIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_view_matrix", "INV_VIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, @@ -2602,11 +2602,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "point_coord", "POINT_COORD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_matrix", "MODEL_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_view_matrix", "INV_VIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection_matrix", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection_matrix", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, @@ -2634,11 +2634,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "specular", "SPECULAR_LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "metallic", "METALLIC" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_matrix", "MODEL_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_view_matrix", "INV_VIEW_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection_matrix", "PROJECTION_MATRIX" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection_matrix", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, @@ -2652,9 +2652,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "texture_pixel_size", "TEXTURE_PIXEL_SIZE" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "canvas", "CANVAS_MATRIX" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "screen", "SCREEN_MATRIX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "model_matrix", "MODEL_MATRIX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "canvas_matrix", "CANVAS_MATRIX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "screen_matrix", "SCREEN_MATRIX" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "instance_custom", "INSTANCE_CUSTOM.rgb" }, diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 7b4d7e66d4..c34aca32dc 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -6805,29 +6805,29 @@ String VisualShaderNodeBillboard::generate_code(Shader::Mode p_mode, VisualShade switch (billboard_type) { case BILLBOARD_TYPE_ENABLED: code += " {\n"; - code += " mat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], CAMERA_MATRIX[1], CAMERA_MATRIX[2], WORLD_MATRIX[3]);\n"; + code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);\n"; if (keep_scale) { - code += " __mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } code += " " + p_output_vars[0] + " = __mvm;\n"; code += " }\n"; break; case BILLBOARD_TYPE_FIXED_Y: code += " {\n"; - code += " mat4 __mvm = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], WORLD_MATRIX[1], vec4(normalize(cross(CAMERA_MATRIX[0].xyz, WORLD_MATRIX[1].xyz)), 0.0), WORLD_MATRIX[3]);\n"; + code += " mat4 __mvm = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], MODEL_MATRIX[1], vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, MODEL_MATRIX[1].xyz)), 0.0), MODEL_MATRIX[3]);\n"; if (keep_scale) { - code += " __mvm = __mvm * mat4(vec4(length(WORLD_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(WORLD_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(length(MODEL_MATRIX[0].xyz), 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, length(MODEL_MATRIX[2].xyz), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } else { - code += " __mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(WORLD_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + code += " __mvm = __mvm * mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0 / length(MODEL_MATRIX[1].xyz), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } code += " " + p_output_vars[0] + " = __mvm;\n"; code += " }\n"; break; case BILLBOARD_TYPE_PARTICLES: code += " {\n"; - code += " mat4 __wm = mat4(normalize(CAMERA_MATRIX[0]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[1]) * length(WORLD_MATRIX[0]), normalize(CAMERA_MATRIX[2]) * length(WORLD_MATRIX[2]), WORLD_MATRIX[3]);\n"; + code += " mat4 __wm = mat4(normalize(INV_VIEW_MATRIX[0]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[1]) * length(MODEL_MATRIX[0]), normalize(INV_VIEW_MATRIX[2]) * length(MODEL_MATRIX[2]), MODEL_MATRIX[3]);\n"; code += " __wm = __wm * mat4(vec4(cos(INSTANCE_CUSTOM.x), -sin(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(sin(INSTANCE_CUSTOM.x), cos(INSTANCE_CUSTOM.x), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; - code += " " + p_output_vars[0] + " = INV_CAMERA_MATRIX * __wm;\n"; + code += " " + p_output_vars[0] + " = VIEW_MATRIX * __wm;\n"; code += " }\n"; break; default: |