diff options
| -rw-r--r-- | core/io/image.cpp | 2 | ||||
| -rw-r--r-- | doc/classes/ConcavePolygonShape2D.xml | 2 | ||||
| -rw-r--r-- | doc/classes/ConcavePolygonShape3D.xml | 2 | ||||
| -rw-r--r-- | editor/editor_node.cpp | 25 | ||||
| -rw-r--r-- | editor/editor_node.h | 2 | ||||
| -rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 4 | ||||
| -rw-r--r-- | modules/csg/csg_shape.cpp | 5 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.cpp | 8 | ||||
| -rw-r--r-- | scene/3d/bone_attachment_3d.cpp | 10 | ||||
| -rw-r--r-- | scene/3d/bone_attachment_3d.h | 4 | ||||
| -rw-r--r-- | scene/3d/soft_body_3d.cpp | 1 | ||||
| -rw-r--r-- | scene/resources/particle_process_material.cpp | 22 | ||||
| -rw-r--r-- | scene/resources/particle_process_material.h | 4 | ||||
| -rw-r--r-- | scene/resources/primitive_meshes.cpp | 35 |
14 files changed, 97 insertions, 29 deletions
diff --git a/core/io/image.cpp b/core/io/image.cpp index 15d0182dfc..ce08b417a8 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -3773,7 +3773,7 @@ void Image::fix_alpha_edges() { } int closest_dist = max_dist; - uint8_t closest_color[3]; + uint8_t closest_color[3] = { 0 }; int from_x = MAX(0, j - max_radius); int to_x = MIN(width - 1, j + max_radius); diff --git a/doc/classes/ConcavePolygonShape2D.xml b/doc/classes/ConcavePolygonShape2D.xml index 31e28bc714..6baf0f380f 100644 --- a/doc/classes/ConcavePolygonShape2D.xml +++ b/doc/classes/ConcavePolygonShape2D.xml @@ -5,7 +5,7 @@ </brief_description> <description> A 2D polyline shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [constant CollisionPolygon2D.BUILD_SEGMENTS] mode. - Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConvexPolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection. + Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConcavePolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection. [b]Note:[/b] When used for collision, [ConcavePolygonShape2D] is intended to work with static [CollisionShape2D] nodes like [StaticBody2D] and will likely not behave well for [CharacterBody2D]s or [RigidBody2D]s in a mode other than Static. [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape2D] is hollow, so it won't detect a collision. [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest 2D collision shape to check collisions against. Its use should generally be limited to level geometry. If the polyline is closed, [CollisionPolygon2D]'s [constant CollisionPolygon2D.BUILD_SOLIDS] mode can be used, which decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s documentation for instructions. diff --git a/doc/classes/ConcavePolygonShape3D.xml b/doc/classes/ConcavePolygonShape3D.xml index c0d0f43010..7e4df2073f 100644 --- a/doc/classes/ConcavePolygonShape3D.xml +++ b/doc/classes/ConcavePolygonShape3D.xml @@ -5,7 +5,7 @@ </brief_description> <description> A 3D trimesh shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. - Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConvexPolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection. + Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConcavePolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection. [b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than Static. [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape3D] is hollow, so it won't detect a collision. [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest 3D collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, [ConvexPolygonShape3D] should be used. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index f73eb81473..cc35be1732 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -47,6 +47,7 @@ #include "core/version.h" #include "editor/editor_string_names.h" #include "main/main.h" +#include "scene/3d/bone_attachment_3d.h" #include "scene/gui/color_picker.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" @@ -6066,6 +6067,27 @@ void EditorNode::_file_access_close_error_notify_impl(const String &p_str) { add_io_error(vformat(TTR("Unable to write to file '%s', file in use, locked or lacking permissions."), p_str)); } +// Since we felt that a bespoke NOTIFICATION might not be desirable, this function +// provides the hardcoded callbacks to address known bugs which occur on certain +// nodes during reimport. +// Ideally, we should probably agree on a standardized method name which could be +// called from here instead. +void EditorNode::_notify_scene_updated(Node *p_node) { + Skeleton3D *skel_3d = Object::cast_to<Skeleton3D>(p_node); + if (skel_3d) { + skel_3d->reset_bone_poses(); + } else { + BoneAttachment3D *attachment = Object::cast_to<BoneAttachment3D>(p_node); + if (attachment) { + attachment->notify_rebind_required(); + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _notify_scene_updated(p_node->get_child(i)); + } +} + void EditorNode::reload_scene(const String &p_path) { int scene_idx = -1; for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { @@ -6449,10 +6471,11 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins } } } + // Cleanup the history of the changes. editor_history.cleanup_history(); - current_edited_scene->propagate_notification(NOTIFICATION_NODE_RECACHE_REQUESTED); + _notify_scene_updated(current_edited_scene); } edited_scene_map.clear(); } diff --git a/editor/editor_node.h b/editor/editor_node.h index bc7da69e75..33de096d35 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -692,6 +692,8 @@ private: void _begin_first_scan(); + void _notify_scene_updated(Node *p_node); + protected: friend class FileSystemDock; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 440496b948..fad0baaf66 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1265,7 +1265,9 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool player->seek(pos, true, true); player->seek(pos + delta, true, true); } else { - player->stop(); + if (player->is_playing()) { + player->stop(); + } player->seek(pos, true, true); } } diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 0656f8224c..0fc61dfe92 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -573,6 +573,11 @@ void CSGShape3D::_notification(int p_what) { // Update this node's parent only if its own visibility has changed, not the visibility of parent nodes parent_shape->_make_dirty(); } + if (is_visible()) { + _update_debug_collision_shape(); + } else { + _clear_debug_collision_shape(); + } last_visible = is_visible(); } break; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 47fc58fe43..ecfb035b82 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -5846,6 +5846,10 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent); p_scene_parent->add_child(bone_attachment, true); + + // Find the correct bone_idx so we can properly serialize it. + bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name())); + bone_attachment->set_owner(p_scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -5949,6 +5953,10 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, p_node_index); p_scene_parent->add_child(bone_attachment, true); + + // Find the correct bone_idx so we can properly serialize it. + bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name())); + bone_attachment->set_owner(p_scene_root); // There is no gltf_node that represent this, so just directly create a unique name diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 60fb6f87c9..45de9b907c 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -349,6 +349,16 @@ void BoneAttachment3D::notify_skeleton_bones_renamed(Node *p_base_scene, Skeleto } } } + +void BoneAttachment3D::notify_rebind_required() { + // Ensures bindings are properly updated after a scene reload. + _check_unbind(); + if (use_external_skeleton) { + _update_external_skeleton_cache(); + } + bone_idx = -1; + _check_bind(); +} #endif // TOOLS_ENABLED BoneAttachment3D::BoneAttachment3D() { diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index bfa3db476d..1bf44c2756 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -89,6 +89,10 @@ public: virtual void on_bone_pose_update(int p_bone_index); +#ifdef TOOLS_ENABLED + virtual void notify_rebind_required(); +#endif + BoneAttachment3D(); }; diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 1f12f96fb3..db2c0e1387 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -471,6 +471,7 @@ void SoftBody3D::_become_mesh_owner() { uint32_t surface_format = mesh->surface_get_format(0); surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + surface_format &= ~Mesh::ARRAY_FLAG_COMPRESS_ATTRIBUTES; Ref<ArrayMesh> soft_mesh; soft_mesh.instantiate(); diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 968ec77d1d..410fe6ea3e 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -31,7 +31,6 @@ #include "particle_process_material.h" #include "core/version.h" -#include "scene/resources/curve_texture.h" Mutex ParticleProcessMaterial::material_mutex; SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; @@ -672,13 +671,18 @@ void ParticleProcessMaterial::_update_shader() { code += " float orbit_amount = param.orbit_velocity;\n"; if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + CurveTexture *texture = Object::cast_to<CurveTexture>(tex_parameters[PARAM_ORBIT_VELOCITY].ptr()); + if (texture) { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + } else { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).b;\n"; + } } code += " if (orbit_amount != 0.0) {\n"; code += " vec3 pos = transform[3].xyz;\n"; code += " vec3 org = emission_transform[3].xyz;\n"; code += " vec3 diff = pos - org;\n"; - code += " float ang = orbit_amount * pi * 2.0;\n"; + code += " float ang = orbit_amount * pi * 2.0 * delta;\n"; code += " mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));\n"; code += " displacement.xy -= diff.xy;\n"; code += " displacement.xy += rot * diff.xy;\n"; @@ -687,8 +691,8 @@ void ParticleProcessMaterial::_update_shader() { code += " vec3 orbit_velocities = vec3(param.orbit_velocity);\n"; code += " orbit_velocities *= texture(orbit_velocity_curve, vec2(lifetime)).rgb;\n"; - code += " orbit_velocities *= degree_to_rad;\n"; - code += " orbit_velocities *= delta/total_lifetime; // we wanna process those by the delta angle\n"; + code += " orbit_velocities *= pi * 2.0;\n"; + code += " orbit_velocities *= delta; // we wanna process those by the delta angle\n"; code += " //vec3 local_velocity_pivot = ((emission_transform) * vec4(velocity_pivot,1.0)).xyz;\n"; code += " // X axis\n"; code += " vec3 local_pos = (inverse(emission_transform) * transform[3]).xyz;\n"; @@ -719,7 +723,7 @@ void ParticleProcessMaterial::_update_shader() { code += " local_pos -= velocity_pivot;\n"; code += " local_pos.z = 0.;\n"; code += " mat3 z_rotation_mat = mat3(\n"; - code += " vec3(cos(orbit_velocities.z),-sin(orbit_velocities.z),0.0),\n"; + code += " vec3(cos(orbit_velocities.z),sin(orbit_velocities.z),0.0),\n"; code += " vec3(-sin(orbit_velocities.z),cos(orbit_velocities.z), 0.0),\n"; code += " vec3(0.0,0.0,1.0)\n"; code += " );\n"; @@ -1387,7 +1391,7 @@ void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Tex } break; case PARAM_ORBIT_VELOCITY: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, tex_rid); - _adjust_curve_range(p_texture, -500, 500); + _adjust_curve_range(p_texture, -2, 2); notify_property_list_changed(); } break; case PARAM_LINEAR_ACCEL: { @@ -2100,8 +2104,8 @@ void ParticleProcessMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_DIRECTIONAL_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "directional_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_DIRECTIONAL_VELOCITY); ADD_SUBGROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture,CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_SUBGROUP("Radial Velocity", "radial_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_VELOCITY); diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h index d3d8f89a15..5ed8b61c77 100644 --- a/scene/resources/particle_process_material.h +++ b/scene/resources/particle_process_material.h @@ -33,6 +33,7 @@ #include "core/templates/rid.h" #include "core/templates/self_list.h" +#include "scene/resources/curve_texture.h" #include "scene/resources/material.h" /* @@ -125,6 +126,7 @@ private: uint64_t alpha_curve : 1; uint64_t emission_curve : 1; uint64_t has_initial_ramp : 1; + uint64_t orbit_uses_curve_xyz : 1; MaterialKey() { memset(this, 0, sizeof(MaterialKey)); @@ -165,6 +167,8 @@ private: mk.alpha_curve = alpha_curve.is_valid() ? 1 : 0; mk.emission_curve = emission_curve.is_valid() ? 1 : 0; mk.has_initial_ramp = color_initial_ramp.is_valid() ? 1 : 0; + CurveXYZTexture *texture = Object::cast_to<CurveXYZTexture>(tex_parameters[PARAM_ORBIT_VELOCITY].ptr()); + mk.orbit_uses_curve_xyz = texture ? 1 : 0; for (int i = 0; i < PARAM_MAX; i++) { if (tex_parameters[i].is_valid()) { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index b323710743..13791d8c2b 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1300,7 +1300,11 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const { points.push_back(Vector3(-x, z, 0.0) + center_offset); } normals.push_back(normal); - ADD_TANGENT(1.0, 0.0, 0.0, 1.0); + if (orientation == FACE_X) { + ADD_TANGENT(0.0, 0.0, -1.0, 1.0); + } else { + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); + } uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */ point++; @@ -2722,7 +2726,6 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph GlyphMeshData &gl_data = cache[p_key]; Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index); - Vector2 origin = Vector2(p_gl.x_off, p_gl.y_off) * pixel_size; PackedVector3Array points = d["points"]; PackedInt32Array contours = d["contours"]; @@ -2742,7 +2745,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph for (int32_t j = start; j <= end; j++) { if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) { // Point on the curve. - Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size + origin; + Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size; polygon.push_back(ContourPoint(p, true)); } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { // Conic Bezier arc. @@ -2776,7 +2779,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t2 = t * t; Vector2 point = p1 + omt2 * (p0 - p1) + t2 * (p2 - p1); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -2810,7 +2813,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t = step; while (t < 1.0) { Vector2 point = p0.bezier_interpolate(p1, p2, p3, t); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -3045,6 +3048,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); _generate_glyph_mesh_data(key, glyphs[j]); GlyphMeshData &gl_data = cache[key]; + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; p_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); i_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); @@ -3057,10 +3061,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { } for (int r = 0; r < glyphs[j].repeat; r++) { - min_p.x = MIN(gl_data.min_p.x + offset.x, min_p.x); - min_p.y = MIN(gl_data.min_p.y - offset.y, min_p.y); - max_p.x = MAX(gl_data.max_p.x + offset.x, max_p.x); - max_p.y = MAX(gl_data.max_p.y - offset.y, max_p.y); + min_p.x = MIN(gl_data.min_p.x + offset.x + gl_of.x, min_p.x); + min_p.y = MIN(gl_data.min_p.y - offset.y + gl_of.y, min_p.y); + max_p.x = MAX(gl_data.max_p.x + offset.x + gl_of.x, max_p.x); + max_p.y = MAX(gl_data.max_p.y - offset.y + gl_of.y, max_p.y); offset.x += glyphs[j].advance * pixel_size; } @@ -3126,12 +3130,13 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { int64_t ts = gl_data.triangles.size(); const Vector2 *ts_ptr = gl_data.triangles.ptr(); + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; for (int r = 0; r < glyphs[j].repeat; r++) { for (int k = 0; k < ts; k += 3) { // Add front face. for (int l = 0; l < 3; l++) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); if (has_depth) { @@ -3149,7 +3154,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { if (has_depth) { // Add back face. for (int l = 2; l >= 0; l--) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, -depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); @@ -3182,10 +3187,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); Vector3 quad_faces[4] = { - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, depth / 2.0), }; for (int m = 0; m < 4; m++) { const Vector2 &d = ((m % 2) == 0) ? d1 : d2; |
