summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/curve.cpp4
-rw-r--r--scene/resources/default_theme/default_theme.cpp11
-rw-r--r--scene/resources/default_theme/default_theme.h2
-rw-r--r--scene/resources/material.cpp37
-rw-r--r--scene/resources/material.h2
-rw-r--r--scene/resources/mesh.cpp35
-rw-r--r--scene/resources/mesh.h6
-rw-r--r--scene/resources/particles_material.cpp42
-rw-r--r--scene/resources/primitive_meshes.cpp39
-rw-r--r--scene/resources/primitive_meshes.h8
-rw-r--r--scene/resources/sky_material.cpp6
-rw-r--r--scene/resources/syntax_highlighter.cpp2
-rw-r--r--scene/resources/texture.cpp64
-rw-r--r--scene/resources/texture.h8
-rw-r--r--scene/resources/theme.cpp149
-rw-r--r--scene/resources/theme.h12
-rw-r--r--scene/resources/tile_set.cpp96
-rw-r--r--scene/resources/visual_shader.cpp44
-rw-r--r--scene/resources/visual_shader.h1
-rw-r--r--scene/resources/visual_shader_nodes.cpp92
-rw-r--r--scene/resources/visual_shader_nodes.h33
21 files changed, 549 insertions, 144 deletions
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 846da39221..53979e16df 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -286,7 +286,7 @@ void Curve::set_min_value(float p_min) {
}
// Note: min and max are indicative values,
// it's still possible that existing points are out of range at this point.
- emit_signal(SIGNAL_RANGE_CHANGED);
+ emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
void Curve::set_max_value(float p_max) {
@@ -296,7 +296,7 @@ void Curve::set_max_value(float p_max) {
_minmax_set_once |= 0b01; // second bit is "max set"
_max_value = p_max;
}
- emit_signal(SIGNAL_RANGE_CHANGED);
+ emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
real_t Curve::interpolate(real_t offset) const {
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 5464a46df4..1bbb84f43d 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -390,6 +390,15 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("shadow_outline_size", "Label", 1 * scale);
theme->set_constant("line_spacing", "Label", 3 * scale);
+ theme->set_type_variation("HeaderSmall", "Label");
+ theme->set_font_size("font_size", "HeaderSmall", default_font_size + 4);
+
+ theme->set_type_variation("HeaderMedium", "Label");
+ theme->set_font_size("font_size", "HeaderMedium", default_font_size + 8);
+
+ theme->set_type_variation("HeaderLarge", "Label");
+ theme->set_font_size("font_size", "HeaderLarge", default_font_size + 12);
+
// LineEdit
theme->set_stylebox("normal", "LineEdit", make_stylebox(line_edit_png, 5, 5, 5, 5));
@@ -984,7 +993,7 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
Ref<StyleBox> default_style;
Ref<Texture2D> default_icon;
Ref<Font> default_font;
- int default_font_size = 16;
+
if (p_font.is_valid()) {
// Use the custom font defined in the Project Settings.
default_font = p_font;
diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h
index a7b2bec5a4..4cd781e814 100644
--- a/scene/resources/default_theme/default_theme.h
+++ b/scene/resources/default_theme/default_theme.h
@@ -33,6 +33,8 @@
#include "scene/resources/theme.h"
+const int default_font_size = 16;
+
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale);
void make_default_theme(bool p_hidpi, Ref<Font> p_font);
void clear_default_theme();
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 4f7926d38d..a264c2d1eb 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -130,7 +130,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
}
if (pr) {
- RenderingServer::get_singleton()->material_set_param(_get_material(), pr, p_value);
+ set_shader_param(pr, p_value);
return true;
}
}
@@ -152,7 +152,12 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
if (pr) {
- r_ret = RenderingServer::get_singleton()->material_get_param(_get_material(), pr);
+ const Map<StringName, Variant>::Element *E = param_cache.find(pr);
+ if (E) {
+ r_ret = E->get();
+ } else {
+ r_ret = Variant();
+ }
return true;
}
}
@@ -219,11 +224,31 @@ Ref<Shader> ShaderMaterial::get_shader() const {
}
void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
- RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ if (p_value.get_type() == Variant::NIL) {
+ param_cache.erase(p_param);
+ RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
+ } else {
+ param_cache[p_param] = p_value;
+ if (p_value.get_type() == Variant::OBJECT) {
+ RID tex_rid = p_value;
+ if (tex_rid == RID()) {
+ param_cache.erase(p_param);
+ RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), p_param, tex_rid);
+ }
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ }
+ }
}
Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
- return RS::get_singleton()->material_get_param(_get_material(), p_param);
+ if (param_cache.has(p_param)) {
+ return param_cache[p_param];
+ } else {
+ return Variant();
+ }
}
void ShaderMaterial::_shader_changed() {
@@ -999,9 +1024,9 @@ void BaseMaterial3D::_update_shader() {
code += "\tSPECULAR = specular;\n";
} else {
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
+ code += "\tvec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
- code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n";
+ code += "\tvec4 orm_tex = texture(texture_orm,base_uv);\n";
}
code += "\tROUGHNESS = orm_tex.g;\n";
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 80e5e94466..e2838e1399 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -79,6 +79,8 @@ class ShaderMaterial : public Material {
GDCLASS(ShaderMaterial, Material);
Ref<Shader> shader;
+ Map<StringName, Variant> param_cache;
+
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index c5bfbc39db..2f92872ad5 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -30,6 +30,7 @@
#include "mesh.h"
+#include "core/math/convex_hull.h"
#include "core/templates/pair.h"
#include "scene/resources/concave_polygon_shape_3d.h"
#include "scene/resources/convex_polygon_shape_3d.h"
@@ -221,9 +222,17 @@ Vector<Face3> Mesh::get_faces() const {
*/
}
-Ref<Shape3D> Mesh::create_convex_shape() const {
- Vector<Vector3> vertices;
+Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const {
+ if (p_simplify) {
+ Vector<Ref<Shape3D>> decomposed = convex_decompose(1);
+ if (decomposed.size() == 1) {
+ return decomposed[0];
+ } else {
+ ERR_PRINT("Convex shape simplification failed, falling back to simpler process.");
+ }
+ }
+ Vector<Vector3> vertices;
for (int i = 0; i < get_surface_count(); i++) {
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>());
@@ -232,6 +241,18 @@ Ref<Shape3D> Mesh::create_convex_shape() const {
}
Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
+
+ if (p_clean) {
+ Geometry3D::MeshData md;
+ Error err = ConvexHullComputer::convex_hull(vertices, md);
+ if (err == OK) {
+ shape->set_points(md.vertices);
+ return shape;
+ } else {
+ ERR_PRINT("Convex shape cleaning failed, falling back to simpler process.");
+ }
+ }
+
shape->set_points(vertices);
return shape;
}
@@ -543,12 +564,12 @@ void Mesh::clear_cache() const {
debug_lines.clear();
}
-Vector<Ref<Shape3D>> Mesh::convex_decompose() const {
+Vector<Ref<Shape3D>> Mesh::convex_decompose(int p_max_convex_hulls) const {
ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
const Vector<Face3> faces = get_faces();
- Vector<Vector<Face3>> decomposed = convex_composition_function(faces);
+ Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_max_convex_hulls);
Vector<Ref<Shape3D>> ret;
@@ -1314,9 +1335,9 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < surfaces.size(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial", PROPERTY_USAGE_EDITOR));
} else {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_EDITOR));
}
}
}
@@ -1852,7 +1873,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape);
- ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape);
+ ClassDB::bind_method(D_METHOD("create_convex_shape", "clean", "simplify"), &ArrayMesh::create_convex_shape, DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline);
ClassDB::bind_method(D_METHOD("regen_normal_maps"), &ArrayMesh::regen_normal_maps);
ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 02cab9a5e1..27b0eb098b 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -149,7 +149,7 @@ public:
void generate_debug_mesh_indices(Vector<Vector3> &r_points);
Ref<Shape3D> create_trimesh_shape() const;
- Ref<Shape3D> create_convex_shape() const;
+ Ref<Shape3D> create_convex_shape(bool p_clean = true, bool p_simplify = false) const;
Ref<Mesh> create_outline(float p_margin) const;
@@ -159,11 +159,11 @@ public:
Size2i get_lightmap_size_hint() const;
void clear_cache() const;
- typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &);
+ typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, int p_max_convex_hulls);
static ConvexDecompositionFunc convex_composition_function;
- Vector<Ref<Shape3D>> convex_decompose() const;
+ Vector<Ref<Shape3D>> convex_decompose(int p_max_convex_hulls = -1) const;
virtual int get_builtin_bind_pose_count() const;
virtual Transform3D get_builtin_bind_pose(int p_index) const;
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index e95df31ccc..00bea312b3 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -569,7 +569,7 @@ void ParticlesMaterial::_update_shader() {
code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
if (color_ramp.is_valid()) {
- code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0);\n";
+ code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(tv, 0.0), 0.0) * color_value;\n";
} else {
code += " COLOR = hue_rot_mat * color_value;\n";
}
@@ -852,52 +852,54 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D
tex_parameters[p_param] = p_texture;
+ RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
//do none for this one
} break;
case PARAM_ANGULAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, tex_rid);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_ORBIT_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, tex_rid);
_adjust_curve_range(p_texture, -500, 500);
} break;
case PARAM_LINEAR_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_RADIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, tex_rid);
_adjust_curve_range(p_texture, -200, 200);
} break;
case PARAM_DAMPING: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 100);
} break;
case PARAM_ANGLE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, tex_rid);
_adjust_curve_range(p_texture, -360, 360);
} break;
case PARAM_SCALE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 1);
} break;
case PARAM_HUE_VARIATION: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, tex_rid);
_adjust_curve_range(p_texture, -1, 1);
} break;
case PARAM_ANIM_SPEED: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, tex_rid);
_adjust_curve_range(p_texture, 0, 200);
} break;
case PARAM_ANIM_OFFSET: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, tex_rid);
} break;
case PARAM_MAX:
break; // Can't happen, but silences warning
@@ -923,7 +925,8 @@ Color ParticlesMaterial::get_color() const {
void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
color_ramp = p_texture;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
+ RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, tex_rid);
_queue_shader_change();
notify_property_list_changed();
}
@@ -965,17 +968,20 @@ void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) {
emission_point_texture = p_points;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
+ RID tex_rid = p_points.is_valid() ? p_points->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, tex_rid);
}
void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) {
emission_normal_texture = p_normals;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
+ RID tex_rid = p_normals.is_valid() ? p_normals->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, tex_rid);
}
void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) {
emission_color_texture = p_colors;
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
+ RID tex_rid = p_colors.is_valid() ? p_colors->get_rid() : RID();
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, tex_rid);
_queue_shader_change();
}
@@ -1040,10 +1046,6 @@ RID ParticlesMaterial::get_shader_rid() const {
}
void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
- if (property.name == "color" && color_ramp.is_valid()) {
- property.usage = PROPERTY_USAGE_NONE;
- }
-
if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
property.usage = PROPERTY_USAGE_NONE;
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 2b2ebb5c16..dfa45cc810 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -207,7 +207,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
@@ -714,7 +714,7 @@ int BoxMesh::get_subdivide_depth() const {
BoxMesh::BoxMesh() {}
/**
- CylinderMesh
+ CylinderMesh
*/
void CylinderMesh::_create_mesh_array(Array &p_arr) const {
@@ -955,7 +955,7 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const {
u /= (subdivide_w + 1.0);
v /= (subdivide_d + 1.0);
- points.push_back(Vector3(-x, 0.0, -z));
+ points.push_back(Vector3(-x, 0.0, -z) + center_offset);
normals.push_back(Vector3(0.0, 1.0, 0.0));
ADD_TANGENT(1.0, 0.0, 0.0, 1.0);
uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */
@@ -993,10 +993,13 @@ void PlaneMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PlaneMesh::get_subdivide_width);
ClassDB::bind_method(D_METHOD("set_subdivide_depth", "subdivide"), &PlaneMesh::set_subdivide_depth);
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PlaneMesh::get_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("set_center_offset", "offset"), &PlaneMesh::set_center_offset);
+ ClassDB::bind_method(D_METHOD("get_center_offset"), &PlaneMesh::get_center_offset);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_offset"), "set_center_offset", "get_center_offset");
}
void PlaneMesh::set_size(const Size2 &p_size) {
@@ -1026,6 +1029,15 @@ int PlaneMesh::get_subdivide_depth() const {
return subdivide_d;
}
+void PlaneMesh::set_center_offset(const Vector3 p_offset) {
+ center_offset = p_offset;
+ _request_update();
+}
+
+Vector3 PlaneMesh::get_center_offset() const {
+ return center_offset;
+}
+
PlaneMesh::PlaneMesh() {}
/**
@@ -1326,10 +1338,10 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
Vector2 _size = Vector2(size.x / 2.0f, size.y / 2.0f);
Vector3 quad_faces[4] = {
- Vector3(-_size.x, -_size.y, 0),
- Vector3(-_size.x, _size.y, 0),
- Vector3(_size.x, _size.y, 0),
- Vector3(_size.x, -_size.y, 0),
+ Vector3(-_size.x, -_size.y, 0) + center_offset,
+ Vector3(-_size.x, _size.y, 0) + center_offset,
+ Vector3(_size.x, _size.y, 0) + center_offset,
+ Vector3(_size.x, -_size.y, 0) + center_offset,
};
static const int indices[6] = {
@@ -1365,7 +1377,11 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
void QuadMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &QuadMesh::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &QuadMesh::get_size);
+ ClassDB::bind_method(D_METHOD("set_center_offset", "center_offset"), &QuadMesh::set_center_offset);
+ ClassDB::bind_method(D_METHOD("get_center_offset"), &QuadMesh::get_center_offset);
+
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_offset"), "set_center_offset", "get_center_offset");
}
QuadMesh::QuadMesh() {
@@ -1381,6 +1397,15 @@ Size2 QuadMesh::get_size() const {
return size;
}
+void QuadMesh::set_center_offset(Vector3 p_center_offset) {
+ center_offset = p_center_offset;
+ _request_update();
+}
+
+Vector3 QuadMesh::get_center_offset() const {
+ return center_offset;
+}
+
/**
SphereMesh
*/
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index bd6f94921e..a3de34d3e3 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -211,6 +211,7 @@ private:
Size2 size = Size2(2.0, 2.0);
int subdivide_w = 0;
int subdivide_d = 0;
+ Vector3 center_offset;
protected:
static void _bind_methods();
@@ -226,6 +227,9 @@ public:
void set_subdivide_depth(const int p_divisions);
int get_subdivide_depth() const;
+ void set_center_offset(const Vector3 p_offset);
+ Vector3 get_center_offset() const;
+
PlaneMesh();
};
@@ -274,6 +278,7 @@ class QuadMesh : public PrimitiveMesh {
private:
Size2 size = Size2(1.0, 1.0);
+ Vector3 center_offset;
protected:
static void _bind_methods();
@@ -284,6 +289,9 @@ public:
void set_size(const Size2 &p_size);
Size2 get_size() const;
+
+ void set_center_offset(const Vector3 p_offset);
+ Vector3 get_center_offset() const;
};
/**
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 9d79c22159..89b3336118 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -270,7 +270,8 @@ ProceduralSkyMaterial::~ProceduralSkyMaterial() {
void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
panorama = p_panorama;
- RS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
+ RID tex_rid = p_panorama.is_valid() ? p_panorama->get_rid() : RID();
+ RS::get_singleton()->material_set_param(_get_material(), "source_panorama", tex_rid);
}
Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
@@ -411,7 +412,8 @@ float PhysicalSkyMaterial::get_dither_strength() const {
void PhysicalSkyMaterial::set_night_sky(const Ref<Texture2D> &p_night_sky) {
night_sky = p_night_sky;
- RS::get_singleton()->material_set_param(_get_material(), "night_sky", night_sky);
+ RID tex_rid = p_night_sky.is_valid() ? p_night_sky->get_rid() : RID();
+ RS::get_singleton()->material_set_param(_get_material(), "night_sky", tex_rid);
}
Ref<Texture2D> PhysicalSkyMaterial::get_night_sky() const {
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 9dd00849f4..bf889d7a1c 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -405,7 +405,7 @@ void CodeHighlighter::_clear_highlighting_cache() {
}
void CodeHighlighter::_update_cache() {
- font_color = text_edit->get_theme_color("font_color");
+ font_color = text_edit->get_theme_color(SNAME("font_color"));
}
void CodeHighlighter::add_keyword_color(const String &p_keyword, const Color &p_color) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d09a1d9f90..38042d84fd 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1412,7 +1412,7 @@ void CurveTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &CurveTexture::_update);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "RGB,Red"), "set_texture_mode", "get_texture_mode");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
@@ -1545,27 +1545,27 @@ CurveTexture::~CurveTexture() {
//////////////////
-void Curve3Texture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_width", "width"), &Curve3Texture::set_width);
+void CurveXYZTexture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveXYZTexture::set_width);
- ClassDB::bind_method(D_METHOD("set_curve_x", "curve"), &Curve3Texture::set_curve_x);
- ClassDB::bind_method(D_METHOD("get_curve_x"), &Curve3Texture::get_curve_x);
+ ClassDB::bind_method(D_METHOD("set_curve_x", "curve"), &CurveXYZTexture::set_curve_x);
+ ClassDB::bind_method(D_METHOD("get_curve_x"), &CurveXYZTexture::get_curve_x);
- ClassDB::bind_method(D_METHOD("set_curve_y", "curve"), &Curve3Texture::set_curve_y);
- ClassDB::bind_method(D_METHOD("get_curve_y"), &Curve3Texture::get_curve_y);
+ ClassDB::bind_method(D_METHOD("set_curve_y", "curve"), &CurveXYZTexture::set_curve_y);
+ ClassDB::bind_method(D_METHOD("get_curve_y"), &CurveXYZTexture::get_curve_y);
- ClassDB::bind_method(D_METHOD("set_curve_z", "curve"), &Curve3Texture::set_curve_z);
- ClassDB::bind_method(D_METHOD("get_curve_z"), &Curve3Texture::get_curve_z);
+ ClassDB::bind_method(D_METHOD("set_curve_z", "curve"), &CurveXYZTexture::set_curve_z);
+ ClassDB::bind_method(D_METHOD("get_curve_z"), &CurveXYZTexture::get_curve_z);
- ClassDB::bind_method(D_METHOD("_update"), &Curve3Texture::_update);
+ ClassDB::bind_method(D_METHOD("_update"), &CurveXYZTexture::_update);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_x", "get_curve_x");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_y", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_y", "get_curve_y");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_z", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_z", "get_curve_z");
}
-void Curve3Texture::set_width(int p_width) {
+void CurveXYZTexture::set_width(int p_width) {
ERR_FAIL_COND(p_width < 32 || p_width > 4096);
if (_width == p_width) {
@@ -1576,11 +1576,11 @@ void Curve3Texture::set_width(int p_width) {
_update();
}
-int Curve3Texture::get_width() const {
+int CurveXYZTexture::get_width() const {
return _width;
}
-void Curve3Texture::ensure_default_setup(float p_min, float p_max) {
+void CurveXYZTexture::ensure_default_setup(float p_min, float p_max) {
if (_curve_x.is_null()) {
Ref<Curve> curve = Ref<Curve>(memnew(Curve));
curve->add_point(Vector2(0, 1));
@@ -1609,46 +1609,46 @@ void Curve3Texture::ensure_default_setup(float p_min, float p_max) {
}
}
-void Curve3Texture::set_curve_x(Ref<Curve> p_curve) {
+void CurveXYZTexture::set_curve_x(Ref<Curve> p_curve) {
if (_curve_x != p_curve) {
if (_curve_x.is_valid()) {
- _curve_x->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update));
+ _curve_x->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
}
_curve_x = p_curve;
if (_curve_x.is_valid()) {
- _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED);
+ _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED);
}
_update();
}
}
-void Curve3Texture::set_curve_y(Ref<Curve> p_curve) {
+void CurveXYZTexture::set_curve_y(Ref<Curve> p_curve) {
if (_curve_y != p_curve) {
if (_curve_y.is_valid()) {
- _curve_y->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update));
+ _curve_y->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
}
_curve_y = p_curve;
if (_curve_y.is_valid()) {
- _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED);
+ _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED);
}
_update();
}
}
-void Curve3Texture::set_curve_z(Ref<Curve> p_curve) {
+void CurveXYZTexture::set_curve_z(Ref<Curve> p_curve) {
if (_curve_z != p_curve) {
if (_curve_z.is_valid()) {
- _curve_z->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update));
+ _curve_z->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
}
_curve_z = p_curve;
if (_curve_z.is_valid()) {
- _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Curve3Texture::_update), varray(), CONNECT_REFERENCE_COUNTED);
+ _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), varray(), CONNECT_REFERENCE_COUNTED);
}
_update();
}
}
-void Curve3Texture::_update() {
+void CurveXYZTexture::_update() {
Vector<uint8_t> data;
data.resize(_width * sizeof(float) * 3);
@@ -1714,28 +1714,28 @@ void Curve3Texture::_update() {
emit_changed();
}
-Ref<Curve> Curve3Texture::get_curve_x() const {
+Ref<Curve> CurveXYZTexture::get_curve_x() const {
return _curve_x;
}
-Ref<Curve> Curve3Texture::get_curve_y() const {
+Ref<Curve> CurveXYZTexture::get_curve_y() const {
return _curve_y;
}
-Ref<Curve> Curve3Texture::get_curve_z() const {
+Ref<Curve> CurveXYZTexture::get_curve_z() const {
return _curve_z;
}
-RID Curve3Texture::get_rid() const {
+RID CurveXYZTexture::get_rid() const {
if (!_texture.is_valid()) {
_texture = RS::get_singleton()->texture_2d_placeholder_create();
}
return _texture;
}
-Curve3Texture::Curve3Texture() {}
+CurveXYZTexture::CurveXYZTexture() {}
-Curve3Texture::~Curve3Texture() {
+CurveXYZTexture::~CurveXYZTexture() {
if (_texture.is_valid()) {
RS::get_singleton()->free(_texture);
}
@@ -1762,7 +1762,7 @@ void GradientTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
@@ -1790,7 +1790,7 @@ void GradientTexture::_queue_update() {
}
update_pending = true;
- call_deferred("_update");
+ call_deferred(SNAME("_update"));
}
void GradientTexture::_update() {
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 73390039cb..98aa61138d 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -628,8 +628,8 @@ public:
VARIANT_ENUM_CAST(CurveTexture::TextureMode)
-class Curve3Texture : public Texture2D {
- GDCLASS(Curve3Texture, Texture2D);
+class CurveXYZTexture : public Texture2D {
+ GDCLASS(CurveXYZTexture, Texture2D);
RES_BASE_EXTENSION("curvetex")
private:
@@ -665,8 +665,8 @@ public:
virtual int get_height() const override { return 1; }
virtual bool has_alpha() const override { return false; }
- Curve3Texture();
- ~Curve3Texture();
+ CurveXYZTexture();
+ ~CurveXYZTexture();
};
class GradientTexture : public Texture2D {
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 89ac033207..303bbf38f4 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -263,6 +263,21 @@ Vector<String> Theme::_get_theme_item_type_list(DataType p_data_type) const {
return Vector<String>();
}
+Vector<String> Theme::_get_type_variation_list(const StringName &p_theme_type) const {
+ Vector<String> ilret;
+ List<StringName> il;
+
+ get_type_variation_list(p_theme_type, &il);
+ ilret.resize(il.size());
+
+ int i = 0;
+ String *w = ilret.ptrw();
+ for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
+ w[i] = E->get();
+ }
+ return ilret;
+}
+
Vector<String> Theme::_get_type_list() const {
Vector<String> ilret;
List<StringName> il;
@@ -292,10 +307,14 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
set_stylebox(name, theme_type, p_value);
} else if (type == "fonts") {
set_font(name, theme_type, p_value);
+ } else if (type == "font_sizes") {
+ set_font_size(name, theme_type, p_value);
} else if (type == "colors") {
set_color(name, theme_type, p_value);
} else if (type == "constants") {
set_constant(name, theme_type, p_value);
+ } else if (type == "base_type") {
+ set_type_variation(theme_type, p_value);
} else {
return false;
}
@@ -332,10 +351,14 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
} else {
r_ret = get_font(name, theme_type);
}
+ } else if (type == "font_sizes") {
+ r_ret = get_font_size(name, theme_type);
} else if (type == "colors") {
r_ret = get_color(name, theme_type);
} else if (type == "constants") {
r_ret = get_constant(name, theme_type);
+ } else if (type == "base_type") {
+ r_ret = get_type_variation_base(theme_type);
} else {
return false;
}
@@ -351,6 +374,14 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
const StringName *key = nullptr;
+ // Type variations.
+ while ((key = variation_map.next(key))) {
+ list.push_back(PropertyInfo(Variant::STRING_NAME, String() + *key + "/base_type"));
+ }
+
+ key = nullptr;
+
+ // Icons.
while ((key = icon_map.next(key))) {
const StringName *key2 = nullptr;
@@ -361,6 +392,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Styles.
while ((key = style_map.next(key))) {
const StringName *key2 = nullptr;
@@ -371,6 +403,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Fonts.
while ((key = font_map.next(key))) {
const StringName *key2 = nullptr;
@@ -381,6 +414,18 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Font sizes.
+ while ((key = font_size_map.next(key))) {
+ const StringName *key2 = nullptr;
+
+ while ((key2 = font_size_map[*key].next(key2))) {
+ list.push_back(PropertyInfo(Variant::INT, String() + *key + "/font_sizes/" + *key2));
+ }
+ }
+
+ key = nullptr;
+
+ // Colors.
while ((key = color_map.next(key))) {
const StringName *key2 = nullptr;
@@ -391,6 +436,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
+ // Constants.
while ((key = constant_map.next(key))) {
const StringName *key2 = nullptr;
@@ -399,6 +445,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
+ // Sort and store properties.
list.sort();
for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) {
p_list->push_back(E->get());
@@ -1183,6 +1230,63 @@ void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_l
}
}
+void Theme::set_type_variation(const StringName &p_theme_type, const StringName &p_base_type) {
+ ERR_FAIL_COND_MSG(p_theme_type == StringName(), "An empty theme type cannot be marked as a variation of another type.");
+ ERR_FAIL_COND_MSG(ClassDB::class_exists(p_theme_type), "A type associated with a built-in class cannot be marked as a variation of another type.");
+ ERR_FAIL_COND_MSG(p_base_type == StringName(), "An empty theme type cannot be the base type of a variation. Use clear_type_variation() instead if you want to unmark '" + String(p_theme_type) + "' as a variation.");
+
+ if (variation_map.has(p_theme_type)) {
+ StringName old_base = variation_map[p_theme_type];
+ variation_base_map[old_base].erase(p_theme_type);
+ }
+
+ variation_map[p_theme_type] = p_base_type;
+ variation_base_map[p_base_type].push_back(p_theme_type);
+
+ _emit_theme_changed();
+}
+
+bool Theme::is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const {
+ return (variation_map.has(p_theme_type) && variation_map[p_theme_type] == p_base_type);
+}
+
+void Theme::clear_type_variation(const StringName &p_theme_type) {
+ ERR_FAIL_COND_MSG(!variation_map.has(p_theme_type), "Cannot clear the type variation '" + String(p_theme_type) + "' because it does not exist.");
+
+ StringName base_type = variation_map[p_theme_type];
+ variation_base_map[base_type].erase(p_theme_type);
+ variation_map.erase(p_theme_type);
+
+ _emit_theme_changed();
+}
+
+StringName Theme::get_type_variation_base(const StringName &p_theme_type) const {
+ if (!variation_map.has(p_theme_type)) {
+ return StringName();
+ }
+
+ return variation_map[p_theme_type];
+}
+
+void Theme::get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const {
+ ERR_FAIL_NULL(p_list);
+
+ if (!variation_base_map.has(p_base_type)) {
+ return;
+ }
+
+ for (const List<StringName>::Element *E = variation_base_map[p_base_type].front(); E; E = E->next()) {
+ // Prevent infinite loops if variants were set to be cross-dependent (that's still invalid usage, but handling for stability sake).
+ if (p_list->find(E->get())) {
+ continue;
+ }
+
+ p_list->push_back(E->get());
+ // Continue looking for sub-variations.
+ get_type_variation_list(E->get(), p_list);
+ }
+}
+
void Theme::_freeze_change_propagation() {
no_change_propagation = true;
}
@@ -1236,9 +1340,13 @@ void Theme::clear() {
icon_map.clear();
style_map.clear();
font_map.clear();
+ font_size_map.clear();
color_map.clear();
constant_map.clear();
+ variation_map.clear();
+ variation_base_map.clear();
+
_emit_theme_changed();
}
@@ -1291,6 +1399,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
color_map = p_other->color_map;
constant_map = p_other->constant_map;
+ variation_map = p_other->variation_map;
+ variation_base_map = p_other->variation_base_map;
+
_unfreeze_and_propagate_changes();
}
@@ -1300,30 +1411,42 @@ void Theme::get_type_list(List<StringName> *p_list) const {
Set<StringName> types;
const StringName *key = nullptr;
+ // Icons.
while ((key = icon_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // StyleBoxes.
while ((key = style_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Fonts.
while ((key = font_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Font sizes.
+ while ((key = font_size_map.next(key))) {
+ types.insert(*key);
+ }
+
+ key = nullptr;
+
+ // Colors.
while ((key = color_map.next(key))) {
types.insert(*key);
}
key = nullptr;
+ // Constants.
while ((key = constant_map.next(key))) {
types.insert(*key);
}
@@ -1333,10 +1456,25 @@ void Theme::get_type_list(List<StringName> *p_list) const {
}
}
-void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) {
+void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) {
ERR_FAIL_NULL(p_list);
- StringName class_name = p_theme_type;
+ // Build the dependency chain for type variations.
+ if (p_type_variation != StringName()) {
+ StringName variation_name = p_type_variation;
+ while (variation_name != StringName()) {
+ p_list->push_back(variation_name);
+ variation_name = get_type_variation_base(variation_name);
+
+ // If we have reached the base type dependency, it's safe to stop (assuming no funny business was done to the Theme).
+ if (variation_name == p_base_type) {
+ break;
+ }
+ }
+ }
+
+ // Continue building the chain using native class hierarchy.
+ StringName class_name = p_base_type;
while (class_name != StringName()) {
p_list->push_back(class_name);
class_name = ClassDB::get_parent_class_nocheck(class_name);
@@ -1346,6 +1484,7 @@ void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringNam
void Theme::reset_state() {
clear();
}
+
void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_icon", "name", "theme_type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "theme_type"), &Theme::get_icon);
@@ -1411,6 +1550,12 @@ void Theme::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "theme_type"), &Theme::_get_theme_item_list);
ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list);
+ ClassDB::bind_method(D_METHOD("set_type_variation", "theme_type", "base_type"), &Theme::set_type_variation);
+ ClassDB::bind_method(D_METHOD("is_type_variation", "theme_type", "base_type"), &Theme::is_type_variation);
+ ClassDB::bind_method(D_METHOD("clear_type_variation", "theme_type"), &Theme::clear_type_variation);
+ ClassDB::bind_method(D_METHOD("get_type_variation_base", "theme_type"), &Theme::get_type_variation_base);
+ ClassDB::bind_method(D_METHOD("get_type_variation_list", "base_type"), &Theme::_get_type_variation_list);
+
ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list);
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index fe64fd7290..8a8fc28be1 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -69,6 +69,8 @@ private:
HashMap<StringName, HashMap<StringName, int>> font_size_map;
HashMap<StringName, HashMap<StringName, Color>> color_map;
HashMap<StringName, HashMap<StringName, int>> constant_map;
+ HashMap<StringName, StringName> variation_map;
+ HashMap<StringName, List<StringName>> variation_base_map;
Vector<String> _get_icon_list(const String &p_theme_type) const;
Vector<String> _get_icon_type_list() const;
@@ -85,6 +87,8 @@ private:
Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_theme_type) const;
Vector<String> _get_theme_item_type_list(DataType p_data_type) const;
+
+ Vector<String> _get_type_variation_list(const StringName &p_theme_type) const;
Vector<String> _get_type_list() const;
protected:
@@ -197,8 +201,14 @@ public:
void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type);
void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const;
+ void set_type_variation(const StringName &p_theme_type, const StringName &p_base_type);
+ bool is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const;
+ void clear_type_variation(const StringName &p_theme_type);
+ StringName get_type_variation_base(const StringName &p_theme_type) const;
+ void get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const;
+
void get_type_list(List<StringName> *p_list) const;
- static void get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list);
+ void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, List<StringName> *p_list);
void copy_default_theme();
void copy_theme(const Ref<Theme> &p_other);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 4f854ff229..deb5a50eb2 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -2245,22 +2245,22 @@ void TileSet::_bind_methods() {
BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_HORIZONTAL);
BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_VERTICAL);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_CORNER);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
- BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_CORNER);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_SIDE);
+ BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_CORNER);
BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS_AND_SIDES);
BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS);
@@ -2569,7 +2569,7 @@ void TileSetAtlasSource::create_tile(const Vector2i p_atlas_coords, const Vector
}
}
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileSetAtlasSource::remove_tile(Vector2i p_atlas_coords) {
@@ -2595,7 +2595,7 @@ void TileSetAtlasSource::remove_tile(Vector2i p_atlas_coords) {
tiles_ids.erase(p_atlas_coords);
tiles_ids.sort();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileSetAtlasSource::has_tile(Vector2i p_atlas_coords) const {
@@ -2723,7 +2723,7 @@ void TileSetAtlasSource::move_tile_in_atlas(Vector2i p_atlas_coords, Vector2i p_
}
}
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileSetAtlasSource::has_tiles_outside_texture() {
@@ -2768,7 +2768,7 @@ int TileSetAtlasSource::create_alternative_tile(const Vector2i p_atlas_coords, i
tiles[p_atlas_coords].alternatives_ids.sort();
_compute_next_alternative_id(p_atlas_coords);
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
return new_alternative_id;
}
@@ -2783,7 +2783,7 @@ void TileSetAtlasSource::remove_alternative_tile(const Vector2i p_atlas_coords,
tiles[p_atlas_coords].alternatives_ids.erase(p_alternative_tile);
tiles[p_atlas_coords].alternatives_ids.sort();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileSetAtlasSource::set_alternative_tile_id(const Vector2i p_atlas_coords, int p_alternative_tile, int p_new_id) {
@@ -2800,7 +2800,7 @@ void TileSetAtlasSource::set_alternative_tile_id(const Vector2i p_atlas_coords,
tiles[p_atlas_coords].alternatives_ids.erase(p_alternative_tile);
tiles[p_atlas_coords].alternatives_ids.sort();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileSetAtlasSource::has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const {
@@ -2958,7 +2958,7 @@ int TileSetScenesCollectionSource::create_scene_tile(Ref<PackedScene> p_packed_s
set_scene_tile_scene(new_scene_id, p_packed_scene);
_compute_next_alternative_id();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
return new_scene_id;
}
@@ -2978,7 +2978,7 @@ void TileSetScenesCollectionSource::set_scene_tile_id(int p_id, int p_new_id) {
scenes.erase(p_id);
scenes_ids.erase(p_id);
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileSetScenesCollectionSource::set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene) {
@@ -2997,7 +2997,7 @@ void TileSetScenesCollectionSource::set_scene_tile_scene(int p_id, Ref<PackedSce
} else {
scenes[p_id].scene = Ref<PackedScene>();
}
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Ref<PackedScene> TileSetScenesCollectionSource::get_scene_tile_scene(int p_id) const {
@@ -3010,7 +3010,7 @@ void TileSetScenesCollectionSource::set_scene_tile_display_placeholder(int p_id,
scenes[p_id].display_placeholder = p_display_placeholder;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileSetScenesCollectionSource::get_scene_tile_display_placeholder(int p_id) const {
@@ -3023,7 +3023,7 @@ void TileSetScenesCollectionSource::remove_scene_tile(int p_id) {
scenes.erase(p_id);
scenes_ids.erase(p_id);
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
int TileSetScenesCollectionSource::get_next_scene_tile_id() const {
@@ -3144,7 +3144,7 @@ void TileData::notify_tile_data_properties_should_change() {
}
notify_property_list_changed();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileData::reset_state() {
@@ -3166,7 +3166,7 @@ bool TileData::is_allowing_transform() const {
void TileData::set_flip_h(bool p_flip_h) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_h, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_h = p_flip_h;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileData::get_flip_h() const {
return flip_h;
@@ -3175,7 +3175,7 @@ bool TileData::get_flip_h() const {
void TileData::set_flip_v(bool p_flip_v) {
ERR_FAIL_COND_MSG(!allow_transform && p_flip_v, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
flip_v = p_flip_v;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileData::get_flip_v() const {
@@ -3185,7 +3185,7 @@ bool TileData::get_flip_v() const {
void TileData::set_transpose(bool p_transpose) {
ERR_FAIL_COND_MSG(!allow_transform && p_transpose, "Transform is only allowed for alternative tiles (with its alternative_id != 0)");
transpose = p_transpose;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileData::get_transpose() const {
return transpose;
@@ -3193,7 +3193,7 @@ bool TileData::get_transpose() const {
void TileData::set_texture_offset(Vector2i p_texture_offset) {
tex_offset = p_texture_offset;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Vector2i TileData::get_texture_offset() const {
@@ -3202,7 +3202,7 @@ Vector2i TileData::get_texture_offset() const {
void TileData::tile_set_material(Ref<ShaderMaterial> p_material) {
material = p_material;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Ref<ShaderMaterial> TileData::tile_get_material() const {
return material;
@@ -3210,7 +3210,7 @@ Ref<ShaderMaterial> TileData::tile_get_material() const {
void TileData::set_modulate(Color p_modulate) {
modulate = p_modulate;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Color TileData::get_modulate() const {
return modulate;
@@ -3218,7 +3218,7 @@ Color TileData::get_modulate() const {
void TileData::set_z_index(int p_z_index) {
z_index = p_z_index;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
int TileData::get_z_index() const {
return z_index;
@@ -3226,7 +3226,7 @@ int TileData::get_z_index() const {
void TileData::set_y_sort_origin(int p_y_sort_origin) {
y_sort_origin = p_y_sort_origin;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
int TileData::get_y_sort_origin() const {
return y_sort_origin;
@@ -3235,7 +3235,7 @@ int TileData::get_y_sort_origin() const {
void TileData::set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon) {
ERR_FAIL_INDEX(p_layer_id, occluders.size());
occluders.write[p_layer_id] = p_occluder_polygon;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id) const {
@@ -3254,20 +3254,20 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count
ERR_FAIL_COND(p_polygons_count < 0);
physics.write[p_layer_id].polygons.resize(p_polygons_count);
notify_property_list_changed();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileData::add_collision_polygon(int p_layer_id) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData());
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileData::remove_collision_polygon(int p_layer_id, int p_polygon_index) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.remove(p_polygon_index);
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon) {
@@ -3291,7 +3291,7 @@ void TileData::set_collision_polygon_points(int p_layer_id, int p_polygon_index,
}
}
physics.write[p_layer_id].polygons.write[p_polygon_index].polygon = p_polygon;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Vector<Vector2> TileData::get_collision_polygon_points(int p_layer_id, int p_polygon_index) const {
@@ -3304,7 +3304,7 @@ void TileData::set_collision_polygon_one_way(int p_layer_id, int p_polygon_index
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way = p_one_way;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
bool TileData::is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const {
@@ -3317,7 +3317,7 @@ void TileData::set_collision_polygon_one_way_margin(int p_layer_id, int p_polygo
ERR_FAIL_INDEX(p_layer_id, physics.size());
ERR_FAIL_INDEX(p_polygon_index, physics[p_layer_id].polygons.size());
physics.write[p_layer_id].polygons.write[p_polygon_index].one_way_margin = p_one_way_margin;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
float TileData::get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const {
@@ -3353,7 +3353,7 @@ void TileData::set_terrain_set(int p_terrain_set) {
}
terrain_set = p_terrain_set;
notify_property_list_changed();
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
int TileData::get_terrain_set() const {
@@ -3368,7 +3368,7 @@ void TileData::set_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit, int
ERR_FAIL_COND(!is_valid_peering_bit_terrain(p_peering_bit));
}
terrain_peering_bits[p_peering_bit] = p_terrain_index;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
int TileData::get_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit) const {
@@ -3386,7 +3386,7 @@ bool TileData::is_valid_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit)
void TileData::set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon) {
ERR_FAIL_INDEX(p_layer_id, navigation.size());
navigation.write[p_layer_id] = p_navigation_polygon;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id) const {
@@ -3398,7 +3398,7 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id) const {
void TileData::set_probability(float p_probability) {
ERR_FAIL_COND(p_probability < 0.0);
probability = p_probability;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
float TileData::get_probability() const {
return probability;
@@ -3422,7 +3422,7 @@ Variant TileData::get_custom_data(String p_layer_name) const {
void TileData::set_custom_data_by_layer_id(int p_layer_id, Variant p_value) {
ERR_FAIL_INDEX(p_layer_id, custom_data.size());
custom_data.write[p_layer_id] = p_value;
- emit_signal("changed");
+ emit_signal(SNAME("changed"));
}
Variant TileData::get_custom_data_by_layer_id(int p_layer_id) const {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 54bc7382db..ae09872171 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1752,6 +1752,11 @@ void VisualShader::_update_shader() const {
StringBuilder func_code;
+ bool is_empty_func = false;
+ if (shader_mode != Shader::MODE_PARTICLES && shader_mode != Shader::MODE_SKY) {
+ is_empty_func = true;
+ }
+
for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
ConnectionKey from_key;
from_key.node = E->get().from_node;
@@ -1764,7 +1769,16 @@ void VisualShader::_update_shader() const {
to_key.port = E->get().to_port;
input_connections.insert(to_key, E);
+
+ if (is_empty_func && to_key.node == NODE_ID_OUTPUT) {
+ is_empty_func = false;
+ }
}
+
+ if (is_empty_func) {
+ continue;
+ }
+
if (shader_mode != Shader::MODE_PARTICLES) {
func_code += "\nvoid " + String(func_name[i]) + "() {\n";
}
@@ -1929,7 +1943,7 @@ void VisualShader::_update_shader() const {
const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param);
}
if (previous_code != final_code) {
- const_cast<VisualShader *>(this)->emit_signal("changed");
+ const_cast<VisualShader *>(this)->emit_signal(SNAME("changed"));
}
previous_code = final_code;
}
@@ -1940,7 +1954,7 @@ void VisualShader::_queue_update() {
}
dirty.set();
- call_deferred("_update_shader");
+ call_deferred(SNAME("_update_shader"));
}
void VisualShader::_input_type_changed(Type p_type, int p_id) {
@@ -2422,7 +2436,7 @@ void VisualShaderNodeInput::set_input_name(String p_name) {
input_name = p_name;
emit_changed();
if (get_input_type_by_name(input_name) != prev_type) {
- emit_signal("input_type_changed");
+ emit_signal(SNAME("input_type_changed"));
}
}
@@ -2708,6 +2722,28 @@ VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_
return UniformType::UNIFORM_TYPE_FLOAT;
}
+VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_by_index(int p_idx) const {
+ if (p_idx >= 0 && p_idx < uniforms.size()) {
+ switch (uniforms[p_idx].type) {
+ case UniformType::UNIFORM_TYPE_FLOAT:
+ return PORT_TYPE_SCALAR;
+ case UniformType::UNIFORM_TYPE_INT:
+ return PORT_TYPE_SCALAR_INT;
+ case UniformType::UNIFORM_TYPE_SAMPLER:
+ return PORT_TYPE_SAMPLER;
+ case UniformType::UNIFORM_TYPE_VECTOR:
+ return PORT_TYPE_VECTOR;
+ case UniformType::UNIFORM_TYPE_TRANSFORM:
+ return PORT_TYPE_TRANSFORM;
+ case UniformType::UNIFORM_TYPE_COLOR:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ }
+ return PORT_TYPE_SCALAR;
+}
+
String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
switch (uniform_type) {
case UniformType::UNIFORM_TYPE_FLOAT:
@@ -2941,7 +2977,7 @@ VisualShaderNodeOutput::VisualShaderNodeOutput() {
void VisualShaderNodeUniform::set_uniform_name(const String &p_name) {
uniform_name = p_name;
- emit_signal("name_changed");
+ emit_signal(SNAME("name_changed"));
emit_changed();
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 454012b7ed..880c401b29 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -517,6 +517,7 @@ public:
String get_uniform_name_by_index(int p_idx) const;
UniformType get_uniform_type_by_name(const String &p_name) const;
UniformType get_uniform_type_by_index(int p_idx) const;
+ PortType get_port_type_by_index(int p_idx) const;
virtual Vector<StringName> get_editable_properties() const override;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index d3b094de31..c090ce78ee 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -707,7 +707,7 @@ void VisualShaderNodeTexture::set_source(Source p_source) {
break;
}
emit_changed();
- emit_signal("editor_refresh_request");
+ emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
@@ -805,7 +805,7 @@ void VisualShaderNodeTexture::_bind_methods() {
VisualShaderNodeTexture::VisualShaderNodeTexture() {
}
-////////////// Curve
+////////////// CurveTexture
String VisualShaderNodeCurveTexture::get_caption() const {
return "CurveTexture";
@@ -889,6 +889,90 @@ VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() {
allow_v_resize = false;
}
+////////////// CurveXYZTexture
+
+String VisualShaderNodeCurveXYZTexture::get_caption() const {
+ return "CurveXYZTexture";
+}
+
+int VisualShaderNodeCurveXYZTexture::get_input_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_input_port_type(int p_port) const {
+ return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeCurveXYZTexture::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeCurveXYZTexture::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeCurveXYZTexture::get_output_port_name(int p_port) const {
+ return String();
+}
+
+void VisualShaderNodeCurveXYZTexture::set_texture(Ref<CurveXYZTexture> p_texture) {
+ texture = p_texture;
+ emit_changed();
+}
+
+Ref<CurveXYZTexture> VisualShaderNodeCurveXYZTexture::get_texture() const {
+ return texture;
+}
+
+Vector<StringName> VisualShaderNodeCurveXYZTexture::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("texture");
+ return props;
+}
+
+String VisualShaderNodeCurveXYZTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ return "uniform sampler2D " + make_unique_id(p_type, p_id, "curve3d") + ";\n";
+}
+
+String VisualShaderNodeCurveXYZTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ if (p_input_vars[0] == String()) {
+ return "\t" + p_output_vars[0] + " = vec3(0.0);\n";
+ }
+ String id = make_unique_id(p_type, p_id, "curve3d");
+ String code;
+ code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ")).rgb;\n";
+ return code;
+}
+
+Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveXYZTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+ VisualShader::DefaultTextureParam dtp;
+ dtp.name = make_unique_id(p_type, p_id, "curve3d");
+ dtp.param = texture;
+ Vector<VisualShader::DefaultTextureParam> ret;
+ ret.push_back(dtp);
+ return ret;
+}
+
+void VisualShaderNodeCurveXYZTexture::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurveXYZTexture::set_texture);
+ ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurveXYZTexture::get_texture);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_texture", "get_texture");
+}
+
+bool VisualShaderNodeCurveXYZTexture::is_use_prop_slots() const {
+ return true;
+}
+
+VisualShaderNodeCurveXYZTexture::VisualShaderNodeCurveXYZTexture() {
+ simple_decl = true;
+ allow_v_resize = false;
+}
+
////////////// Sample3D
int VisualShaderNodeSample3D::get_input_port_count() const {
@@ -992,7 +1076,7 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader
void VisualShaderNodeSample3D::set_source(Source p_source) {
source = p_source;
emit_changed();
- emit_signal("editor_refresh_request");
+ emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeSample3D::Source VisualShaderNodeSample3D::get_source() const {
@@ -1282,7 +1366,7 @@ String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const {
void VisualShaderNodeCubemap::set_source(Source p_source) {
source = p_source;
emit_changed();
- emit_signal("editor_refresh_request");
+ emit_signal(SNAME("editor_refresh_request"));
}
VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 5b44e9f776..33a45a4384 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -338,6 +338,39 @@ public:
///////////////////////////////////////
+class VisualShaderNodeCurveXYZTexture : public VisualShaderNodeResizableBase {
+ GDCLASS(VisualShaderNodeCurveXYZTexture, VisualShaderNodeResizableBase);
+ Ref<CurveXYZTexture> texture;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ void set_texture(Ref<CurveXYZTexture> p_value);
+ Ref<CurveXYZTexture> get_texture() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ VisualShaderNodeCurveXYZTexture();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeSample3D : public VisualShaderNode {
GDCLASS(VisualShaderNodeSample3D, VisualShaderNode);