Create wonderful smooth Bézier-, CatMulRom- and Hermite-Splines with Trigger Events for your MonoGame project.
Hello everyone!
I always wanted to have something like spline tools for XNA / MonoGame but struggled to find something useful.
Nearly everything I found to this topic is eiter Unity3D specific, based on different languages or plain documents about the idea and math of splines.
So, I took the hard way and studied the creation of BézierSplines. It was important for me to create a functional library so that others (the MonoGame community) can benefit from it.
MonoGame.SplineFlower was born!
Please watch this video to get an impression:
The Visual Studio 2019 solution contains the following projects:
MonoGame.SplineFlower (the portable class library)
MonoGame.SplineFlower.Content (spline data and setup class)
MonoGame.SplineFlower.Content.Pipeline (creates .xnb files out of .json BézierSpline data)
MonoGame.SplineFlower.Samples (showing features of the library)
MonoGame.SplineFlower.Editor (create, import and export BézierSplines)
MonoGame.SplineFlower.GameTest (DesktopGL project which loads a BézierSpline with the ContentManager)
This should make creating and using BézierSplines a breeze!
You can do pretty much anything with BézierSplines. The limit is really just your imagination. Play around with the samples and learn from it.
Get a lot more information by taking a look at the official repo and readme file:
Update: 1.1.0 - Advanced Controls (Keyboard and GamePad)
It’s now possible to have Keyboard and GamePad input at the same time.
It’s now possible to add multiple keys or buttons to the SplineWalker; just one of those buttons can be pressed at the same time.
Renamed AlreadyTriggered to CanTrigger in the SplineWalker class.
Made sure that we have the _currentTriggerIndex value higher than -1 to avoid out of range bugs.
Fixed a bug where the current trigger index went wrong when quickly changed the walking direction.
Added Tank class (SplineWalker) and TankTrack BezierSpline to show the new input features.
It’s now possible to control a SplineWalker with a Keyboard and a GamePad.
Renamed Mode to WalkerMode in the SplineWalker class.
A SplineWalker can now trigger events in different directions. For example only when he travels forward, backward or forward and backward.
A SplineWalker can now perform a turn (rotating 180 degrees) when walking in the opposite direction (PingPong WalkingMode).
Added new sample project AdvancedControls.cs
This update was actually way more difficult to make than I originally thought. Reason for this is the current trigger index, which can be dynamic now, because the new input capabilities allowing to walk dynamically on the spline.
See for yourself:
You have also multiple trigger mode options now. You can for example allow that the trigger on a spline only triggering, when a SplineWalker walks in the forward-, backward- or both directions.
You can also allow spline revolutions (SplineWalker walks from the last to the first trigger on the spline), when the WalkerMode is not “Once”. In the opposite it’s possible to disallow spline revolutions, when a SplineWalker’s mode is set to “Once” but not to “Loop” or “PingPong”.
Oh, and by the way: You can also rotate the turret of the tank you saw in the video with the right thumbstick, but… shhhhhhhhht: we don’t want that something bad will happen!!
I got asked by some people if the MonoGame.SplineFlower library is able to output CatMulRomSplines, but for the past 6 months I needed to say “NO”. I didn’t like that, because I know that CatMulRomSplines are pretty important in game development and… also pretty cool!
So… recently I finally managed to had some time to wrap my head around this topic and i’m quite happy to show you my results, because the library can now output CatMulRomSplines! “YES”
Just by looking at this gif you will clearly see why CatMulRomSplines are so great. Take a look at the yellow spline track and you will notice that it will pass tough all of the red control points. This is not the case for the BézierSpline which makes it naturally kinda hard for the developer to know where the yellow spline track will be when creating a BézierSpline within code.
But with a CatMulRomSpline you can be sure that the yellow track will hit every red control point at least one time and it passes exactly through the center of such a control point. This makes game development with splines more foreseeable (imagine race tracks or rail tracks).
Fancy Editing:
Changelog:
Added support for CatMulRomSplines.
Added public static float SplineStepDistance so that the user can easily get the current step resolution of a specific spline.
Added a SplineWalker to CatMulRom sample and looping the spline track.
Direction vectors for CatMulRom splines have now the correct rotation / angle.
Added possibility of showing or hideing the curves of a CatMulRomSpline.
Json serialization updated accordingly.
ContentPipeline support.
Editor updated accordingly.
Updated Readme.md file.
Note:
Creating a CatMulRomSpline is verry simple. Imagine you have a BézierSpline called “MySpline” and you want to convert it to a CatMulRomSpline. Then you just need to do this:
MySpline.CatMulRom = true;
Everything else happens automagically!
It’s also possible to convert already existing BézierSplines like this pretty easily.
Hope you like this update! It should work pretty stable, but it’s a fresh implementation so… bugs are possible
Those catmull rom curves are pretty nice.
Its possible to make surfaces from these curves as well.
I dunno how well catmulls would be for that as they look uniformed.
I had ported over a little of David f Rodgers c Nurbs code to generate surfaces from them, but i kind of hate how you have to add multiple knots for edges and to pull them to the vertices and stuff so i started writing my own splines with single weights that would find a middle ground they work but they aren’t done the main reason is the curvature is uniformed atm and i need to make them non uniformed for good texturing which there is no formula for distance of a second degree polynominal that i can find and mine is purposely imbalanced so, its been on the shelf forever.
This is very cool im going to take a look at it when i get a chance.
Yeah, I stumbled upon this topic too (NURBS). It’s pretty nice for 3D development I think.
There are different types of CatMulRom-Splines. Look at this article:
There is also a graphic which compares the Uniformed one with a Centripedal CatMulRom and a Chordal CatMulRom.
I think espacially the Centripedal one could be used for creating surfaces. At least it looks so for me.
Wikipedia says:
“it will not form loop or self-intersection within a curve segment. Second, cusp will never occur within a curve segment. Third, it follows the control points more tightly”
But i’m just guessing here
BTW: I think about integrating a possibility of adding a (textured) polygon-stripe to a spline curve, which would make it possible to bend images around such a spline (roads, railroads, laser beams etc).
Ya the thing about curves and surface splines is there are really two important issues minus big words.
Mind you im terrible at math never even took algebra. But here goes.
The continuity of the curve geometry.
Basically you want (C2 curvature) but you want some sort of ability to turn that down to at certain points for sharp edges.
In relation to uv texturing.
You want the acceleration of the curve to be non uniform so that you can control er prevent or allow stretching of a texture across the surface. This is related to the acceleration of the generated points on a curve or surface. Sometimes called G3 or G4 continuous.
This second part is the really important part the continuity is far less important (provided you have at least some control) then the ability to change uv acceleration.
Yeah, having geometric continuity per mouse click or keystroke would be nice. At least you can achieve that by “playing around with the control points”. But doing this always manually can make you angry sometimes.
For the MonoGame.SplineFlower library I plan to add at least parametric continuity (BézierSplines & CatMulRomSplines), so that particles or a spline walker can have the same velocity or acceleration over time.
Regarding CatMulRom-Splines there are also other tricks like adding or removing tension to a curve to make it sharper or softer. In combination with an alpha value 0-1f you could have a pretty nice control over your generated curves (0 = uniform, 0.5 = centripedal, 1 = chordal [inclusive all the grey-zones]).
But I don’t know if this would be good enough for 3D-Development.
I’ll continue my inquiry here instead ^_^y sorry tweetter has little text to offer : - D
Here it goes bro,
I have a function that returns a Points from a given line Start-Position and End-Position with a given Contour in the middle, can I extract the points position and it’s cotour from the editor ?
E;g:
Start, Counter, End
1, 1.5, 2
2, 2.5, 3
3, 3.5, 4
This my function looks like
/// <summary>
/// Curve to points.
/// </summary>
/// <param name="pStart">Line start point</param>
/// <param name="pEnd">Line end point</param>
// <param name="pContour">Curve center contour</param>
/// <param name="pSegment">Desired number of segment</param>
/// <returns></returns>
public static Vector3[] CreateCurvePointsFromLine( Vector3 pStart, Vector3 pEnd, Vector3 pContour, int pSegment )
{
return CreateCurvePointsFromLine(ref pStart, ref pEnd, ref pContour, pSegment );
}
mFrom = 1;
mContour = 1.5;
mTo = 2;
var Vector3[] CreateCurvePointsFromLine( mFrom, mContour, mEnd, 4 );
This will give 4 points as shown below
To make the long story short bro, can I extract the lines position with a contour?
Do you want to convert the points from your function to a spline and make this spline visible in the editor?
I just need the points to follow, can I export the points from your editor and save it in a text file all the points of the car to follow as on your example:
Have you tried to restore the nuget packages?
I download it directly your from your github, I’ll try nuget instead ^_^y
EDIT: Works the restore nuget and dependencies are ok,
One more problem which I always encountered on using MVSC 2017, i’'ll try to compile it on MVSC 2015 and plays with it… Thanks ^_^Y
Click on “File->Export JSON” in the editor and chose a save location. You can open the json file with any text editor. If you need help loading this data back to your environment then don’t hesitate to ask. I will help you bro
This is a picture from the internet. The right option is not selected here. It’s the one below the red marker “Restore NuGet Packages”.
Click on that and see if it resolves your issue with missing DLLs.
Edit: Ah, I see it helped. The two error messages on the top are just post build events. You don’t need them on your side. You can delete them in the project “Properties->Build Events” section.
By clicking and dragging the orange transform it’s possible to do this now:
Renamed ShowBezierSpline to ShowSpline.
Added ShowCenterTransform to make it possible to hide or show the transform in the center of the spline.
Only calculating the CenterTransform when necessary.
It’s now possible to programmatically create a spline by using the new constructor.
Added CenterTransformMode “None”. On this mode the whole spline can be moved by dragging the CenterSpline with the left mouse button.
Fixed that points which could be placed exactly at the start point (index 0) could resulting in wrong calculations.
After importing a spline the newly imported spline will be placed on the center of the screen.
Added NuGetRelease configuration so that if building in Release configuration, it wouldn’t result in compilation errors on the users end, because of the post build commands. @DexterZ
It’s now possible to change the CenterTransformMode (Rotate, Scale, ScaleRotate) in the Sample- and Editor project.
Fixed IndexOutOfRangeException when the CurrentTriggerIndex was -1 in the SplineWalker class.
Added additional NullReference checks for the splineControl and the splineControl.MySplineWalker. @DexterZ
It’s now possible to scale the whole spline by dragging the CenterSpline transform with the left mouse button.
It’s now possible to rotate and scale-rotate the whole spline.
Added public bool IsCenterSpline to check if a Transform is the center of the spline or not.
Renamed GetSplineCenter to CenterSpline.
Added checks to determine if a Transform is a point on a spline or the CenterTransform.
Removed LineControl sample and CurveControl sample from the project.
Extended GameSample to demonstrate new features.
The orange transform will always be in the center of the spline:
This update should improve MonoGame.SplineFlower by alot.