diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/font.cpp | 20 | ||||
-rw-r--r-- | scene/resources/material.cpp | 6 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 199 | ||||
-rw-r--r-- | scene/resources/mesh.h | 85 | ||||
-rw-r--r-- | scene/resources/particles_material.cpp | 64 | ||||
-rw-r--r-- | scene/resources/particles_material.h | 26 | ||||
-rw-r--r-- | scene/resources/primitive_meshes.cpp | 42 | ||||
-rw-r--r-- | scene/resources/primitive_meshes.h | 8 | ||||
-rw-r--r-- | scene/resources/surface_tool.cpp | 433 | ||||
-rw-r--r-- | scene/resources/surface_tool.h | 61 | ||||
-rw-r--r-- | scene/resources/text_line.cpp | 24 | ||||
-rw-r--r-- | scene/resources/text_line.h | 2 | ||||
-rw-r--r-- | scene/resources/text_paragraph.cpp | 57 | ||||
-rw-r--r-- | scene/resources/text_paragraph.h | 2 | ||||
-rw-r--r-- | scene/resources/visual_shader.cpp | 41 | ||||
-rw-r--r-- | scene/resources/visual_shader.h | 2 |
16 files changed, 700 insertions, 372 deletions
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index da35137a09..f88082c665 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -595,41 +595,41 @@ Dictionary Font::get_feature_list() const { float Font::get_height(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_height(p_size); + ret = MAX(ret, data[i]->get_height(p_size)); } - return (ret / data.size()) + spacing_top + spacing_bottom; + return ret + spacing_top + spacing_bottom; } float Font::get_ascent(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_ascent(p_size); + ret = MAX(ret, data[i]->get_ascent(p_size)); } - return (ret / data.size()) + spacing_top; + return ret + spacing_top; } float Font::get_descent(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_descent(p_size); + ret = MAX(ret, data[i]->get_descent(p_size)); } - return (ret / data.size()) + spacing_bottom; + return ret + spacing_bottom; } float Font::get_underline_position(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_underline_position(p_size); + ret = MAX(ret, data[i]->get_underline_position(p_size)); } - return (ret / data.size()); + return ret; } float Font::get_underline_thickness(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_underline_thickness(p_size); + ret = MAX(ret, data[i]->get_underline_thickness(p_size)); } - return (ret / data.size()); + return ret; } int Font::get_spacing(int p_type) const { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 35c967ce27..6e08af23f5 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2417,10 +2417,10 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Height", "heightmap_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_heightmap_scale", "get_heightmap_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 97c0c7a81d..c6815c8ecc 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -157,7 +157,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { bool Mesh::surface_is_softbody_friendly(int p_idx) const { const uint32_t surface_format = surface_get_format(p_idx); - return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL))); + return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE); } Vector<Face3> Mesh::get_faces() const { @@ -480,8 +480,30 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES); BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); + BIND_ENUM_CONSTANT(ARRAY_NORMAL); + BIND_ENUM_CONSTANT(ARRAY_TANGENT); + BIND_ENUM_CONSTANT(ARRAY_COLOR); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM3); + BIND_ENUM_CONSTANT(ARRAY_BONES); + BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); + BIND_ENUM_CONSTANT(ARRAY_INDEX); + BIND_ENUM_CONSTANT(ARRAY_MAX); + + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); @@ -489,31 +511,28 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3); BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK); - BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE); - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS); } void Mesh::clear_cache() const { @@ -560,11 +579,50 @@ Vector<Ref<Shape3D>> Mesh::convex_decompose() const { Mesh::Mesh() { } +#if 0 static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) { - bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE))); - bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES); - bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2)); - bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2)); + enum ArrayType { + OLD_ARRAY_VERTEX = 0, + OLD_ARRAY_NORMAL = 1, + OLD_ARRAY_TANGENT = 2, + OLD_ARRAY_COLOR = 3, + OLD_ARRAY_TEX_UV = 4, + OLD_ARRAY_TEX_UV2 = 5, + OLD_ARRAY_BONES = 6, + OLD_ARRAY_WEIGHTS = 7, + OLD_ARRAY_INDEX = 8, + OLD_ARRAY_MAX = 9 + }; + + enum ArrayFormat { + /* OLD_ARRAY FORMAT FLAGS */ + OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory + OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, + OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, + OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, + OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, + OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, + OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, + OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, + OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, + + OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), + OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_DEFAULT = OLD_ARRAY_COMPRESS_NORMAL | OLD_ARRAY_COMPRESS_TANGENT | OLD_ARRAY_COMPRESS_COLOR | OLD_ARRAY_COMPRESS_TEX_UV | OLD_ARRAY_COMPRESS_TEX_UV2, + + OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, + OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, + }; + + bool vertex_16bit = p_format & ((1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE))); + bool has_bones = (p_format & OLD_ARRAY_FORMAT_BONES); + bool bone_8 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_INDEX << 2)); + bool weight_32 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_TEX_UV2 << 2)); print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32)); @@ -572,7 +630,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return p_src; } - bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1)); + bool vertex_2d = (p_format & (OLD_ARRAY_COMPRESS_INDEX << 1)); uint32_t src_stride = p_src.size() / p_elements; uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0); @@ -671,6 +729,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return ret; } +#endif bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -727,6 +786,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]); } else if (d.has("array_data")) { +#if 0 //print_line("array data (old style"); //older format (3.x) Vector<uint8_t> array_data = d["array_data"]; @@ -793,6 +853,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } add_surface(format, PrimitiveType(primitive), array_data, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb); +#endif } else { ERR_FAIL_V(false); } @@ -824,6 +885,12 @@ Array ArrayMesh::_get_surfaces() const { data["primitive"] = surface.primitive; data["vertex_data"] = surface.vertex_data; data["vertex_count"] = surface.vertex_count; + if (surface.skin_data.size()) { + data["skin_data"] = surface.skin_data; + } + if (surface.attribute_data.size()) { + data["attribute_data"] = surface.attribute_data; + } data["aabb"] = surface.aabb; if (surface.index_count) { data["index_data"] = surface.index_data; @@ -848,9 +915,9 @@ Array ArrayMesh::_get_surfaces() const { data["bone_aabbs"] = bone_aabbs; } - Array blend_shapes; - for (int j = 0; j < surface.blend_shapes.size(); j++) { - blend_shapes.push_back(surface.blend_shapes[j]); + if (surface.blend_shape_data.size()) { + data["blend_shapes"] = surface.blend_shape_data; + data["blend_shapes_count"] = surface.blend_shape_count; } if (surfaces[i].material.is_valid()) { @@ -896,6 +963,12 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { surface.primitive = RS::PrimitiveType(int(d["primitive"])); surface.vertex_data = d["vertex_data"]; surface.vertex_count = d["vertex_count"]; + if (d.has("attribute_data")) { + surface.attribute_data = d["attribute_data"]; + } + if (d.has("skin_data")) { + surface.skin_data = d["skin_data"]; + } surface.aabb = d["aabb"]; if (d.has("index_data")) { @@ -922,11 +995,9 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { } } - if (d.has("blend_shapes")) { - Array blend_shapes; - for (int j = 0; j < blend_shapes.size(); j++) { - surface.blend_shapes.push_back(blend_shapes[j]); - } + if (d.has("blend_shapes") && d.has("blend_shape_count")) { + surface.blend_shape_data = d["blend_shapes"]; + surface.blend_shape_count = d["blend_shape_count"]; } Ref<Material> material; @@ -982,7 +1053,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { s.aabb = surface_data[i].aabb; if (i == 0) { aabb = s.aabb; - blend_shapes.resize(surface_data[i].blend_shapes.size()); + blend_shapes.resize(surface_data[i].blend_shape_count); } else { aabb.merge_with(s.aabb); } @@ -1070,7 +1141,7 @@ void ArrayMesh::_recompute_aabb() { #ifndef _MSC_VER #warning need to add binding to add_surface using future MeshSurfaceData object #endif -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, uint32_t p_blend_shape_count, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) { _create_if_empty(); Surface s; @@ -1090,10 +1161,13 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const sd.aabb = p_aabb; sd.vertex_count = p_vertex_count; sd.vertex_data = p_array; + sd.attribute_data = p_attribute_array; + sd.skin_data = p_skin_array; sd.index_count = p_index_count; sd.index_data = p_index_array; - sd.blend_shapes = p_blend_shapes; - sd.bone_aabbs = p_bone_aabb; + sd.blend_shape_data = p_blend_shape_data; + sd.blend_shape_count = p_blend_shape_count; + sd.bone_aabbs = p_bone_aabbs; sd.lods = p_lods; RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); @@ -1111,15 +1185,17 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RenderingServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags); ERR_FAIL_COND(err != OK); - /* print_line("format: " + itos(surface.format)); + /* Debug code. + print_line("format: " + itos(surface.format)); print_line("aabb: " + surface.aabb); print_line("array size: " + itos(surface.vertex_data.size())); print_line("vertex count: " + itos(surface.vertex_count)); print_line("index size: " + itos(surface.index_data.size())); print_line("index count: " + itos(surface.index_count)); print_line("primitive: " + itos(surface.primitive)); -*/ - add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods); + */ + + add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.attribute_data, surface.skin_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shape_data, surface.blend_shape_count, surface.bone_aabbs, surface.lods); } Array ArrayMesh::surface_get_arrays(int p_surface) const { @@ -1452,29 +1528,29 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { - surfaces_tools.write[surface]->add_color(v.color); + surfaces_tools.write[surface]->set_color(v.color); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { - surfaces_tools.write[surface]->add_uv(v.uv); + surfaces_tools.write[surface]->set_uv(v.uv); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { - surfaces_tools.write[surface]->add_normal(v.normal); + surfaces_tools.write[surface]->set_normal(v.normal); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { Plane t; t.normal = v.tangent; t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; - surfaces_tools.write[surface]->add_tangent(t); + surfaces_tools.write[surface]->set_tangent(t); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { - surfaces_tools.write[surface]->add_bones(v.bones); + surfaces_tools.write[surface]->set_bones(v.bones); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { - surfaces_tools.write[surface]->add_weights(v.weights); + surfaces_tools.write[surface]->set_weights(v.weights); } Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); - surfaces_tools.write[surface]->add_uv2(uv2); + surfaces_tools.write[surface]->set_uv2(uv2); surfaces_tools.write[surface]->add_vertex(v.vertex); } @@ -1507,7 +1583,7 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); @@ -1537,29 +1613,8 @@ void ArrayMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); - BIND_CONSTANT(NO_INDEX_ARRAY); - BIND_CONSTANT(ARRAY_WEIGHTS_SIZE); - - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); - - BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); } void ArrayMesh::reload_from_file() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 642ae7e1b0..ae2139a0cf 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -61,6 +61,10 @@ public: ARRAY_COLOR = RenderingServer::ARRAY_COLOR, ARRAY_TEX_UV = RenderingServer::ARRAY_TEX_UV, ARRAY_TEX_UV2 = RenderingServer::ARRAY_TEX_UV2, + ARRAY_CUSTOM0 = RenderingServer::ARRAY_CUSTOM0, + ARRAY_CUSTOM1 = RenderingServer::ARRAY_CUSTOM1, + ARRAY_CUSTOM2 = RenderingServer::ARRAY_CUSTOM2, + ARRAY_CUSTOM3 = RenderingServer::ARRAY_CUSTOM3, ARRAY_BONES = RenderingServer::ARRAY_BONES, ARRAY_WEIGHTS = RenderingServer::ARRAY_WEIGHTS, ARRAY_INDEX = RenderingServer::ARRAY_INDEX, @@ -68,30 +72,47 @@ public: }; + enum ArrayCustomFormat { + ARRAY_CUSTOM_RGBA8_UNORM, + ARRAY_CUSTOM_RGBA8_SNORM, + ARRAY_CUSTOM_RG_HALF, + ARRAY_CUSTOM_RGBA_HALF, + ARRAY_CUSTOM_R_FLOAT, + ARRAY_CUSTOM_RG_FLOAT, + ARRAY_CUSTOM_RGB_FLOAT, + ARRAY_CUSTOM_RGBA_FLOAT, + ARRAY_CUSTOM_MAX + }; + enum ArrayFormat { - /* ARRAY FORMAT FLAGS */ - ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory - ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL, - ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT, - ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR, - ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV, - ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2, - ARRAY_FORMAT_BONES = 1 << ARRAY_BONES, - ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS, - ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX, - - ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1), - ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), - - ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, - ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 + ARRAY_FORMAT_VERTEX = RS::ARRAY_FORMAT_VERTEX, + ARRAY_FORMAT_NORMAL = RS::ARRAY_FORMAT_NORMAL, + ARRAY_FORMAT_TANGENT = RS::ARRAY_FORMAT_TANGENT, + ARRAY_FORMAT_COLOR = RS::ARRAY_FORMAT_COLOR, + ARRAY_FORMAT_TEX_UV = RS::ARRAY_FORMAT_TEX_UV, + ARRAY_FORMAT_TEX_UV2 = RS::ARRAY_FORMAT_TEX_UV2, + ARRAY_FORMAT_CUSTOM0 = RS::ARRAY_FORMAT_CUSTOM0, + ARRAY_FORMAT_CUSTOM1 = RS::ARRAY_FORMAT_CUSTOM1, + ARRAY_FORMAT_CUSTOM2 = RS::ARRAY_FORMAT_CUSTOM2, + ARRAY_FORMAT_CUSTOM3 = RS::ARRAY_FORMAT_CUSTOM3, + ARRAY_FORMAT_BONES = RS::ARRAY_FORMAT_BONES, + ARRAY_FORMAT_WEIGHTS = RS::ARRAY_FORMAT_WEIGHTS, + ARRAY_FORMAT_INDEX = RS::ARRAY_FORMAT_INDEX, + + ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK, + + ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE, + ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT, + ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT, + ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT, + ARRAY_FORMAT_CUSTOM3_SHIFT = RS::ARRAY_FORMAT_CUSTOM3_SHIFT, + + ARRAY_FORMAT_CUSTOM_MASK = RS::ARRAY_FORMAT_CUSTOM_MASK, + ARRAY_COMPRESS_FLAGS_BASE = RS::ARRAY_COMPRESS_FLAGS_BASE, + + ARRAY_FLAG_USE_2D_VERTICES = RS::ARRAY_FLAG_USE_2D_VERTICES, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE, + ARRAY_FLAG_USE_8_BONE_WEIGHTS = RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS, }; @@ -104,11 +125,6 @@ public: PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX, }; - enum BlendShapeMode { - BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, - BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, - }; - virtual int get_surface_count() const = 0; virtual int surface_get_array_len(int p_idx) const = 0; virtual int surface_get_array_index_len(int p_idx) const = 0; @@ -155,6 +171,12 @@ class ArrayMesh : public Mesh { Array _get_surfaces() const; void _set_surfaces(const Array &p_data); +public: + enum BlendShapeMode { + BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, + BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, + }; + private: struct Surface { uint32_t format; @@ -187,9 +209,9 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), uint32_t p_blend_shape_count = 0, const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); Array surface_get_arrays(int p_surface) const override; Array surface_get_blend_shape_arrays(int p_surface) const override; @@ -244,7 +266,8 @@ public: VARIANT_ENUM_CAST(Mesh::ArrayType); VARIANT_ENUM_CAST(Mesh::ArrayFormat); +VARIANT_ENUM_CAST(Mesh::ArrayCustomFormat); VARIANT_ENUM_CAST(Mesh::PrimitiveType); -VARIANT_ENUM_CAST(Mesh::BlendShapeMode); +VARIANT_ENUM_CAST(ArrayMesh::BlendShapeMode); #endif diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index a286184aee..e2f96c54cb 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -329,7 +329,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; @@ -377,7 +377,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n"; if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " mat2 rotm;"; code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n"; code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n"; @@ -398,7 +398,7 @@ void ParticlesMaterial::_update_shader() { code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -413,7 +413,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; } else { @@ -471,7 +471,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 force = gravity;\n"; code += " vec3 pos = TRANSFORM[3].xyz;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " pos.z = 0.0;\n"; } code += " // apply linear acceleration\n"; @@ -481,7 +481,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 diff = pos - org;\n"; code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);\n"; code += " // apply tangential acceleration;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; } else { @@ -495,7 +495,7 @@ void ParticlesMaterial::_update_shader() { code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; code += " // orbit velocity\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n"; code += " if (orbit_amount != 0.0) {\n"; code += " float ang = orbit_amount * DELTA * pi * 2.0;\n"; @@ -562,8 +562,8 @@ void ParticlesMaterial::_update_shader() { } code += "\n"; - if (flags[FLAG_DISABLE_Z]) { - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -579,7 +579,7 @@ void ParticlesMaterial::_update_shader() { } else { // orient particle Y towards velocity - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -598,7 +598,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n"; } // turn particle by rotation in Y - if (flags[FLAG_ROTATE_Y]) { + if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) { code += " TRANSFORM = TRANSFORM * mat4(vec4(cos(CUSTOM.x), 0.0, -sin(CUSTOM.x), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(sin(CUSTOM.x), 0.0, cos(CUSTOM.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } } @@ -611,7 +611,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[0].xyz *= base_scale;\n"; code += " TRANSFORM[1].xyz *= base_scale;\n"; code += " TRANSFORM[2].xyz *= base_scale;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -916,18 +916,18 @@ Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { return color_ramp; } -void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) { - ERR_FAIL_INDEX(p_flag, FLAG_MAX); - flags[p_flag] = p_enable; +void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { + ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); + particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); - if (p_flag == FLAG_DISABLE_Z) { + if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { _change_notify(); } } -bool ParticlesMaterial::get_flag(Flags p_flag) const { - ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); - return flags[p_flag]; +bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { + ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); + return particle_flags[p_particle_flag]; } void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { @@ -1056,7 +1056,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { + if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = 0; } } @@ -1170,8 +1170,8 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &ParticlesMaterial::set_flag); - ClassDB::bind_method(D_METHOD("get_flag", "flag"), &ParticlesMaterial::get_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag); ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape); ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape); @@ -1238,10 +1238,10 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count"); - ADD_GROUP("Flags", "flag_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); + ADD_GROUP("ParticleFlags", "particle_flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); @@ -1327,10 +1327,10 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_MAX); - BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); - BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); - BIND_ENUM_CONSTANT(FLAG_DISABLE_Z); - BIND_ENUM_CONSTANT(FLAG_MAX); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); @@ -1385,8 +1385,8 @@ ParticlesMaterial::ParticlesMaterial() : set_param_randomness(Parameter(i), 0); } - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + particle_flags[i] = false; } set_color(Color(1, 1, 1, 1)); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 12fa53ef29..7e8f05b706 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -61,11 +61,11 @@ public: PARAM_MAX }; - enum Flags { - FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ROTATE_Y, - FLAG_DISABLE_Z, - FLAG_MAX + enum ParticleFlags { + PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, + PARTICLE_FLAG_ROTATE_Y, + PARTICLE_FLAG_DISABLE_Z, + PARTICLE_FLAG_MAX }; enum EmissionShape { @@ -90,7 +90,7 @@ private: struct { uint32_t texture_mask : 16; uint32_t texture_color : 1; - uint32_t flags : 4; + uint32_t particle_flags : 4; uint32_t emission_shape : 2; uint32_t invalid_key : 1; uint32_t has_emission_color : 1; @@ -124,9 +124,9 @@ private: mk.texture_mask |= (1 << i); } } - for (int i = 0; i < FLAG_MAX; i++) { - if (flags[i]) { - mk.flags |= (1 << i); + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + if (particle_flags[i]) { + mk.particle_flags |= (1 << i); } } @@ -227,7 +227,7 @@ private: Color color; Ref<Texture2D> color_ramp; - bool flags[FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; @@ -284,8 +284,8 @@ public: void set_color_ramp(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_color_ramp() const; - void set_flag(Flags p_flag, bool p_enable); - bool get_flag(Flags p_flag) const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); + bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); @@ -349,7 +349,7 @@ public: }; VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) -VARIANT_ENUM_CAST(ParticlesMaterial::Flags) +VARIANT_ENUM_CAST(ParticlesMaterial::ParticleFlags) VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode) diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 8d9c5f07b2..06e181cb99 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -148,7 +148,7 @@ Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); - return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX | RS::ARRAY_COMPRESS_DEFAULT; + return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX; } Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { @@ -477,10 +477,10 @@ CapsuleMesh::CapsuleMesh() { } /** - CubeMesh + BoxMesh */ -void CubeMesh::_create_mesh_array(Array &p_arr) const { +void BoxMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; @@ -672,16 +672,16 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { p_arr[RS::ARRAY_INDEX] = indices; } -void CubeMesh::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_size", "size"), &CubeMesh::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &CubeMesh::get_size); +void BoxMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &BoxMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &BoxMesh::get_size); - ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &CubeMesh::set_subdivide_width); - ClassDB::bind_method(D_METHOD("get_subdivide_width"), &CubeMesh::get_subdivide_width); - ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &CubeMesh::set_subdivide_height); - ClassDB::bind_method(D_METHOD("get_subdivide_height"), &CubeMesh::get_subdivide_height); - ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &CubeMesh::set_subdivide_depth); - ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &CubeMesh::get_subdivide_depth); + ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &BoxMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &BoxMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &BoxMesh::set_subdivide_height); + ClassDB::bind_method(D_METHOD("get_subdivide_height"), &BoxMesh::get_subdivide_height); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &BoxMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &BoxMesh::get_subdivide_depth); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "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"); @@ -689,43 +689,43 @@ void CubeMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth"); } -void CubeMesh::set_size(const Vector3 &p_size) { +void BoxMesh::set_size(const Vector3 &p_size) { size = p_size; _request_update(); } -Vector3 CubeMesh::get_size() const { +Vector3 BoxMesh::get_size() const { return size; } -void CubeMesh::set_subdivide_width(const int p_divisions) { +void BoxMesh::set_subdivide_width(const int p_divisions) { subdivide_w = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_width() const { +int BoxMesh::get_subdivide_width() const { return subdivide_w; } -void CubeMesh::set_subdivide_height(const int p_divisions) { +void BoxMesh::set_subdivide_height(const int p_divisions) { subdivide_h = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_height() const { +int BoxMesh::get_subdivide_height() const { return subdivide_h; } -void CubeMesh::set_subdivide_depth(const int p_divisions) { +void BoxMesh::set_subdivide_depth(const int p_divisions) { subdivide_d = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_depth() const { +int BoxMesh::get_subdivide_depth() const { return subdivide_d; } -CubeMesh::CubeMesh() { +BoxMesh::BoxMesh() { // defaults size = Vector3(2.0, 2.0, 2.0); subdivide_w = 0; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index f0ae611b5e..02aea9c5c8 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -130,10 +130,10 @@ public: }; /** - Similar to test cube but with subdivision support and different texture coordinates + A box */ -class CubeMesh : public PrimitiveMesh { - GDCLASS(CubeMesh, PrimitiveMesh); +class BoxMesh : public PrimitiveMesh { + GDCLASS(BoxMesh, PrimitiveMesh); private: Vector3 size; @@ -158,7 +158,7 @@ public: void set_subdivide_depth(const int p_divisions); int get_subdivide_depth() const; - CubeMesh(); + BoxMesh(); }; /** diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ff14a5a292..3166067573 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -74,6 +74,12 @@ bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { } } + for (int i = 0; i < RS::ARRAY_CUSTOM_MAX; i++) { + if (custom[i] != p_vertex.custom[i]) { + return false; + } + } + return true; } @@ -87,6 +93,7 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { h = hash_djb2_buffer((const uint8_t *)&p_vtx.color, sizeof(real_t) * 4, h); h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int), h); h = hash_djb2_buffer((const uint8_t *)p_vtx.weights.ptr(), p_vtx.weights.size() * sizeof(float), h); + h = hash_djb2_buffer((const uint8_t *)&p_vtx.custom[0], sizeof(Color) * RS::ARRAY_CUSTOM_COUNT, h); return h; } @@ -111,8 +118,11 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { vtx.bones = last_bones; vtx.tangent = last_tangent.normal; vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + vtx.custom[i] = last_custom[i]; + } - const int expected_vertices = 4; + const int expected_vertices = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) { //ensure vertices are the expected amount @@ -163,7 +173,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { format |= Mesh::ARRAY_FORMAT_VERTEX; } -void SurfaceTool::add_color(Color p_color) { +void SurfaceTool::set_color(Color p_color) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR)); @@ -172,7 +182,7 @@ void SurfaceTool::add_color(Color p_color) { last_color = p_color; } -void SurfaceTool::add_normal(const Vector3 &p_normal) { +void SurfaceTool::set_normal(const Vector3 &p_normal) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL)); @@ -181,7 +191,7 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) { last_normal = p_normal; } -void SurfaceTool::add_tangent(const Plane &p_tangent) { +void SurfaceTool::set_tangent(const Plane &p_tangent) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT)); @@ -189,7 +199,7 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) { last_tangent = p_tangent; } -void SurfaceTool::add_uv(const Vector2 &p_uv) { +void SurfaceTool::set_uv(const Vector2 &p_uv) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV)); @@ -197,7 +207,7 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) { last_uv = p_uv; } -void SurfaceTool::add_uv2(const Vector2 &p_uv2) { +void SurfaceTool::set_uv2(const Vector2 &p_uv2) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2)); @@ -205,19 +215,40 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) { last_uv2 = p_uv2; } -void SurfaceTool::add_bones(const Vector<int> &p_bones) { +void SurfaceTool::set_custom(int p_index, const Color &p_custom) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(!begun); + ERR_FAIL_COND(last_custom_format[p_index] == CUSTOM_MAX); + static const uint32_t mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + ERR_FAIL_COND(!first && !(format & mask[p_index])); + + if (first) { + format |= mask[p_index]; + format |= last_custom_format[p_index] << shift[p_index]; + } + last_custom[p_index] = p_custom; +} + +void SurfaceTool::set_bones(const Vector<int> &p_bones) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES)); format |= Mesh::ARRAY_FORMAT_BONES; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_bones = p_bones; } -void SurfaceTool::add_weights(const Vector<float> &p_weights) { +void SurfaceTool::set_weights(const Vector<float> &p_weights) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS)); format |= Mesh::ARRAY_FORMAT_WEIGHTS; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_weights = p_weights; } @@ -238,15 +269,15 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect #define ADD_POINT(n) \ { \ if (p_colors.size() > n) \ - add_color(p_colors[n]); \ + set_color(p_colors[n]); \ if (p_uvs.size() > n) \ - add_uv(p_uvs[n]); \ + set_uv(p_uvs[n]); \ if (p_uv2s.size() > n) \ - add_uv2(p_uv2s[n]); \ + set_uv2(p_uv2s[n]); \ if (p_normals.size() > n) \ - add_normal(p_normals[n]); \ + set_normal(p_normals[n]); \ if (p_tangents.size() > n) \ - add_tangent(p_tangents[n]); \ + set_tangent(p_tangents[n]); \ add_vertex(p_vertices[n]); \ } @@ -358,18 +389,157 @@ Array SurfaceTool::commit_to_arrays() { a[i] = array; } break; + case Mesh::ARRAY_CUSTOM0: + case Mesh::ARRAY_CUSTOM1: + case Mesh::ARRAY_CUSTOM2: + case Mesh::ARRAY_CUSTOM3: { + int fmt = i - Mesh::ARRAY_CUSTOM0; + switch (last_custom_format[fmt]) { + case CUSTOM_RGBA8_UNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255); + w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255); + w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255); + w[idx * 4 + 3] = CLAMP(int32_t(c.a * 255.0), 0, 255); + } + + a[i] = array; + } break; + case CUSTOM_RGBA8_SNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127))); + w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127))); + w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127))); + w[idx * 4 + 3] = uint8_t(int8_t(CLAMP(int32_t(c.a * 127.0), -128, 127))); + } + + a[i] = array; + } break; + case CUSTOM_RG_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint16_t *w = (uint16_t *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = Math::make_half_float(c.r); + w[idx * 2 + 1] = Math::make_half_float(c.g); + } + + a[i] = array; + } break; + case CUSTOM_RGBA_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 8); + uint16_t *w = (uint16_t *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = Math::make_half_float(c.r); + w[idx * 4 + 1] = Math::make_half_float(c.g); + w[idx * 4 + 2] = Math::make_half_float(c.b); + w[idx * 4 + 3] = Math::make_half_float(c.a); + } + + a[i] = array; + } break; + case CUSTOM_R_FLOAT: { + Vector<float> array; + array.resize(varr_len); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx] = c.r; + } + + a[i] = array; + } break; + case CUSTOM_RG_FLOAT: { + Vector<float> array; + array.resize(varr_len * 2); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = c.r; + w[idx * 2 + 1] = c.g; + } + + a[i] = array; + } break; + case CUSTOM_RGB_FLOAT: { + Vector<float> array; + array.resize(varr_len * 3); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 3 + 0] = c.r; + w[idx * 3 + 1] = c.g; + w[idx * 3 + 2] = c.b; + } + + a[i] = array; + } break; + case CUSTOM_RGBA_FLOAT: { + Vector<float> array; + array.resize(varr_len * 4); + float *w = (float *)array.ptrw(); + + int idx = 0; + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { + const Vertex &v = E->get(); + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = c.r; + w[idx * 4 + 1] = c.g; + w[idx * 4 + 2] = c.b; + w[idx * 4 + 3] = c.a; + } + + a[i] = array; + } break; + default: { + } //unreachable but compiler warning anyway + } + } break; case Mesh::ARRAY_BONES: { + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; Vector<int> array; - array.resize(varr_len * 4); + array.resize(varr_len * count); int *w = array.ptrw(); int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) { const Vertex &v = E->get(); - ERR_CONTINUE(v.bones.size() != 4); + ERR_CONTINUE(v.bones.size() != count); - for (int j = 0; j < 4; j++) { + for (int j = 0; j < count; j++) { w[idx + j] = v.bones[j]; } } @@ -379,15 +549,17 @@ Array SurfaceTool::commit_to_arrays() { } break; case Mesh::ARRAY_WEIGHTS: { Vector<float> array; - array.resize(varr_len * 4); + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; + + array.resize(varr_len * count); float *w = array.ptrw(); int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { + for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += count) { const Vertex &v = E->get(); - ERR_CONTINUE(v.weights.size() != 4); + ERR_CONTINUE(v.weights.size() != count); - for (int j = 0; j < 4; j++) { + for (int j = 0; j < count; j++) { w[idx + j] = v.weights[j]; } } @@ -492,13 +664,13 @@ void SurfaceTool::deindex() { index_array.clear(); } -void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { +void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) { Array arr = p_existing->surface_get_arrays(p_surface); ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX); _create_list_from_arrays(arr, r_vertex, r_index, lformat); } -Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) { +Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format) { Vector<SurfaceTool::Vertex> ret; Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX]; @@ -509,9 +681,13 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array Vector<Vector2> uv2arr = p_arrays[RS::ARRAY_TEX_UV2]; Vector<int> barr = p_arrays[RS::ARRAY_BONES]; Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS]; + Vector<float> custom_float[RS::ARRAY_CUSTOM_COUNT]; int vc = varr.size(); if (vc == 0) { + if (r_format) { + *r_format = 0; + } return ret; } @@ -534,12 +710,40 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array if (uv2arr.size()) { lformat |= RS::ARRAY_FORMAT_TEX_UV2; } - if (barr.size()) { + int wcount = 0; + if (barr.size() && warr.size()) { lformat |= RS::ARRAY_FORMAT_BONES; + lformat |= RS::ARRAY_FORMAT_WEIGHTS; + + wcount = barr.size() / varr.size(); + if (wcount == 8) { + lformat |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } } + if (warr.size()) { lformat |= RS::ARRAY_FORMAT_WEIGHTS; } + static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported"); + if (p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_FLOAT32_ARRAY) { + lformat |= custom_mask[i]; + custom_float[i] = p_arrays[RS::ARRAY_CUSTOM0 + i]; + int fmt = custom_float[i].size() / varr.size(); + if (fmt == 1) { + lformat |= CUSTOM_R_FLOAT << custom_shift[i]; + } else if (fmt == 2) { + lformat |= CUSTOM_RG_FLOAT << custom_shift[i]; + } else if (fmt == 3) { + lformat |= CUSTOM_RGB_FLOAT << custom_shift[i]; + } else if (fmt == 4) { + lformat |= CUSTOM_RGBA_FLOAT << custom_shift[i]; + } + } + } for (int i = 0; i < vc; i++) { Vertex v; @@ -565,112 +769,46 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array } if (lformat & RS::ARRAY_FORMAT_BONES) { Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; + b.resize(wcount); + for (int j = 0; j < wcount; j++) { + b.write[j] = barr[i * wcount + j]; + } v.bones = b; } if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; + w.resize(wcount); + for (int j = 0; j < wcount; j++) { + w.write[j] = warr[i * wcount + j]; + } v.weights = w; } + for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) { + if (lformat & custom_mask[j]) { + int cc = custom_float[j].size() / varr.size(); + for (int k = 0; k < cc; k++) { + v.custom[j][k] = custom_float[j][i * cc + k]; + } + } + } + ret.push_back(v); } - return ret; -} - -void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { - Vector<Vector3> varr = arr[RS::ARRAY_VERTEX]; - Vector<Vector3> narr = arr[RS::ARRAY_NORMAL]; - Vector<float> tarr = arr[RS::ARRAY_TANGENT]; - Vector<Color> carr = arr[RS::ARRAY_COLOR]; - Vector<Vector2> uvarr = arr[RS::ARRAY_TEX_UV]; - Vector<Vector2> uv2arr = arr[RS::ARRAY_TEX_UV2]; - Vector<int> barr = arr[RS::ARRAY_BONES]; - Vector<float> warr = arr[RS::ARRAY_WEIGHTS]; - - int vc = varr.size(); - if (vc == 0) { - return; + if (r_format) { + *r_format = lformat; } - lformat = 0; - if (varr.size()) { - lformat |= RS::ARRAY_FORMAT_VERTEX; - } - if (narr.size()) { - lformat |= RS::ARRAY_FORMAT_NORMAL; - } - if (tarr.size()) { - lformat |= RS::ARRAY_FORMAT_TANGENT; - } - if (carr.size()) { - lformat |= RS::ARRAY_FORMAT_COLOR; - } - if (uvarr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV; - } - if (uv2arr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV2; - } - if (barr.size()) { - lformat |= RS::ARRAY_FORMAT_BONES; - } - if (warr.size()) { - lformat |= RS::ARRAY_FORMAT_WEIGHTS; - } + return ret; +} - for (int i = 0; i < vc; i++) { - Vertex v; - if (lformat & RS::ARRAY_FORMAT_VERTEX) { - v.vertex = varr[i]; - } - if (lformat & RS::ARRAY_FORMAT_NORMAL) { - v.normal = narr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TANGENT) { - Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]); - v.tangent = p.normal; - v.binormal = p.normal.cross(v.tangent).normalized() * p.d; - } - if (lformat & RS::ARRAY_FORMAT_COLOR) { - v.color = carr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV) { - v.uv = uvarr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV2) { - v.uv2 = uv2arr[i]; - } - if (lformat & RS::ARRAY_FORMAT_BONES) { - Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; - v.bones = b; - } - if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { - Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; - v.weights = w; - } +void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat) { + Vector<Vertex> arrays = create_vertex_array_from_triangle_arrays(arr, &lformat); + ERR_FAIL_COND(arrays.size() == 0); - r_vertex->push_back(v); + for (int i = 0; i < arrays.size(); i++) { + r_vertex->push_back(arrays[i]); } //indices @@ -725,7 +863,7 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const format = 0; } - int nformat; + uint32_t nformat; List<Vertex> nvertices; List<int> nindices; _create_list(p_existing, p_surface, &nvertices, &nindices, nformat); @@ -975,19 +1113,48 @@ void SurfaceTool::clear() { vertex_array.clear(); smooth_groups.clear(); material.unref(); + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } + skin_weights = SKIN_4_WEIGHTS; +} + +void SurfaceTool::set_skin_weight_count(SkinWeightCount p_weights) { + ERR_FAIL_COND(begun); + skin_weights = p_weights; +} +SurfaceTool::SkinWeightCount SurfaceTool::get_skin_weight_count() const { + return skin_weights; +} + +void SurfaceTool::set_custom_format(int p_index, CustomFormat p_format) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(begun); + last_custom_format[p_index] = p_format; +} +SurfaceTool::CustomFormat SurfaceTool::get_custom_format(int p_index) const { + ERR_FAIL_INDEX_V(p_index, RS::ARRAY_CUSTOM_COUNT, CUSTOM_MAX); + return last_custom_format[p_index]; } void SurfaceTool::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_skin_weight_count", "count"), &SurfaceTool::set_skin_weight_count); + ClassDB::bind_method(D_METHOD("get_skin_weight_count"), &SurfaceTool::get_skin_weight_count); + + ClassDB::bind_method(D_METHOD("set_custom_format", "index", "format"), &SurfaceTool::set_custom_format); + ClassDB::bind_method(D_METHOD("get_custom_format", "index"), &SurfaceTool::get_custom_format); + ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin); ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex); - ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color); - ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal); - ClassDB::bind_method(D_METHOD("add_tangent", "tangent"), &SurfaceTool::add_tangent); - ClassDB::bind_method(D_METHOD("add_uv", "uv"), &SurfaceTool::add_uv); - ClassDB::bind_method(D_METHOD("add_uv2", "uv2"), &SurfaceTool::add_uv2); - ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones); - ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); + ClassDB::bind_method(D_METHOD("set_color", "color"), &SurfaceTool::set_color); + ClassDB::bind_method(D_METHOD("set_normal", "normal"), &SurfaceTool::set_normal); + ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &SurfaceTool::set_tangent); + ClassDB::bind_method(D_METHOD("set_uv", "uv"), &SurfaceTool::set_uv); + ClassDB::bind_method(D_METHOD("set_uv2", "uv2"), &SurfaceTool::set_uv2); + ClassDB::bind_method(D_METHOD("set_bones", "bones"), &SurfaceTool::set_bones); + ClassDB::bind_method(D_METHOD("set_weights", "weights"), &SurfaceTool::set_weights); + ClassDB::bind_method(D_METHOD("set_custom", "index", "custom"), &SurfaceTool::set_custom); ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); @@ -1006,13 +1173,29 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from); ClassDB::bind_method(D_METHOD("create_from_blend_shape", "existing", "surface", "blend_shape"), &SurfaceTool::create_from_blend_shape); ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from); - ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("commit_to_arrays"), &SurfaceTool::commit_to_arrays); + + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_MAX); + BIND_ENUM_CONSTANT(SKIN_4_WEIGHTS); + BIND_ENUM_CONSTANT(SKIN_8_WEIGHTS); } SurfaceTool::SurfaceTool() { first = false; begun = false; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } primitive = Mesh::PRIMITIVE_LINES; + skin_weights = SKIN_4_WEIGHTS; format = 0; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index d7b255e695..4a5c7d990c 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -49,12 +49,30 @@ public: Vector2 uv2; Vector<int> bones; Vector<float> weights; + Color custom[RS::ARRAY_CUSTOM_COUNT]; bool operator==(const Vertex &p_vertex) const; Vertex() {} }; + enum CustomFormat { + CUSTOM_RGBA8_UNORM = RS::ARRAY_CUSTOM_RGBA8_UNORM, + CUSTOM_RGBA8_SNORM = RS::ARRAY_CUSTOM_RGBA8_SNORM, + CUSTOM_RG_HALF = RS::ARRAY_CUSTOM_RG_HALF, + CUSTOM_RGBA_HALF = RS::ARRAY_CUSTOM_RGBA_HALF, + CUSTOM_R_FLOAT = RS::ARRAY_CUSTOM_R_FLOAT, + CUSTOM_RG_FLOAT = RS::ARRAY_CUSTOM_RG_FLOAT, + CUSTOM_RGB_FLOAT = RS::ARRAY_CUSTOM_RGB_FLOAT, + CUSTOM_RGBA_FLOAT = RS::ARRAY_CUSTOM_RGBA_FLOAT, + CUSTOM_MAX = RS::ARRAY_CUSTOM_MAX + }; + + enum SkinWeightCount { + SKIN_4_WEIGHTS, + SKIN_8_WEIGHTS + }; + private: struct VertexHasher { static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx); @@ -71,7 +89,7 @@ private: bool begun; bool first; Mesh::PrimitiveType primitive; - int format; + uint32_t format; Ref<Material> material; //arrays List<Vertex> vertex_array; @@ -87,8 +105,14 @@ private: Vector<float> last_weights; Plane last_tangent; - void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); - void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); + SkinWeightCount skin_weights; + + Color last_custom[RS::ARRAY_CUSTOM_COUNT]; + + CustomFormat last_custom_format[RS::ARRAY_CUSTOM_COUNT]; + + void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat); + void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, uint32_t &lformat); //mikktspace callbacks static int mikktGetNumFaces(const SMikkTSpaceContext *pContext); @@ -103,18 +127,26 @@ protected: static void _bind_methods(); public: + void set_skin_weight_count(SkinWeightCount p_weights); + SkinWeightCount get_skin_weight_count() const; + + void set_custom_format(int p_index, CustomFormat p_format); + CustomFormat get_custom_format(int p_index) const; + void begin(Mesh::PrimitiveType p_primitive); + void set_color(Color p_color); + void set_normal(const Vector3 &p_normal); + void set_tangent(const Plane &p_tangent); + void set_uv(const Vector2 &p_uv); + void set_uv2(const Vector2 &p_uv2); + void set_custom(int p_index, const Color &p_custom); + void set_bones(const Vector<int> &p_bones); + void set_weights(const Vector<float> &p_weights); + void add_vertex(const Vector3 &p_vertex); - void add_color(Color p_color); - void add_normal(const Vector3 &p_normal); - void add_tangent(const Plane &p_tangent); - void add_uv(const Vector2 &p_uv); - void add_uv2(const Vector2 &p_uv2); - void add_bones(const Vector<int> &p_bones); - void add_weights(const Vector<float> &p_weights); - void add_smooth_group(bool p_smooth); + void add_smooth_group(bool p_smooth); void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); void add_index(int p_index); @@ -131,14 +163,17 @@ public: List<Vertex> &get_vertex_array() { return vertex_array; } void create_from_triangle_arrays(const Array &p_arrays); - static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); + static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays, uint32_t *r_format = nullptr); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = 0); SurfaceTool(); }; +VARIANT_ENUM_CAST(SurfaceTool::CustomFormat) +VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount) + #endif diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 5a419bb232..cc9b6758b6 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -113,6 +113,8 @@ RID TextLine::get_rid() const { void TextLine::clear() { TS->shaped_text_clear(rid); + spacing_top = 0; + spacing_bottom = 0; } void TextLine::set_preserve_invalid(bool p_enabled) { @@ -166,6 +168,8 @@ void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) { bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); dirty = true; return res; } @@ -233,17 +237,21 @@ float TextLine::get_width() const { Size2 TextLine::get_size() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_size(rid); + if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y); + } } float TextLine::get_line_ascent() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_ascent(rid); + return TS->shaped_text_get_ascent(rid) + spacing_top; } float TextLine::get_line_descent() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_descent(rid); + return TS->shaped_text_get_descent(rid) + spacing_bottom; } float TextLine::get_line_width() const { @@ -291,10 +299,10 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co float clip_l; if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(rid); + ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.x - ofs.x); } else { - ofs.x += TS->shaped_text_get_ascent(rid); + ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.y - ofs.y); } return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color); @@ -330,10 +338,10 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si float clip_l; if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(rid); + ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.x - ofs.x); } else { - ofs.x += TS->shaped_text_get_ascent(rid); + ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.y - ofs.y); } return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color); @@ -347,6 +355,8 @@ int TextLine::hit_test(float p_coords) const { TextLine::TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, TextServer::Direction p_direction, TextServer::Orientation p_orientation) { rid = TS->create_shaped_text(p_direction, p_orientation); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); } diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index ffa06cc5c1..6ed3558bd9 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -40,6 +40,8 @@ class TextLine : public Reference { GDCLASS(TextLine, Reference); RID rid; + int spacing_top = 0; + int spacing_bottom = 0; bool dirty = true; diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index d4f96ff9e8..fd6dd071eb 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -140,6 +140,8 @@ RID TextParagraph::get_line_rid(int p_line) const { } void TextParagraph::clear() { + spacing_top = 0; + spacing_bottom = 0; for (int i = 0; i < lines.size(); i++) { TS->free(lines[i]); } @@ -187,6 +189,8 @@ TextServer::Orientation TextParagraph::get_orientation() const { bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); dirty_lines = true; return res; } @@ -260,7 +264,11 @@ float TextParagraph::get_width() const { Size2 TextParagraph::get_non_wraped_size() const { const_cast<TextParagraph *>(this)->_shape_lines(); - return TS->shaped_text_get_size(rid); + if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y); + } } Size2 TextParagraph::get_size() const { @@ -270,9 +278,9 @@ Size2 TextParagraph::get_size() const { Size2 lsize = TS->shaped_text_get_size(lines[i]); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { size.x = MAX(size.x, lsize.x); - size.y += lsize.y; + size.y += lsize.y + spacing_top + spacing_bottom; } else { - size.x += lsize.x; + size.x += lsize.x + spacing_top + spacing_bottom; size.y = MAX(size.y, lsize.y); } } @@ -297,9 +305,9 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const { for (int i = 0; i < p_line; i++) { Size2 lsize = TS->shaped_text_get_size(lines[i]); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { - xrect.position.y += lsize.y; + xrect.position.y += lsize.y + spacing_top + spacing_bottom; } else { - xrect.position.x += lsize.x; + xrect.position.x += lsize.x + spacing_top + spacing_bottom; } } return xrect; @@ -308,7 +316,11 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const { Size2 TextParagraph::get_line_size(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), Size2()); - return TS->shaped_text_get_size(lines[p_line]); + if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(lines[p_line]).x, TS->shaped_text_get_size(lines[p_line]).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(lines[p_line]).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(lines[p_line]).y); + } } Vector2i TextParagraph::get_line_range(int p_line) const { @@ -320,13 +332,13 @@ Vector2i TextParagraph::get_line_range(int p_line) const { float TextParagraph::get_line_ascent(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f); - return TS->shaped_text_get_ascent(lines[p_line]); + return TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } float TextParagraph::get_line_descent(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f); - return TS->shaped_text_get_descent(lines[p_line]); + return TS->shaped_text_get_descent(lines[p_line]) + spacing_bottom; } float TextParagraph::get_line_width(int p_line) const { @@ -353,10 +365,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo for (int i = 0; i < lines.size(); i++) { if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_ascent(lines[i]); + ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_ascent(lines[i]); + ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } float length = TS->shaped_text_get_width(lines[i]); if (width > 0) { @@ -389,10 +401,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo TS->shaped_text_draw(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_color); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines[i]); + ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines[i]); + ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } } } @@ -403,10 +415,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli for (int i = 0; i < lines.size(); i++) { if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_ascent(lines[i]); + ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_ascent(lines[i]); + ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } float length = TS->shaped_text_get_width(lines[i]); if (width > 0) { @@ -439,10 +451,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli TS->shaped_text_draw_outline(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines[i]); + ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines[i]); + ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } } } @@ -462,10 +474,12 @@ int TextParagraph::hit_test(const Point2 &p_coords) const { if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines[i]).y)) { return TS->shaped_text_hit_test_position(lines[i], p_coords.x); } + ofs.y += TS->shaped_text_get_size(lines[i]).y + spacing_bottom + spacing_top; } else { if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines[i]).x)) { return TS->shaped_text_hit_test_position(lines[i], p_coords.y); } + ofs.y += TS->shaped_text_get_size(lines[i]).x + spacing_bottom + spacing_top; } } return TS->shaped_text_get_range(rid).y; @@ -477,9 +491,9 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co Vector2 ofs = p_pos; if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(lines[p_line]); + ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } else { - ofs.x += TS->shaped_text_get_ascent(lines[p_line]); + ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } return TS->shaped_text_draw(lines[p_line], p_canvas, ofs, -1, -1, p_color); } @@ -490,9 +504,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_ Vector2 ofs = p_pos; if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(lines[p_line]); + ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } else { - ofs.x += TS->shaped_text_get_ascent(lines[p_line]); + ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } return TS->shaped_text_draw_outline(lines[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color); } @@ -500,8 +514,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_ TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) { rid = TS->create_shaped_text(p_direction, p_orientation); TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); width = p_width; - dirty_lines = true; } TextParagraph::TextParagraph() { diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 587bb6bfc1..f7f49e9058 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -41,6 +41,8 @@ class TextParagraph : public Reference { RID rid; Vector<RID> lines; + int spacing_top = 0; + int spacing_bottom = 0; bool dirty_lines = true; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index dd9f64693e..34129e35da 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -811,8 +811,12 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port #define IS_SYMBOL_CHAR(m_d) (((m_d) >= 'a' && (m_d) <= 'z') || ((m_d) >= 'A' && (m_d) <= 'Z') || ((m_d) >= '0' && (m_d) <= '9') || (m_d) == '_') -String VisualShader::validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const { - String name = p_name; +String VisualShader::validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const { + String name = p_port_name; + + if (name == String()) { + return String(); + } while (name.length() && !IS_INITIAL_CHAR(name[0])) { name = name.substr(1, name.length() - 1); @@ -830,29 +834,28 @@ String VisualShader::validate_port_name(const String &p_name, const List<String> } name = valid_name; + } else { + return String(); } - String valid_name = name; - bool is_equal = false; + List<String> input_names; + List<String> output_names; - for (int i = 0; i < p_input_ports.size(); i++) { - if (name == p_input_ports[i]) { - is_equal = true; - break; + for (int i = 0; i < p_node->get_input_port_count(); i++) { + if (!p_output && i == p_port_id) { + continue; } - } - - if (!is_equal) { - for (int i = 0; i < p_output_ports.size(); i++) { - if (name == p_output_ports[i]) { - is_equal = true; - break; - } + if (name == p_node->get_input_port_name(i)) { + return String(); } } - - if (is_equal) { - name = ""; + for (int i = 0; i < p_node->get_output_port_count(); i++) { + if (p_output && i == p_port_id) { + continue; + } + if (name == p_node->get_output_port_name(i)) { + return String(); + } } return name; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 41c4642ee3..a38c2886e2 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -175,7 +175,7 @@ public: String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const; - String validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const; + String validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const; String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const; VisualShader(); |