summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-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/mesh.cpp31
-rw-r--r--scene/resources/mesh.h6
-rw-r--r--scene/resources/particles_material.cpp6
-rw-r--r--scene/resources/texture.cpp56
-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/visual_shader.cpp22
-rw-r--r--scene/resources/visual_shader.h1
-rw-r--r--scene/resources/visual_shader_nodes.cpp42
-rw-r--r--scene/resources/visual_shader_nodes.h12
13 files changed, 282 insertions, 76 deletions
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/mesh.cpp b/scene/resources/mesh.cpp
index f44c0c3ee2..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;
@@ -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 2bde98abe0..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";
}
@@ -1046,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/texture.cpp b/scene/resources/texture.cpp
index 98997e482a..26c0d432a9 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1545,19 +1545,19 @@ 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, "1,4096"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_x", "get_curve_x");
@@ -1565,7 +1565,7 @@ void Curve3Texture::_bind_methods() {
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);
}
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/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 54bc7382db..36a1c206c8 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -2708,6 +2708,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:
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 4e73b8db44..79ea9d72df 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -889,56 +889,56 @@ VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() {
allow_v_resize = false;
}
-////////////// Curve3Texture
+////////////// CurveXYZTexture
-String VisualShaderNodeCurve3Texture::get_caption() const {
- return "Curve3Texture";
+String VisualShaderNodeCurveXYZTexture::get_caption() const {
+ return "CurveXYZTexture";
}
-int VisualShaderNodeCurve3Texture::get_input_port_count() const {
+int VisualShaderNodeCurveXYZTexture::get_input_port_count() const {
return 1;
}
-VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_input_port_type(int p_port) const {
+VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeCurve3Texture::get_input_port_name(int p_port) const {
+String VisualShaderNodeCurveXYZTexture::get_input_port_name(int p_port) const {
return String();
}
-int VisualShaderNodeCurve3Texture::get_output_port_count() const {
+int VisualShaderNodeCurveXYZTexture::get_output_port_count() const {
return 1;
}
-VisualShaderNodeCurve3Texture::PortType VisualShaderNodeCurve3Texture::get_output_port_type(int p_port) const {
+VisualShaderNodeCurveXYZTexture::PortType VisualShaderNodeCurveXYZTexture::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
-String VisualShaderNodeCurve3Texture::get_output_port_name(int p_port) const {
+String VisualShaderNodeCurveXYZTexture::get_output_port_name(int p_port) const {
return String();
}
-void VisualShaderNodeCurve3Texture::set_texture(Ref<Curve3Texture> p_texture) {
+void VisualShaderNodeCurveXYZTexture::set_texture(Ref<CurveXYZTexture> p_texture) {
texture = p_texture;
emit_changed();
}
-Ref<Curve3Texture> VisualShaderNodeCurve3Texture::get_texture() const {
+Ref<CurveXYZTexture> VisualShaderNodeCurveXYZTexture::get_texture() const {
return texture;
}
-Vector<StringName> VisualShaderNodeCurve3Texture::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeCurveXYZTexture::get_editable_properties() const {
Vector<StringName> props;
props.push_back("texture");
return props;
}
-String VisualShaderNodeCurve3Texture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+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 VisualShaderNodeCurve3Texture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String 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";
}
@@ -948,7 +948,7 @@ String VisualShaderNodeCurve3Texture::generate_code(Shader::Mode p_mode, VisualS
return code;
}
-Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurve3Texture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
+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;
@@ -957,18 +957,18 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurve3Texture::get_def
return ret;
}
-void VisualShaderNodeCurve3Texture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurve3Texture::set_texture);
- ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurve3Texture::get_texture);
+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, "Curve3Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_texture", "get_texture");
}
-bool VisualShaderNodeCurve3Texture::is_use_prop_slots() const {
+bool VisualShaderNodeCurveXYZTexture::is_use_prop_slots() const {
return true;
}
-VisualShaderNodeCurve3Texture::VisualShaderNodeCurve3Texture() {
+VisualShaderNodeCurveXYZTexture::VisualShaderNodeCurveXYZTexture() {
simple_decl = true;
allow_v_resize = false;
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 3ae79723e9..33a45a4384 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -338,9 +338,9 @@ public:
///////////////////////////////////////
-class VisualShaderNodeCurve3Texture : public VisualShaderNodeResizableBase {
- GDCLASS(VisualShaderNodeCurve3Texture, VisualShaderNodeResizableBase);
- Ref<Curve3Texture> texture;
+class VisualShaderNodeCurveXYZTexture : public VisualShaderNodeResizableBase {
+ GDCLASS(VisualShaderNodeCurveXYZTexture, VisualShaderNodeResizableBase);
+ Ref<CurveXYZTexture> texture;
protected:
static void _bind_methods();
@@ -360,13 +360,13 @@ public:
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<Curve3Texture> p_value);
- Ref<Curve3Texture> get_texture() const;
+ 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;
- VisualShaderNodeCurve3Texture();
+ VisualShaderNodeCurveXYZTexture();
};
///////////////////////////////////////