From 151e08ac18355099c170a914228cb9d817449af2 Mon Sep 17 00:00:00 2001 From: Yxure <93406322+Yxure@users.noreply.github.com> Date: Thu, 18 Nov 2021 23:47:54 +0100 Subject: [PATCH] Fixed closed path rotation and added auto tilt checkbox --- scene/resources/curve.cpp | 41 +++++++++++++++++++++++++++++++++++++++ scene/resources/curve.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index b530a72033cf..81331b81063a 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -1313,6 +1313,33 @@ void Curve3D::_bake() const { idx++; } + + //Tilt smoothing, paralell rotation frame does not guarantee that the rotation at the beginning of the curve is equal to that at the end of the curve. + //Check out: Wang, W., Juttler, B., Zheng, D., and Liu, Y. 2008. Computation of rotation minimizing frame. + + if (auto_tilts) { + + //Calculate tilt angle difference between first and last baked up vector + Vector3 first_up = up_write[0]; + Vector3 last_up = up_write[pointlist.size() - 1]; + Vector3 tangent = Vector3(0, 0, 0); + + for (int i = 0; i < idx; i++) { + tangent = (w[0] - w[i]); + if (tangent.length_squared() > CMP_EPSILON2) { + break; + } + } + tangent = tangent.normalized(); + float phi = first_up.signed_angle_to(last_up, tangent); + + for (int i = 0; i < idx; i++) { + wt[i] += phi * float(i) / float(idx - 1); + } + } + + + } float Curve3D::get_baked_length() const { @@ -1584,6 +1611,16 @@ bool Curve3D::is_up_vector_enabled() const { return up_vector_enabled; } +void Curve3D::set_auto_tilts(bool p_auto_tilts) { + auto_tilts = p_auto_tilts; + baked_cache_dirty = true; + emit_signal(CoreStringNames::get_singleton()->changed); +} + +bool Curve3D::is_auto_tilts() const { + return auto_tilts; +} + Dictionary Curve3D::_get_data() const { Dictionary dc; @@ -1684,6 +1721,8 @@ void Curve3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bake_interval"), &Curve3D::get_bake_interval); ClassDB::bind_method(D_METHOD("set_up_vector_enabled", "enable"), &Curve3D::set_up_vector_enabled); ClassDB::bind_method(D_METHOD("is_up_vector_enabled"), &Curve3D::is_up_vector_enabled); + ClassDB::bind_method(D_METHOD("set_auto_tilts", "enable"), &Curve3D::set_auto_tilts); + ClassDB::bind_method(D_METHOD("is_auto_tilts"), &Curve3D::is_auto_tilts); ClassDB::bind_method(D_METHOD("get_baked_length"), &Curve3D::get_baked_length); ClassDB::bind_method(D_METHOD("interpolate_baked", "offset", "cubic"), &Curve3D::interpolate_baked, DEFVAL(false)); @@ -1701,6 +1740,8 @@ void Curve3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval"); ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_tilts"), "set_auto_tilts", "is_auto_tilts"); + ADD_GROUP("Up Vector", "up_vector_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "up_vector_enabled"), "set_up_vector_enabled", "is_up_vector_enabled"); } diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 5808fd650861..804ba51161d7 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -232,6 +232,7 @@ class Curve3D : public Resource { float bake_interval = 0.2; bool up_vector_enabled = true; + bool auto_tilts= true; void _bake_segment3d(Map &r_bake, float p_begin, float 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, float p_tol) const; Dictionary _get_data() const; @@ -261,6 +262,8 @@ class Curve3D : public Resource { float get_bake_interval() const; void set_up_vector_enabled(bool p_enable); bool is_up_vector_enabled() const; + void set_auto_tilts(bool p_auto_tilts); + bool is_auto_tilts() const; float get_baked_length() const; Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const;