diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/light_2d.cpp | 5 | ||||
-rw-r--r-- | scene/2d/light_2d.h | 2 | ||||
-rw-r--r-- | scene/3d/light_3d.cpp | 5 | ||||
-rw-r--r-- | scene/3d/light_3d.h | 2 | ||||
-rw-r--r-- | scene/3d/node_3d.cpp | 70 | ||||
-rw-r--r-- | scene/3d/node_3d.h | 1 | ||||
-rw-r--r-- | scene/gui/control.cpp | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 5 | ||||
-rw-r--r-- | scene/main/node.h | 1 | ||||
-rw-r--r-- | scene/resources/curve.cpp | 72 | ||||
-rw-r--r-- | scene/resources/curve.h | 13 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 1 | ||||
-rw-r--r-- | scene/resources/importer_mesh.cpp | 8 | ||||
-rw-r--r-- | scene/resources/navigation_mesh.cpp | 24 | ||||
-rw-r--r-- | scene/resources/navigation_mesh.h | 8 |
15 files changed, 177 insertions, 42 deletions
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 28d9b284e6..0481a58431 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -30,6 +30,11 @@ #include "light_2d.h" +void Light2D::owner_changed_notify() { + // For cases where owner changes _after_ entering tree (as example, editor editing). + _update_light_visibility(); +} + void Light2D::_update_light_visibility() { if (!is_inside_tree()) { return; diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index f7b1f420e3..a84b6516c0 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -73,6 +73,8 @@ private: void _update_light_visibility(); + virtual void owner_changed_notify() override; + protected: _FORCE_INLINE_ RID _get_light() const { return canvas_light; } void _notification(int p_what); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 28614d7cae..6c999d85e2 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -176,6 +176,11 @@ Ref<Texture2D> Light3D::get_projector() const { return projector; } +void Light3D::owner_changed_notify() { + // For cases where owner changes _after_ entering tree (as example, editor editing). + _update_visibility(); +} + void Light3D::_update_visibility() { if (!is_inside_tree()) { return; diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index 383fa644e5..6ff332df5a 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -85,6 +85,8 @@ private: // bind helpers + virtual void owner_changed_notify() override; + protected: RID light; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 6e36815f2b..78d53439e8 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -85,10 +85,13 @@ void Node3D::_notify_dirty() { } void Node3D::_update_local_transform() const { - if (this->get_rotation_edit_mode() != ROTATION_EDIT_MODE_BASIS) { - data.local_transform = data.local_transform.orthogonalized(); + if (this->get_rotation_edit_mode() == ROTATION_EDIT_MODE_EULER) { + data.local_transform.basis.set_euler(data.rotation, data.rotation_order); + data.local_transform.basis.scale_local(data.scale); + } else if (this->get_rotation_edit_mode() == ROTATION_EDIT_MODE_QUATERNION) { + data.local_transform.basis = Basis(data.quaternion); + data.local_transform.basis.scale_local(data.scale); } - data.local_transform.basis.set_euler_scale(data.rotation, data.scale); data.dirty &= ~DIRTY_LOCAL; } @@ -212,7 +215,18 @@ void Node3D::set_basis(const Basis &p_basis) { set_transform(Transform3D(p_basis, data.local_transform.origin)); } void Node3D::set_quaternion(const Quaternion &p_quaternion) { - set_transform(Transform3D(Basis(p_quaternion), data.local_transform.origin)); + if (data.dirty & DIRTY_VECTORS) { + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); + data.scale = get_transform().basis.get_scale(); + data.dirty &= ~DIRTY_VECTORS; + } + + data.quaternion = p_quaternion; + data.dirty |= DIRTY_LOCAL; + _propagate_transform_changed(this); + if (data.notify_local_transform) { + notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); + } } void Node3D::set_transform(const Transform3D &p_transform) { @@ -228,7 +242,14 @@ Basis Node3D::get_basis() const { return get_transform().basis; } Quaternion Node3D::get_quaternion() const { - return Quaternion(get_transform().basis); + if (data.dirty & DIRTY_VECTORS) { + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); + data.scale = get_transform().basis.get_scale(); + data.dirty &= ~DIRTY_VECTORS; + } + + return data.quaternion; } void Node3D::set_global_transform(const Transform3D &p_transform) { @@ -255,9 +276,9 @@ Transform3D Node3D::get_global_transform() const { } if (data.parent && !data.top_level_active) { - data.global_transform = data.parent->get_global_transform() * data.local_transform; + data.global_transform = data.parent->get_global_transform() * get_transform(); } else { - data.global_transform = data.local_transform; + data.global_transform = get_transform(); } if (data.disable_scale) { @@ -303,7 +324,7 @@ Transform3D Node3D::get_relative_transform(const Node *p_parent) const { } void Node3D::set_position(const Vector3 &p_position) { - data.local_transform.origin = p_position; + get_transform().origin = p_position; _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -314,9 +335,13 @@ void Node3D::set_rotation_edit_mode(RotationEditMode p_mode) { if (data.rotation_edit_mode == p_mode) { return; } + + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); + data.scale = get_transform().basis.get_scale(); data.rotation_edit_mode = p_mode; - // Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS. + // Shearing is not allowed except in ROTATION_EDIT_MODE_BASIS, so validate local_transform. data.dirty |= DIRTY_LOCAL; _propagate_transform_changed(this); if (data.notify_local_transform) { @@ -340,8 +365,9 @@ void Node3D::set_rotation_order(RotationOrder p_order) { ERR_FAIL_INDEX(int32_t(order), 6); if (data.dirty & DIRTY_VECTORS) { - data.rotation = data.local_transform.basis.get_euler_normalized(order); - data.scale = data.local_transform.basis.get_scale(); + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(order); + data.scale = get_transform().basis.get_scale(); data.dirty &= ~DIRTY_VECTORS; } else { data.rotation = Basis::from_euler(data.rotation, data.rotation_order).get_euler_normalized(order); @@ -359,7 +385,8 @@ Node3D::RotationOrder Node3D::get_rotation_order() const { void Node3D::set_rotation(const Vector3 &p_euler_rad) { if (data.dirty & DIRTY_VECTORS) { - data.scale = data.local_transform.basis.get_scale(); + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.scale = get_transform().basis.get_scale(); data.dirty &= ~DIRTY_VECTORS; } @@ -373,7 +400,8 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) { void Node3D::set_scale(const Vector3 &p_scale) { if (data.dirty & DIRTY_VECTORS) { - data.rotation = data.local_transform.basis.get_euler_normalized(data.rotation_order); + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); data.dirty &= ~DIRTY_VECTORS; } @@ -386,14 +414,14 @@ void Node3D::set_scale(const Vector3 &p_scale) { } Vector3 Node3D::get_position() const { - return data.local_transform.origin; + return get_transform().origin; } Vector3 Node3D::get_rotation() const { if (data.dirty & DIRTY_VECTORS) { - data.scale = data.local_transform.basis.get_scale(); - data.rotation = data.local_transform.basis.get_euler_normalized(data.rotation_order); - + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); + data.scale = get_transform().basis.get_scale(); data.dirty &= ~DIRTY_VECTORS; } @@ -402,9 +430,9 @@ Vector3 Node3D::get_rotation() const { Vector3 Node3D::get_scale() const { if (data.dirty & DIRTY_VECTORS) { - data.scale = data.local_transform.basis.get_scale(); - data.rotation = data.local_transform.basis.get_euler_normalized(data.rotation_order); - + data.quaternion = get_transform().basis.get_rotation_quaternion(); + data.rotation = get_transform().basis.get_euler_normalized(data.rotation_order); + data.scale = get_transform().basis.get_scale(); data.dirty &= ~DIRTY_VECTORS; } @@ -865,7 +893,7 @@ Variant Node3D::property_get_revert(const String &p_name) { } else if (p_name == "quaternion") { Variant variant = PropertyUtils::get_property_default_value(this, "transform", &valid); if (valid && variant.get_type() == Variant::Type::TRANSFORM3D) { - r_ret = Quaternion(Transform3D(variant).get_basis()); + r_ret = Transform3D(variant).get_basis().get_rotation_quaternion(); } else { return Quaternion(); } diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 6d857a83ea..3d561e8620 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -81,6 +81,7 @@ private: mutable Transform3D global_transform; mutable Transform3D local_transform; mutable Basis::EulerOrder rotation_order = Basis::EULER_ORDER_YXZ; + mutable Quaternion quaternion; mutable Vector3 rotation; mutable Vector3 scale = Vector3(1, 1, 1); mutable RotationEditMode rotation_edit_mode = ROTATION_EDIT_MODE_EULER; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 036d00345d..7b97b0fa47 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -3286,7 +3286,7 @@ void Control::_bind_methods() { ADD_GROUP("Layout", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index b5caec3fc3..a30eb036db 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -420,6 +420,9 @@ void Node::move_child_notify(Node *p_child) { // to be used when not wanted } +void Node::owner_changed_notify() { +} + void Node::set_physics_process(bool p_process) { if (data.physics_process == p_process) { return; @@ -1544,6 +1547,8 @@ void Node::_set_owner_nocheck(Node *p_owner) { data.owner = p_owner; data.owner->data.owned.push_back(this); data.OW = data.owner->data.owned.back(); + + owner_changed_notify(); } void Node::_release_unique_name_in_owner() { diff --git a/scene/main/node.h b/scene/main/node.h index 8de6c1ce69..5b7bc0a587 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -208,6 +208,7 @@ protected: virtual void add_child_notify(Node *p_child); virtual void remove_child_notify(Node *p_child); virtual void move_child_notify(Node *p_child); + virtual void owner_changed_notify(); void _propagate_replace_owner(Node *p_owner, Node *p_by_owner); diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index c99f71b13e..96cf7bb708 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -56,12 +56,13 @@ void Curve::set_point_count(int p_count) { mark_dirty(); } else { for (int i = p_count - _points.size(); i > 0; i--) { - add_point(Vector2()); + _add_point(Vector2()); } } + notify_property_list_changed(); } -int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) { +int Curve::_add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) { // Add a point and preserve order // Curve bounds is in 0..1 @@ -112,6 +113,13 @@ int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_t return ret; } +int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) { + int ret = _add_point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode); + notify_property_list_changed(); + + return ret; +} + int Curve::get_index(real_t p_offset) const { // Lower-bound float binary search @@ -217,15 +225,21 @@ Curve::TangentMode Curve::get_point_right_mode(int p_index) const { return _points[p_index].right_mode; } -void Curve::remove_point(int p_index) { +void Curve::_remove_point(int p_index) { ERR_FAIL_INDEX(p_index, _points.size()); _points.remove_at(p_index); mark_dirty(); } +void Curve::remove_point(int p_index) { + _remove_point(p_index); + notify_property_list_changed(); +} + void Curve::clear_points() { _points.clear(); mark_dirty(); + notify_property_list_changed(); } void Curve::set_point_value(int p_index, real_t p_position) { @@ -238,8 +252,8 @@ void Curve::set_point_value(int p_index, real_t p_position) { int Curve::set_point_offset(int p_index, real_t p_offset) { ERR_FAIL_INDEX_V(p_index, _points.size(), -1); Point p = _points[p_index]; - remove_point(p_index); - int i = add_point(Vector2(p_offset, p.position.y)); + _remove_point(p_index); + int i = _add_point(Vector2(p_offset, p.position.y)); _points.write[i].left_tangent = p.left_tangent; _points.write[i].right_tangent = p.right_tangent; _points.write[i].left_mode = p.left_mode; @@ -370,7 +384,6 @@ real_t Curve::interpolate_local_nocheck(int p_index, real_t p_local_offset) cons void Curve::mark_dirty() { _baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); - notify_property_list_changed(); } Array Curve::get_data() const { @@ -429,6 +442,7 @@ void Curve::set_data(const Array p_input) { } mark_dirty(); + notify_property_list_changed(); } void Curve::bake() { @@ -636,16 +650,15 @@ void Curve2D::set_point_count(int p_count) { if (points.size() >= p_count) { points.resize(p_count); mark_dirty(); - baked_cache_dirty = true; - emit_signal(CoreStringNames::get_singleton()->changed); } else { for (int i = p_count - points.size(); i > 0; i--) { - add_point(Vector2()); + _add_point(Vector2()); } } + notify_property_list_changed(); } -void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) { +void Curve2D::_add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) { Point n; n.position = p_position; n.in = p_in; @@ -659,6 +672,11 @@ void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Ve mark_dirty(); } +void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) { + _add_point(p_position, p_in, p_out, p_atpos); + notify_property_list_changed(); +} + void Curve2D::set_point_position(int p_index, const Vector2 &p_position) { ERR_FAIL_INDEX(p_index, points.size()); @@ -695,16 +713,22 @@ Vector2 Curve2D::get_point_out(int p_index) const { return points[p_index].out; } -void Curve2D::remove_point(int p_index) { +void Curve2D::_remove_point(int p_index) { ERR_FAIL_INDEX(p_index, points.size()); points.remove_at(p_index); mark_dirty(); } +void Curve2D::remove_point(int p_index) { + _remove_point(p_index); + notify_property_list_changed(); +} + void Curve2D::clear_points() { if (!points.is_empty()) { points.clear(); mark_dirty(); + notify_property_list_changed(); } } @@ -739,7 +763,6 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const { void Curve2D::mark_dirty() { baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); - notify_property_list_changed(); } void Curve2D::_bake_segment2d(RBMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const { @@ -1054,7 +1077,8 @@ void Curve2D::_set_data(const Dictionary &p_data) { points.write[i].position = r[i * 3 + 2]; } - baked_cache_dirty = true; + mark_dirty(); + notify_property_list_changed(); } PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) const { @@ -1205,12 +1229,13 @@ void Curve3D::set_point_count(int p_count) { mark_dirty(); } else { for (int i = p_count - points.size(); i > 0; i--) { - add_point(Vector3()); + _add_point(Vector3()); } } + notify_property_list_changed(); } -void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) { +void Curve3D::_add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) { Point n; n.position = p_position; n.in = p_in; @@ -1224,6 +1249,11 @@ void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Ve mark_dirty(); } +void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) { + _add_point(p_position, p_in, p_out, p_atpos); + notify_property_list_changed(); +} + void Curve3D::set_point_position(int p_index, const Vector3 &p_position) { ERR_FAIL_INDEX(p_index, points.size()); @@ -1272,16 +1302,22 @@ Vector3 Curve3D::get_point_out(int p_index) const { return points[p_index].out; } -void Curve3D::remove_point(int p_index) { +void Curve3D::_remove_point(int p_index) { ERR_FAIL_INDEX(p_index, points.size()); points.remove_at(p_index); mark_dirty(); } +void Curve3D::remove_point(int p_index) { + _remove_point(p_index); + notify_property_list_changed(); +} + void Curve3D::clear_points() { if (!points.is_empty()) { points.clear(); mark_dirty(); + notify_property_list_changed(); } } @@ -1316,7 +1352,6 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const { void Curve3D::mark_dirty() { baked_cache_dirty = true; emit_signal(CoreStringNames::get_singleton()->changed); - notify_property_list_changed(); } void Curve3D::_bake_segment3d(RBMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const { @@ -1839,7 +1874,8 @@ void Curve3D::_set_data(const Dictionary &p_data) { points.write[i].tilt = rt[i]; } - baked_cache_dirty = true; + mark_dirty(); + notify_property_list_changed(); } PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) const { diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 834e7ffa07..08807b1b6e 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -83,7 +83,6 @@ public: real_t right_tangent = 0, TangentMode left_mode = TANGENT_FREE, TangentMode right_mode = TANGENT_FREE); - void remove_point(int p_index); void clear_points(); @@ -137,6 +136,12 @@ protected: private: void mark_dirty(); + int _add_point(Vector2 p_position, + real_t left_tangent = 0, + real_t right_tangent = 0, + TangentMode left_mode = TANGENT_FREE, + TangentMode right_mode = TANGENT_FREE); + void _remove_point(int p_index); Vector<Point> _points; bool _baked_cache_dirty = false; @@ -184,6 +189,9 @@ class Curve2D : public Resource { bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + void _add_point(const Vector2 &p_position, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1); + void _remove_point(int p_index); + protected: static void _bind_methods(); @@ -256,6 +264,9 @@ class Curve3D : public Resource { bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + void _add_point(const Vector3 &p_position, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1); + void _remove_point(int p_index); + protected: static void _bind_methods(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 5fcaf8f2c4..401aeb4889 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -570,7 +570,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Window theme->set_stylebox("embedded_border", "Window", sb_expand(make_flat_stylebox(style_popup_color, 10, 28, 10, 8), 8, 32, 8, 6)); - theme->set_constant("scaleborder_size", "Window", 4 * scale); theme->set_font("title_font", "Window", Ref<Font>()); theme->set_font_size("title_font_size", "Window", -1); diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 71640357b9..293fdd6f05 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -331,6 +331,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli bool is_uvs_close = (!uvs_ptr || uvs_ptr[j].distance_squared_to(uvs_ptr[idx.second]) < CMP_EPSILON2); bool is_uv2s_close = (!uv2s_ptr || uv2s_ptr[j].distance_squared_to(uv2s_ptr[idx.second]) < CMP_EPSILON2); + ERR_FAIL_INDEX(idx.second, normals.size()); bool is_normals_close = normals[idx.second].dot(n) > normal_merge_threshold; if (is_uvs_close && is_uv2s_close && is_normals_close) { vertex_remap.push_back(idx.first); @@ -1046,6 +1047,10 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, PackedVector3Array rnormals = arrays[Mesh::ARRAY_NORMAL]; + if (!rnormals.size()) { + continue; + } + int vertex_ofs = vertices.size() / 3; vertices.resize((vertex_ofs + vc) * 3); @@ -1086,6 +1091,9 @@ Error ImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, } else { for (int j = 0; j < ic / 3; j++) { + ERR_FAIL_INDEX_V(rindices[j * 3 + 0], rvertices.size(), ERR_INVALID_DATA); + ERR_FAIL_INDEX_V(rindices[j * 3 + 1], rvertices.size(), ERR_INVALID_DATA); + ERR_FAIL_INDEX_V(rindices[j * 3 + 2], rvertices.size(), ERR_INVALID_DATA); Vector3 p0 = transform.xform(rvertices[rindices[j * 3 + 0]]); Vector3 p1 = transform.xform(rvertices[rindices[j * 3 + 1]]); Vector3 p2 = transform.xform(rvertices[rindices[j * 3 + 2]]); diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 784ecc3a4d..a808ead66b 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -272,6 +272,24 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const { return filter_walkable_low_height_spans; } +void NavigationMesh::set_filter_baking_aabb(const AABB &p_aabb) { + filter_baking_aabb = p_aabb; + notify_property_list_changed(); +} + +AABB NavigationMesh::get_filter_baking_aabb() const { + return filter_baking_aabb; +} + +void NavigationMesh::set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset) { + filter_baking_aabb_offset = p_aabb_offset; + notify_property_list_changed(); +} + +Vector3 NavigationMesh::get_filter_baking_aabb_offset() const { + return filter_baking_aabb_offset; +} + void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) { vertices = p_vertices; notify_property_list_changed(); @@ -469,6 +487,10 @@ void NavigationMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &NavigationMesh::set_filter_walkable_low_height_spans); ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &NavigationMesh::get_filter_walkable_low_height_spans); + ClassDB::bind_method(D_METHOD("set_filter_baking_aabb", "baking_aabb"), &NavigationMesh::set_filter_baking_aabb); + ClassDB::bind_method(D_METHOD("get_filter_baking_aabb"), &NavigationMesh::get_filter_baking_aabb); + ClassDB::bind_method(D_METHOD("set_filter_baking_aabb_offset", "baking_aabb_offset"), &NavigationMesh::set_filter_baking_aabb_offset); + ClassDB::bind_method(D_METHOD("get_filter_baking_aabb_offset"), &NavigationMesh::get_filter_baking_aabb_offset); ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationMesh::set_vertices); ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationMesh::get_vertices); @@ -516,6 +538,8 @@ void NavigationMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "filter_baking_aabb"), "set_filter_baking_aabb", "get_filter_baking_aabb"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "filter_baking_aabb_offset"), "set_filter_baking_aabb_offset", "get_filter_baking_aabb_offset"); BIND_ENUM_CONSTANT(SAMPLE_PARTITION_WATERSHED); BIND_ENUM_CONSTANT(SAMPLE_PARTITION_MONOTONE); diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 93c1c11876..40b275c792 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -117,6 +117,8 @@ protected: bool filter_low_hanging_obstacles = false; bool filter_ledge_spans = false; bool filter_walkable_low_height_spans = false; + AABB filter_baking_aabb; + Vector3 filter_baking_aabb_offset; public: // Recast settings @@ -186,6 +188,12 @@ public: void set_filter_walkable_low_height_spans(bool p_value); bool get_filter_walkable_low_height_spans() const; + void set_filter_baking_aabb(const AABB &p_aabb); + AABB get_filter_baking_aabb() const; + + void set_filter_baking_aabb_offset(const Vector3 &p_aabb_offset); + Vector3 get_filter_baking_aabb_offset() const; + void create_from_mesh(const Ref<Mesh> &p_mesh); void set_vertices(const Vector<Vector3> &p_vertices); |