You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Path3D prefer control points for outward curve
This commit is contained in:
@@ -149,7 +149,31 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
|
|||||||
local.snapf(snap);
|
local.snapf(snap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.type == HandleType::HANDLE_TYPE_IN) {
|
// Determine if control points should be swapped based on delta movement.
|
||||||
|
// Only run on the next update after an overlap is detected, to get proper delta movement.
|
||||||
|
if (control_points_overlapped) {
|
||||||
|
control_points_overlapped = false;
|
||||||
|
Vector3 delta = local - (info.type == HANDLE_TYPE_IN ? c->get_point_in(idx) : c->get_point_out(idx));
|
||||||
|
Vector3 p0 = c->get_point_position(idx - 1) - base;
|
||||||
|
Vector3 p1 = c->get_point_position(idx + 1) - base;
|
||||||
|
HandleType new_type = Math::abs(delta.angle_to(p0)) < Math::abs(delta.angle_to(p1)) ? HANDLE_TYPE_IN : HANDLE_TYPE_OUT;
|
||||||
|
if (info.type != new_type) {
|
||||||
|
swapped_control_points_idx = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect control points overlap.
|
||||||
|
bool control_points_equal = c->get_point_in(idx).is_equal_approx(c->get_point_out(idx));
|
||||||
|
if (idx > 0 && idx < (c->get_point_count() - 1) && control_points_equal) {
|
||||||
|
control_points_overlapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleType control_type = info.type;
|
||||||
|
if (swapped_control_points_idx == idx) {
|
||||||
|
control_type = info.type == HANDLE_TYPE_IN ? HANDLE_TYPE_OUT : HANDLE_TYPE_IN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control_type == HandleType::HANDLE_TYPE_IN) {
|
||||||
c->set_point_in(idx, local);
|
c->set_point_in(idx, local);
|
||||||
if (Path3DEditorPlugin::singleton->mirror_angle_enabled()) {
|
if (Path3DEditorPlugin::singleton->mirror_angle_enabled()) {
|
||||||
c->set_point_out(idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length));
|
c->set_point_out(idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length));
|
||||||
@@ -190,6 +214,9 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
|
void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
|
||||||
|
swapped_control_points_idx = -1;
|
||||||
|
control_points_overlapped = false;
|
||||||
|
|
||||||
Ref<Curve3D> c = path->get_curve();
|
Ref<Curve3D> c = path->get_curve();
|
||||||
if (c.is_null()) {
|
if (c.is_null()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ class Path3DGizmo : public EditorNode3DGizmo {
|
|||||||
mutable float orig_out_length;
|
mutable float orig_out_length;
|
||||||
mutable float disk_size = 0.8;
|
mutable float disk_size = 0.8;
|
||||||
|
|
||||||
|
// Index that should have swapped control points for achieving an outwards curve.
|
||||||
|
int swapped_control_points_idx = -1;
|
||||||
|
bool control_points_overlapped = false;
|
||||||
|
|
||||||
// Cache information of secondary handles.
|
// Cache information of secondary handles.
|
||||||
Vector<HandleInfo> _secondary_handles_info;
|
Vector<HandleInfo> _secondary_handles_info;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user