summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/cpu_particles_2d.cpp10
-rw-r--r--scene/2d/cpu_particles_2d.h1
-rw-r--r--scene/3d/cpu_particles_3d.cpp12
-rw-r--r--scene/3d/cpu_particles_3d.h1
-rw-r--r--scene/3d/light_3d.cpp21
-rw-r--r--scene/3d/light_3d.h13
-rw-r--r--scene/animation/animation_blend_tree.cpp2
-rw-r--r--scene/animation/animation_tree.cpp96
-rw-r--r--scene/animation/animation_tree.h5
-rw-r--r--scene/gui/label.cpp6
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/option_button.cpp10
-rw-r--r--scene/gui/option_button.h2
-rw-r--r--scene/gui/rich_text_label.cpp130
-rw-r--r--scene/gui/rich_text_label.h13
-rw-r--r--scene/gui/tab_bar.h2
-rw-r--r--scene/main/canvas_item.cpp20
-rw-r--r--scene/main/canvas_item.h1
-rw-r--r--scene/resources/font.cpp14
-rw-r--r--scene/resources/font.h2
-rw-r--r--scene/resources/material.cpp24
-rw-r--r--scene/resources/particles_material.cpp15
-rw-r--r--scene/resources/particles_material.h1
-rw-r--r--scene/resources/text_line.cpp2
-rw-r--r--scene/resources/text_paragraph.cpp12
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--scene/resources/visual_shader.cpp34
-rw-r--r--scene/resources/visual_shader_nodes.cpp14
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: