summaryrefslogtreecommitdiffstats
path: root/scene/resources/curve.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/curve.cpp')
-rw-r--r--scene/resources/curve.cpp79
1 files changed, 62 insertions, 17 deletions
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 12ee36654d..2e49022c29 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -1551,6 +1551,9 @@ void Curve3D::_bake() const {
baked_cache_dirty = false;
if (points.size() == 0) {
+#ifdef TOOLS_ENABLED
+ points_in_cache.clear();
+#endif
baked_point_cache.clear();
baked_tilt_cache.clear();
baked_dist_cache.clear();
@@ -1561,6 +1564,11 @@ void Curve3D::_bake() const {
}
if (points.size() == 1) {
+#ifdef TOOLS_ENABLED
+ points_in_cache.resize(1);
+ points_in_cache.set(0, 0);
+#endif
+
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].position);
baked_tilt_cache.resize(1);
@@ -1584,10 +1592,18 @@ void Curve3D::_bake() const {
{
Vector<RBMap<real_t, Vector3>> midpoints = _tessellate_even_length(10, bake_interval);
+#ifdef TOOLS_ENABLED
+ points_in_cache.resize(points.size());
+ points_in_cache.set(0, 0);
+#endif
+
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
pc++;
pc += midpoints[i].size();
+#ifdef TOOLS_ENABLED
+ points_in_cache.set(i + 1, pc - 1);
+#endif
}
baked_point_cache.resize(pc);
@@ -1791,6 +1807,22 @@ real_t Curve3D::_sample_baked_tilt(Interval p_interval) const {
return Math::lerp(r[idx], r[idx + 1], frac);
}
+// Internal method for getting posture at a baked point. Assuming caller
+// make all sanity checks.
+Basis Curve3D::_compose_posture(int p_index) const {
+ Vector3 forward = baked_forward_vector_cache[p_index];
+
+ Vector3 up;
+ if (up_vector_enabled) {
+ up = baked_up_vector_cache[p_index];
+ } else {
+ up = Vector3(0.0, 1.0, 0.0);
+ }
+
+ const Basis frame = Basis::looking_at(forward, up);
+ return frame;
+}
+
Basis Curve3D::_sample_posture(Interval p_interval, bool p_apply_tilt) const {
// Assuming that p_interval is valid.
ERR_FAIL_INDEX_V_MSG(p_interval.idx, baked_point_cache.size(), Basis(), "Invalid interval");
@@ -1801,35 +1833,48 @@ Basis Curve3D::_sample_posture(Interval p_interval, bool p_apply_tilt) const {
int idx = p_interval.idx;
real_t frac = p_interval.frac;
- Vector3 forward_begin = baked_forward_vector_cache[idx];
- Vector3 forward_end = baked_forward_vector_cache[idx + 1];
+ // Get frames at both ends of the interval, then interpolate.
+ const Basis frame_begin = _compose_posture(idx);
+ const Basis frame_end = _compose_posture(idx + 1);
+ const Basis frame = frame_begin.slerp(frame_end, frac).orthonormalized();
- Vector3 up_begin;
- Vector3 up_end;
- if (up_vector_enabled) {
- up_begin = baked_up_vector_cache[idx];
- up_end = baked_up_vector_cache[idx + 1];
- } else {
- up_begin = Vector3(0.0, 1.0, 0.0);
- up_end = Vector3(0.0, 1.0, 0.0);
+ if (!p_apply_tilt) {
+ return frame;
}
- // Build frames at both ends of the interval, then interpolate.
- const Basis frame_begin = Basis::looking_at(forward_begin, up_begin);
- const Basis frame_end = Basis::looking_at(forward_end, up_end);
- const Basis frame = frame_begin.slerp(frame_end, frac).orthonormalized();
+ // Applying tilt.
+ const real_t tilt = _sample_baked_tilt(p_interval);
+ Vector3 tangent = -frame.get_column(2);
+
+ const Basis twist(tangent, tilt);
+ return twist * frame;
+}
+
+#ifdef TOOLS_ENABLED
+// Get posture at a control point. Needed for Gizmo implementation.
+Basis Curve3D::get_point_baked_posture(int p_index, bool p_apply_tilt) const {
+ if (baked_cache_dirty) {
+ _bake();
+ }
+
+ // Assuming that p_idx is valid.
+ ERR_FAIL_INDEX_V_MSG(p_index, points_in_cache.size(), Basis(), "Invalid control point index");
+
+ int baked_idx = points_in_cache[p_index];
+ Basis frame = _compose_posture(baked_idx);
if (!p_apply_tilt) {
return frame;
}
// Applying tilt.
- const real_t tilt = _sample_baked_tilt(p_interval);
- Vector3 forward = frame.get_column(2);
+ const real_t tilt = points[p_index].tilt;
+ Vector3 tangent = -frame.get_column(2);
+ const Basis twist(tangent, tilt);
- const Basis twist(forward, tilt);
return twist * frame;
}
+#endif
Vector3 Curve3D::sample_baked(real_t p_offset, bool p_cubic) const {
if (baked_cache_dirty) {