Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draw fish bones for Path3D and Path2D in the Editor #68860

Merged
merged 1 commit into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 44 additions & 19 deletions editor/plugins/path_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,38 +240,63 @@ void Path3DGizmo::redraw() {
return;
}

Vector<Vector3> v3a = c->tessellate();
//Vector<Vector3> v3a=c->get_baked_points();
real_t interval = 0.1;
const real_t length = c->get_baked_length();

int v3s = v3a.size();
if (v3s == 0) {
return;
}
Vector<Vector3> v3p;
const Vector3 *r = v3a.ptr();

// BUG: the following won't work when v3s, avoid drawing as a temporary workaround.
for (int i = 0; i < v3s - 1; i++) {
v3p.push_back(r[i]);
v3p.push_back(r[i + 1]);
//v3p.push_back(r[i]);
//v3p.push_back(r[i]+Vector3(0,0.2,0));
}
// 1. Draw curve and bones.
if (length > CMP_EPSILON) {
const int sample_count = int(length / interval) + 2;
interval = length / (sample_count - 1); // Recalculate real interval length.

Vector<Transform3D> frames;
frames.resize(sample_count);

{
Transform3D *w = frames.ptrw();

for (int i = 0; i < sample_count; i++) {
w[i] = c->sample_baked_with_rotation(i * interval, true, true);
}
}

const Transform3D *r = frames.ptr();
Vector<Vector3> v3p;
for (int i = 0; i < sample_count - 1; i++) {
const Vector3 p1 = r[i].origin;
const Vector3 p2 = r[i + 1].origin;
const Vector3 side = r[i].basis.get_column(0);
const Vector3 up = r[i].basis.get_column(1);
const Vector3 forward = r[i].basis.get_column(2);

// Curve segment.
v3p.push_back(p1);
v3p.push_back(p2);

// Fish Bone.
v3p.push_back(p1);
v3p.push_back(p1 + (side - forward) * 0.06);

v3p.push_back(p1);
v3p.push_back(p1 + (-side - forward) * 0.06);

v3p.push_back(p1);
v3p.push_back(p1 + up * 0.03);
}

if (v3p.size() > 1) {
add_lines(v3p, path_material);
add_collision_segments(v3p);
}

// 2. Draw handles.
if (Path3DEditorPlugin::singleton->get_edited_path() == path) {
v3p.clear();
Vector<Vector3> v3p;
Vector<Vector3> handle_points;
Vector<Vector3> sec_handle_points;

for (int i = 0; i < c->get_point_count(); i++) {
Vector3 p = c->get_point_position(i);
handle_points.push_back(p);
// push Out points first so they get selected if the In and Out points are on top of each other.
// Push out points first so they get selected if the In and Out points are on top of each other.
if (i < c->get_point_count() - 1) {
v3p.push_back(p);
v3p.push_back(p + c->get_point_out(i));
Expand Down
59 changes: 49 additions & 10 deletions scene/2d/path_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,57 @@ void Path2D::_notification(int p_what) {
#else
const real_t line_width = get_tree()->get_debug_paths_width();
#endif
_cached_draw_pts.resize(curve->get_point_count() * 8);
int count = 0;

for (int i = 0; i < curve->get_point_count(); i++) {
for (int j = 0; j < 8; j++) {
real_t frac = j * (1.0 / 8.0);
Vector2 p = curve->sample(i, frac);
_cached_draw_pts.set(count++, p);
real_t interval = 10;
const real_t length = curve->get_baked_length();

if (length > CMP_EPSILON) {
const int sample_count = int(length / interval) + 2;
interval = length / (sample_count - 1); // Recalculate real interval length.

Vector<Transform2D> frames;
frames.resize(sample_count);

{
Transform2D *w = frames.ptrw();

for (int i = 0; i < sample_count; i++) {
w[i] = curve->sample_baked_with_rotation(i * interval, true, true);
}
}
}

draw_polyline(_cached_draw_pts, get_tree()->get_debug_paths_color(), line_width, true);
const Transform2D *r = frames.ptr();
// Draw curve segments
{
PackedVector2Array v2p;
v2p.resize(sample_count);
Vector2 *w = v2p.ptrw();

for (int i = 0; i < sample_count; i++) {
w[i] = r[i].get_origin();
}
draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width, false);
}

// Draw fish bones
{
PackedVector2Array v2p;
v2p.resize(3);
Vector2 *w = v2p.ptrw();

for (int i = 0; i < sample_count; i++) {
const Vector2 p = r[i].get_origin();
const Vector2 side = r[i].columns[0];
const Vector2 forward = r[i].columns[1];

// Fish Bone.
w[0] = p + (side - forward) * 5;
w[1] = p;
w[2] = p + (-side - forward) * 5;

draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width * 0.5, false);
}
}
}
} break;
}
}
Expand Down
1 change: 0 additions & 1 deletion scene/2d/path_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);

Ref<Curve2D> curve;
Vector<Vector2> _cached_draw_pts;

void _curve_changed();

Expand Down
32 changes: 25 additions & 7 deletions servers/rendering/renderer_canvas_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,18 +1075,36 @@ void RendererCanvasCull::canvas_item_add_polyline(RID p_item, const Vector<Point

void RendererCanvasCull::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
ERR_FAIL_COND(p_points.size() < 2);
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_COND(!canvas_item);

Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);

if (true || p_width <= 1) {
#define TODO make thick lines possible
// TODO: `canvas_item_add_line`(`multiline`, `polyline`) share logic, should factor out.
if (p_width <= 1) {
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
ERR_FAIL_COND(!canvas_item);

Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
pline->primitive = RS::PRIMITIVE_LINES;
pline->polygon.create(Vector<int>(), p_points, p_colors);
} else {
if (p_colors.size() == 1) {
Color color = p_colors[0];
for (int i = 0; i < p_points.size() >> 1; i++) {
Vector2 from = p_points[i * 2 + 0];
Vector2 to = p_points[i * 2 + 1];

canvas_item_add_line(p_item, from, to, color, p_width);
}
} else if (p_colors.size() == p_points.size() >> 1) {
for (int i = 0; i < p_points.size() >> 1; i++) {
Color color = p_colors[i];
Vector2 from = p_points[i * 2 + 0];
Vector2 to = p_points[i * 2 + 1];

canvas_item_add_line(p_item, from, to, color, p_width);
}
} else {
ERR_FAIL_MSG("Length of p_colors is invalid.");
}
}
}

Expand Down