Add Spline primitive
We already have PolyLine, but is better to have spline.
Interpolated if possible.
We already have PolyLine, but is better to have spline.
Interpolated if possible.
Hiya
I'd like to make the request to have, curves or arcs any control to create rounded or seemingly rounded shapes perhaps via bezier curves or able to set the radius between points. I'm sure you know what I'm on about.
it depends on how you sample splines in their package (I personally haven't used it), but in immediate mode it would look something like this:
using( PolylinePath pp = new() ) {
const int DETAIL = 100;
for( int i = 0; i < 100; i++ ) {
float t = i / (DETAIL-1f); // assumes the spline is sampled in a 0 to 1 range
pp.AddPoint(spline.Eval( t ));
}
Draw.Polyline( pp );
}
and for component polylines you would do something similar, except apply the points to the polyline component
I would rather use it in non immediate mode. I need to implement a spline editor tool in my runtime application. De -serialization for saving and all.
Thanks though for this first step. I'll work my way through and come back if I stumble on my way.
With the new splines package from Unity, how would I go about using this as a base?
Would be really nice to draw a spline 'directly' with Shapes
it depends on how you sample splines in their package (I personally haven't used it), but in immediate mode it would look something like this:
using( PolylinePath pp = new() ) {
const int DETAIL = 100;
for( int i = 0; i < 100; i++ ) {
float t = i / (DETAIL-1f); // assumes the spline is sampled in a 0 to 1 range
pp.AddPoint(spline.Eval( t ));
}
Draw.Polyline( pp );
}
and for component polylines you would do something similar, except apply the points to the polyline component
Currently on hold - Shapes can already draw splines if you provide the points for a polyline component, or draw them in immediate mode.
The thing is, Shapes isn't a spline library, it's a rendering library, but you can certainly use it with splines!
If you want some code for common curves used in splines, you can find that here: https://github.com/FreyaHolmer/Mathfs/tree/dev/Curves
With the new splines package from Unity, how would I go about using this as a base?
Would be really nice to draw a spline 'directly' with Shapes
Currently on hold - Shapes can already draw splines if you provide the points for a polyline component, or draw them in immediate mode.
The thing is, Shapes isn't a spline library, it's a rendering library, but you can certainly use it with splines!
If you want some code for common curves used in splines, you can find that here: https://github.com/FreyaHolmer/Mathfs/tree/dev/Curves
For me personally it isn't so much about having handles that can be manipulated with a cursor in the editor, but about generating curved shapes with code. Ideally it would work along the lines of the curves in processing, with the priority being the "continuous spline curve" mode whereby it interpolates between n control points.
Another thing (since we're here) I'd love a radius option for the rounded corners in poly lines, similar to the roundness value on regular polygons!
I was looking for something similar to this. I realize based on other posts that maybe the purpose of the library isn't so much a graphing/interpolation library. But passing a group of points into a method to create a splined curve would be pretty sweet. I had a hard time actually finding out how to do Bezier curves without this post (code sample was very helpful, but nothing in the docs). Here's my basic "spline?" attempt, improvements welcome, I'm definitely not a "math person" so those words could be wrong, not to mention this implementation :)
using Shapes; using UnityEngine; public class BezierDraw : MonoBehaviour { [Range(0.0f, 1.0f)] public float curveAmount = 0.5f; [Range(0.1f, 10.0f)] public float sphereRadius = 0.5f; public int interpolationPoints; public float lineThickness = 0.2f; public Vector3[] points; void OnDrawGizmos() { // bail unless we have 2 points if (points.Length < 2) return; Draw.PolylineGeometry = PolylineGeometry.Billboard; using (var path = new PolylinePath()) { Vector3 prevTan = Vector3.zero; for (int i = 0; i < points.Length; i++) { if (i == 0) { // if we're on the first point, there's no tangent path.AddPoint(points[0]); prevTan = points[0]; continue; } else if (i == points.Length - 1) { // if we're on the last point, we use the previous tangent and end point path.BezierTo(prevTan, points[i], points[i], interpolationPoints); continue; } // Find the direction between the previous point and the next point to interpolate Vector3 dir = (points[i+1] - points[i-1]).normalized; // This points ending tangent Vector3 tan = points[i] - (dir * (Vector3.Distance(points[i-1], points[i]) * curveAmount)); // What will be the next points starting tangent Vector3 endTan = points[i] + (dir * (Vector3.Distance(points[i], points[i+1]) * curveAmount)); // draw tangent line visuals Draw.Color = Color.blue; Draw.Line(tan, endTan); path.BezierTo(prevTan, tan, points[i], interpolationPoints); prevTan = endTan; } // Draw the Polyline Draw.Color = Color.white; Draw.Polyline(path, lineThickness, PolylineJoins.Simple); } Draw.Color = Color.white; using(var path = new PolylinePath()) { foreach(Vector3 point in points) { Draw.Sphere(point, sphereRadius); } } } }
Result:
For me personally it isn't so much about having handles that can be manipulated with a cursor in the editor, but about generating curved shapes with code. Ideally it would work along the lines of the curves in processing, with the priority being the "continuous spline curve" mode whereby it interpolates between n control points.
Another thing (since we're here) I'd love a radius option for the rounded corners in poly lines, similar to the roundness value on regular polygons!
I'm curious for those of you who have voted on this - what is your specific use case for splines?
It would help me to know what the uses will be when designing a potential spline component :)
I know this is a late reply to this comment but I thought it might help nonetheless. Really I'm using Shapes for design work so this spline feature would be great for creating certain shapes that aren't possible currently. So just having handles to be able to control the curves between points would be what I'd most use it for, akin to designing in any vector program. Also like those programs, being able to break tangents would be a huge help too but that might be a whole other issue to contend with. Thanks for all the hard work so far!
It would make sense for splines to be treated like a new shape component, as it requires a more complex set of controls compared to polylines. However, it could always use polylines under the hood — allow the user to select the resolution of the curve (maybe per-segment?), and that controls the number of polyline points generated.
(edit: Realized this is what you meant by your first question, so - yes! Extension of polylines sounds good and sensible)
If you already have other components that function on top of polylines, great! Consistency between components is an excellent reason to go that path.
I think it's important for splines to support chaining multiple points. Sometimes, a desired curve just can't be achieved with a single segment, and having to craft multiple single segments for longer/complex curves could become a real pain very quickly.
I prefer has one line with multiply point. For example to draw past or predicted trajectory. So some poins and smooth line between them
I think the main questions for me revolve around three things:
A. Should this be an extension of polylines? as in, an inspector/scene view based component that automatically calculates polyline points for you, similar to the immediate mode splines and arcs?
B. Should this be an entirely separate shape? as in, a spline component that allows you to chain multiple control points together with dedicated controls
C. if it *is* an entirely separate shape, that has a few implications - while this (mostly) isn't possible with cubic beziers, quadratic beziers can actually have vector-based smoothness instead of having multiple control points, though it would then be limited to a flat plane instead of the billboarding support that polylines have, which instead is a little bit more limiting
another question is how important it is to chain multiple curves together in a single component, or if one spline segment per component would be fine
there are lots of questions I need to figure out a good design for, so, yeah, we'll see! more of your actual use cases would be helpful regardless :)
I'm curious for those of you who have voted on this - what is your specific use case for splines?
It would help me to know what the uses will be when designing a potential spline component :)
I wanted to make projectile traectory. It should be basic cubic spline.
Also it suits some mechanics of dragNdrop like in Slay the Spire (Red pointer from card)
On a project that I'm currently on, we've been using polylines as detail elements in scenes, for things like pixel-thin wires, cables, power lines. Splines would help us cut down the number of points we have to use in order to draw freestyle curves. Weighted handles in particular would be very handy, as well as split handles (for hard/pinched corners or asymmetrical curve weights).
I'm curious for those of you who have voted on this - what is your specific use case for splines?
It would help me to know what the uses will be when designing a potential spline component :)
Thanks for the example. Is it also possible to draw a dashed curved 3d line?
currently polylines don't support it, but in the example code above using individual lines, you could skip every second line or so for a dashed look
Thanks for the example. Is it also possible to draw a dashed curved 3d line?
At the moment, you're best off drawing them in immediate mode, where there are multiple ways of drawing it. The easiest is to use a billboarded polyline, but if you need a true volumetric 3D line you'll need to stitch together several 3D lines. Here's an example script that does both! Add this script to an object in your scene. You can check the polyline box in the inspector to toggle between polyline path vs 3D line path
using Shapes;
using UnityEngine;
public class BezierDraw : MonoBehaviour {
public Vector3 a = new Vector3( 0, 0, 0 );
public Vector3 b = new Vector3( -2, 1, 1 );
public Vector3 c = new Vector3( 2, 1, 3 );
public Vector3 d = new Vector3( 0, 0, 4 );
public float lineThickness = 0.05f;
public bool polyline = false;
public int pointCount = 48;
void OnDrawGizmos() {
if( polyline ) { // Drawing using billboard polylines
Draw.PolylineGeometry = PolylineGeometry.Billboard;
using( var path = new PolylinePath() ) {
path.AddPoint( a );
path.BezierTo( b, c, d, pointCount );
Draw.Polyline( path, lineThickness, PolylineJoins.Simple );
}
} else { // Drawing using 3D lines
Draw.LineGeometry = LineGeometry.Volumetric3D;
Vector3[] pts = new Vector3[pointCount];
for( int i = 0; i < pointCount; i++ )
pts[i] = GetBezierPt( a, b, c, d, i / ( pointCount - 1f ) );
for( int i = 0; i < pointCount - 1; i++ )
Draw.Line( pts[i], pts[i + 1], lineThickness, LineEndCap.Round );
}
}
static Vector3 GetBezierPt( Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t ) {
float omt = 1f - t;
float omt2 = omt * omt;
return a * ( omt2 * omt ) + b * ( 3f * omt2 * t ) + c * ( 3f * omt * t * t ) + d * ( t * t * t );
}
}
Hi, I'm really need the splines too. How did the curved 3d-line was drawn, one on the asset-shop screenshots?
In case you havn't seen this maybe this cornershape solution, it may have relevance?
https://github.com/cukiakimani/jelly-platforms/
This is something I need to think about a little more
currently, this is the only thing immediate mode supports that the components don't, and I feel like this should work similar in components as it does in polylines
in other words - it should also support the ArcTo functions, in addition to the bezier splines you were requesting
Polyline works great. I love the mesh constructions in different modes. This is great! But in regular use-cases we need to work with Bezier curve. Of course, we can make a Bezier curve generator on top of Polyline, it will work. But not all of us know how to do that. Because bezier is math. People buying the Shapes plugin just for that reason - to not work with math directly or save time. In both cases creating your own Bezier implementation is not right.
People asking you - how did you build the curve. That is the point.
My proposition - to add Bezier mode to Polyline. Or if it does not work architecturally, it would be a dedicated component called "Curve" or "Bezier" or even "Bezier Curve". That will be really great. Of course please don't forget to add a property for customizing amount of intermediate (smooth) points.
With love!