diff options
Diffstat (limited to 'scene/3d')
-rw-r--r-- | scene/3d/cpu_particles_3d.cpp | 11 | ||||
-rw-r--r-- | scene/3d/gpu_particles_3d.cpp | 2 | ||||
-rw-r--r-- | scene/3d/label_3d.cpp | 126 | ||||
-rw-r--r-- | scene/3d/label_3d.h | 32 | ||||
-rw-r--r-- | scene/3d/sprite_3d.cpp | 5 | ||||
-rw-r--r-- | scene/3d/voxel_gi.cpp | 3 |
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(); } |