summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/cpu_particles_3d.cpp11
-rw-r--r--scene/3d/gpu_particles_3d.cpp2
-rw-r--r--scene/3d/label_3d.cpp126
-rw-r--r--scene/3d/label_3d.h32
-rw-r--r--scene/3d/sprite_3d.cpp5
-rw-r--r--scene/3d/voxel_gi.cpp3
6 files changed, 64 insertions, 115 deletions
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 8585f3bdfc..4df0c37ad6 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -164,6 +164,8 @@ void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) {
} else {
RS::get_singleton()->multimesh_set_mesh(multimesh, RID());
}
+
+ update_configuration_warnings();
}
Ref<Mesh> CPUParticles3D::get_mesh() const {
@@ -187,7 +189,7 @@ bool CPUParticles3D::get_fractional_delta() const {
}
TypedArray<String> CPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
bool mesh_found = false;
bool anim_material_found = false;
@@ -266,6 +268,8 @@ void CPUParticles3D::set_param_min(Parameter p_param, real_t p_value) {
if (parameters_min[p_param] > parameters_max[p_param]) {
set_param_max(p_param, p_value);
}
+
+ update_configuration_warnings();
}
real_t CPUParticles3D::get_param_min(Parameter p_param) const {
@@ -276,10 +280,13 @@ real_t CPUParticles3D::get_param_min(Parameter p_param) const {
void CPUParticles3D::set_param_max(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
+
parameters_max[p_param] = p_value;
if (parameters_min[p_param] > parameters_max[p_param]) {
set_param_min(p_param, p_value);
}
+
+ update_configuration_warnings();
}
real_t CPUParticles3D::get_param_max(Parameter p_param) const {
@@ -340,6 +347,8 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
default: {
}
}
+
+ update_configuration_warnings();
}
Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const {
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index d18c452ca7..b352114c7f 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -270,7 +270,7 @@ bool GPUParticles3D::get_interpolate() const {
}
TypedArray<String> GPUParticles3D::get_configuration_warnings() const {
- TypedArray<String> warnings = Node::get_configuration_warnings();
+ TypedArray<String> warnings = GeometryInstance3D::get_configuration_warnings();
if (RenderingServer::get_singleton()->is_low_end()) {
warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose."));
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 0849b2c631..0e5771bdb1 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -53,10 +53,6 @@ void Label3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label3D::set_text_direction);
ClassDB::bind_method(D_METHOD("get_text_direction"), &Label3D::get_text_direction);
- ClassDB::bind_method(D_METHOD("set_opentype_feature", "tag", "value"), &Label3D::set_opentype_feature);
- ClassDB::bind_method(D_METHOD("get_opentype_feature", "tag"), &Label3D::get_opentype_feature);
- ClassDB::bind_method(D_METHOD("clear_opentype_features"), &Label3D::clear_opentype_features);
-
ClassDB::bind_method(D_METHOD("set_language", "language"), &Label3D::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &Label3D::get_language);
@@ -140,7 +136,7 @@ void Label3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_modulate"), "set_outline_modulate", "get_outline_modulate");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, ""), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,127,1,suffix:px"), "set_font_size", "get_font_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px"), "set_font_size", "get_font_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,suffix:px"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom"), "set_vertical_alignment", "get_vertical_alignment");
@@ -148,12 +144,12 @@ void Label3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing");
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width", PROPERTY_HINT_NONE, "suffix:px"), "set_width", "get_width");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
- ADD_GROUP("Locale", "");
+ ADD_GROUP("BiDi", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
BIND_ENUM_CONSTANT(FLAG_SHADED);
BIND_ENUM_CONSTANT(FLAG_DOUBLE_SIDED);
@@ -166,56 +162,6 @@ void Label3D::_bind_methods() {
BIND_ENUM_CONSTANT(ALPHA_CUT_OPAQUE_PREPASS);
}
-bool Label3D::_set(const StringName &p_name, const Variant &p_value) {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- int value = p_value;
- if (value == -1) {
- if (opentype_features.has(tag)) {
- opentype_features.erase(tag);
- dirty_font = true;
- _queue_update();
- }
- } else {
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
- opentype_features[tag] = value;
- dirty_font = true;
- _queue_update();
- }
- }
- notify_property_list_changed();
- return true;
- }
-
- return false;
-}
-
-bool Label3D::_get(const StringName &p_name, Variant &r_ret) const {
- String str = p_name;
- if (str.begins_with("opentype_features/")) {
- String name = str.get_slicec('/', 1);
- int32_t tag = TS->name_to_tag(name);
- if (opentype_features.has(tag)) {
- r_ret = opentype_features[tag];
- return true;
- } else {
- r_ret = -1;
- return true;
- }
- }
- return false;
-}
-
-void Label3D::_get_property_list(List<PropertyInfo> *p_list) const {
- for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
- String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
- }
- p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
-}
-
void Label3D::_validate_property(PropertyInfo &property) const {
if (property.name == "material_override" || property.name == "material_overlay") {
property.usage = PROPERTY_USAGE_NO_EDITOR;
@@ -280,7 +226,7 @@ Ref<TriangleMesh> Label3D::generate_triangle_mesh() const {
float total_h = 0.0;
float max_line_w = 0.0;
for (int i = 0; i < lines_rid.size(); i++) {
- total_h += TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing;
+ total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing;
max_line_w = MAX(max_line_w, TS->shaped_text_get_width(lines_rid[i]));
}
@@ -370,15 +316,8 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,
bool msdf = TS->font_is_multichannel_signed_distance_field(p_glyph.font_rid);
- uint64_t mat_hash;
- if (tex != RID()) {
- mat_hash = hash_one_uint64(tex.get_id());
- } else {
- mat_hash = hash_one_uint64(0);
- }
- mat_hash = hash_fmix32(hash_murmur3_one_64(p_priority | (p_outline_size << 31), mat_hash));
-
- if (!surfaces.has(mat_hash)) {
+ SurfaceKey key = SurfaceKey(tex.get_id(), p_priority, p_outline_size);
+ if (!surfaces.has(key)) {
SurfaceData surf;
surf.material = RenderingServer::get_singleton()->material_create();
// Set defaults for material, names need to match up those in StandardMaterial3D
@@ -407,9 +346,9 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,
surf.z_shift = p_priority * pixel_size;
}
- surfaces[mat_hash] = surf;
+ surfaces[key] = surf;
}
- SurfaceData &s = surfaces[mat_hash];
+ SurfaceData &s = surfaces[key];
s.mesh_vertices.resize((s.offset + 1) * 4);
s.mesh_normals.resize((s.offset + 1) * 4);
@@ -464,7 +403,7 @@ void Label3D::_shape() {
aabb = AABB();
// Clear materials.
- for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) {
+ for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
RenderingServer::get_singleton()->free(E.value.material);
}
surfaces.clear();
@@ -478,7 +417,10 @@ void Label3D::_shape() {
TS->shaped_text_set_direction(text_rid, text_direction);
String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text;
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, language);
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, font->get_opentype_features(), language);
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
+ }
Array stt;
if (st_parser == TextServer::STRUCTURED_TEXT_CUSTOM) {
@@ -494,7 +436,10 @@ void Label3D::_shape() {
} else if (dirty_font) {
int spans = TS->shaped_get_span_count(text_rid);
for (int i = 0; i < spans; i++) {
- TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, opentype_features);
+ TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, font->get_opentype_features());
+ }
+ for (int i = 0; i < TextServer::SPACING_MAX; i++) {
+ TS->shaped_text_set_spacing(text_rid, TextServer::SpacingType(i), font->get_spacing(TextServer::SpacingType(i)));
}
dirty_font = false;
@@ -541,7 +486,7 @@ void Label3D::_shape() {
// Generate surfaces and materials.
float total_h = 0.0;
for (int i = 0; i < lines_rid.size(); i++) {
- total_h += (TS->shaped_text_get_size(lines_rid[i]).y + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM) + line_spacing) * pixel_size;
+ total_h += (TS->shaped_text_get_size(lines_rid[i]).y + line_spacing) * pixel_size;
}
float vbegin = 0.0;
@@ -577,7 +522,7 @@ void Label3D::_shape() {
} break;
}
offset.x += lbl_offset.x * pixel_size;
- offset.y -= (TS->shaped_text_get_ascent(lines_rid[i]) + font->get_spacing(TextServer::SPACING_TOP)) * pixel_size;
+ offset.y -= TS->shaped_text_get_ascent(lines_rid[i]) * pixel_size;
if (outline_modulate.a != 0.0 && outline_size > 0) {
// Outline surfaces.
@@ -591,10 +536,10 @@ void Label3D::_shape() {
for (int j = 0; j < gl_size; j++) {
_generate_glyph_surfaces(glyphs[j], offset, modulate, render_priority);
}
- offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM)) * pixel_size;
+ offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing) * pixel_size;
}
- for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) {
+ for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
Array mesh_array;
mesh_array.resize(RS::ARRAY_MAX);
mesh_array[RS::ARRAY_VERTEX] = E.value.mesh_vertices;
@@ -664,29 +609,6 @@ TextServer::Direction Label3D::get_text_direction() const {
return text_direction;
}
-void Label3D::clear_opentype_features() {
- opentype_features.clear();
- dirty_font = true;
- _queue_update();
-}
-
-void Label3D::set_opentype_feature(const String &p_name, int p_value) {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
- opentype_features[tag] = p_value;
- dirty_font = true;
- _queue_update();
- }
-}
-
-int Label3D::get_opentype_feature(const String &p_name) const {
- int32_t tag = TS->name_to_tag(p_name);
- if (!opentype_features.has(tag)) {
- return -1;
- }
- return opentype_features[tag];
-}
-
void Label3D::set_language(const String &p_language) {
if (language != p_language) {
language = p_language;
@@ -788,7 +710,7 @@ Ref<Font> Label3D::_get_font_or_default() const {
theme_font.unref();
}
- if (font_override.is_valid() && font_override->get_data_count() > 0) {
+ if (font_override.is_valid()) {
return font_override;
}
@@ -1018,7 +940,7 @@ Label3D::~Label3D() {
TS->free_rid(text_rid);
RenderingServer::get_singleton()->free(mesh);
- for (KeyValue<uint64_t, SurfaceData> E : surfaces) {
+ for (KeyValue<SurfaceKey, SurfaceData> E : surfaces) {
RenderingServer::get_singleton()->free(E.value.material);
}
surfaces.clear();
diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h
index 7766bca068..4498e89517 100644
--- a/scene/3d/label_3d.h
+++ b/scene/3d/label_3d.h
@@ -76,7 +76,29 @@ private:
RID material;
};
- HashMap<uint64_t, SurfaceData> surfaces;
+ struct SurfaceKey {
+ uint64_t texture_id;
+ int32_t priority;
+ int32_t outline_size;
+
+ bool operator==(const SurfaceKey &p_b) const {
+ return (texture_id == p_b.texture_id) && (priority == p_b.priority) && (outline_size == p_b.outline_size);
+ }
+
+ SurfaceKey(uint64_t p_texture_id, int p_priority, int p_outline_size) {
+ texture_id = p_texture_id;
+ priority = p_priority;
+ outline_size = p_outline_size;
+ }
+ };
+
+ struct SurfaceKeyHasher {
+ _FORCE_INLINE_ static uint32_t hash(const SurfaceKey &p_a) {
+ return hash_murmur3_buffer(&p_a, sizeof(SurfaceKey));
+ }
+ };
+
+ HashMap<SurfaceKey, SurfaceData, SurfaceKeyHasher> surfaces;
HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
@@ -100,7 +122,6 @@ private:
float line_spacing = 0.f;
- Dictionary opentype_features;
String language;
TextServer::Direction text_direction = TextServer::DIRECTION_AUTO;
TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT;
@@ -128,9 +149,6 @@ protected:
static void _bind_methods();
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_property(PropertyInfo &property) const override;
void _im_update();
@@ -158,10 +176,6 @@ public:
void set_text_direction(TextServer::Direction p_text_direction);
TextServer::Direction get_text_direction() const;
- void set_opentype_feature(const String &p_name, int p_value);
- int get_opentype_feature(const String &p_name) const;
- void clear_opentype_features();
-
void set_language(const String &p_language);
String get_language() const;
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 55b55d924c..cb6354f7a8 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -1034,8 +1034,11 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
if (property.name == "frame") {
property.hint = PROPERTY_HINT_RANGE;
- if (frames->has_animation(animation) && frames->get_frame_count(animation) > 1) {
+ if (frames->has_animation(animation) && frames->get_frame_count(animation) > 0) {
property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1";
+ } else {
+ // Avoid an error, `hint_string` is required for `PROPERTY_HINT_RANGE`.
+ property.hint_string = "0,0,1";
}
property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS;
}
diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp
index d81b59b3fc..ae231026a7 100644
--- a/scene/3d/voxel_gi.cpp
+++ b/scene/3d/voxel_gi.cpp
@@ -272,7 +272,8 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const {
}
void VoxelGI::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
+ // Prevent very small extents as these break baking if other extents are set very high.
+ extents = Vector3(MAX(1.0, p_extents.x), MAX(1.0, p_extents.y), MAX(1.0, p_extents.z));
update_gizmos();
}