During the last month or so, I've noticed a couple of impressive custom node editors here in the forums.
It's hard to resist not getting in on that. In this blog post, the focus will be on the link connectors.
Typically, what I saw was the sharp bent line. It makes perfect sense to use this style. Quick and low overhead.
Three segments with four vertices. Nice. Nothing wrong with that at all.
Then I started hunting for spline code examples until the math bits showed teeth with that angry growl.
If I have to pull out sqrt or some form of smoothstep just for pretty lines, then maybe it's not worth it.
So, what to do…what to do. Well, in my case, I took a nap. 🙂
After waking from slumber, I had the ‘just fake it’ idea. Why not, right?
Here, I'll just show the generate points part and call it good.
core::cLine _spline;
sPoint _controlPoints[5];
bool gui::cSpline::Create(sPoint start, sPoint end)
{
_controlPoints[0] = start;
_controlPoints[1] = sPoint(start.x + 4, start.y);
_controlPoints[2] = sPoint(start.x + ((end.x-start.x)/2), start.y + ((end.y-start.y)/2));
_controlPoints[3] = sPoint(end.x - 4, end.y);
_controlPoints[4] = end;
std::vector<sPoint> points = GenerateSegments();
_spline.data.stride = 2;
_spline.data.num_verts = points.size();
for (sPoint pt : points)
{
_spline.data.vdata.push_back(pt.x);
_spline.data.vdata.push_back(pt.y);
}
_spline.Upload();
return true;
}
std::vector<sPoint> gui::cSpline::GenerateSegments()
{
sPoint p1 = { _controlPoints[1].x, _controlPoints[1].y };
sPoint p2 = { _controlPoints[2].x, _controlPoints[2].y };
float dx = (p2.x > p1.x) ? (p2.x - p1.x)/20 : -(p1.x - p2.x)/20;
float dy = (p2.y > p1.y) ? (p2.y - p1.y)/20 : -(p1.y - p2.y)/20;
std::vector<sPoint> pts;
pts.push_back(_controlPoints[0]);
pts.push_back(_controlPoints[1]);
for (int i = 0; i < 20; i++)
{
p1.x += dx;
p1.y += dy * (i * 0.1f);
pts.push_back(p1);
}
for (int i = 20; i > 0; i--)
{
p1.x += dx;
p1.y += dy * (i * 0.1f);
pts.push_back(p1);
}
pts.push_back(_controlPoints[4]);
return pts;
}
My cLine class has the every day VAO/VBO/vertex descriptor goodness.
The cSpline class just adds the control point concept and fills the in between.
p1 is the start position. p2 is a calculated mid point relative to the end position.
dx and dy is the linear step value between p1 and p2.
The curve comes from the vertical scaling during the two for loops in GenerateSegments.
Pretty simple and effective in all four directional quadrants.
The extra copy is for the copy/paste guys and gals. :P
Took that out this morning.