Curve-X is a small and easy-to-use C++ Bézier library to create 2D-splines with its own GUI editor.
If you are a game developer working on your own C++ game or engine and you want to have fine control over your values (let's say: gamepad sensitivity, dynamic FOV depending on the player's speed, gravity force, particle effects, animations, etc.) for the sake of game feel, this project may interests you.
Curve-X allows to create 2D-splines, either they are intended to be geometrical shapes or for timed-based values. It is simple of usage yet allows a lot of manipulation. The code is also well-documented: each class, functions and enums are properly described.
By default, the project is built for C++17, yet it is compatible with the versions specified in Dependencies.
This project is still under development, feel free to raise issues as you encounter them.
- C++11, 14, 17 or 20 compiler
- CMake 3.11 is optional
- Carefully well-documented code for classes, functions and enums
- Written in simple and straightforward C++17 using snake_case notation
- Project IDE-independent thanks to CMake
- Custom GUI editor to easily create and edit curve files
- Support for both geometrical shapes and timed-based curves
- Multiple evaluation methods: progress (from 0.0 to 1.0), time (using X-axis) and distance.
- Embedded curves serialization and un-serialization methods
- Custom and human-readable text format for curves serialization
- Free and open-source
Two examples: a geometrical shape curve (
samples/heart.cvx
) and a timed-based curve (samples/controller-gamepad-sensitivity.cvx
) from the GUI editor
This project is split into two Github repositories: the library (this one) and the GUI editor. You are not forced to use the editor, it is entirely optional but it is here to facilitate your experience with Curve-X.
Folder structure:
include/curve-x/
contains header files that you, as the library user, want to use inside your project. The most important one iscurve.h
, containing all required definitions to start using the library. If you want to have a deep-dive into the code, I'd recommend you to check the header files in this order:point.h
,utils.h
,key.h
,curve.h
and finallycurve-serializer.h
.src/
contains source files and implementations of the header files located in the folderinclude/curve-x/
.tests/
contains source files for testing and usage examples. You may want to look at it to better understand how to use the library.samples/
contains samples of curve files generated by the library. You can import these inside the GUI editor or in your code for testing. It's also here so you can get a grasp of what the text format is.
From tests/simple_example.cpp
:
// Includes all necessary code including the Curve class
#include <curve-x/curve.h>
// Includes the CurveSerializer class, only if you want to import or export
// the curves data from or to files
#include <curve-x/curve-serializer.h>
// Includes std::ofstream to output the curve data to files
#include <fstream>
int main()
{
// Initialize a curve object
curve_x::Curve curve;
// Add two keys with different control points
curve.add_key( curve_x::CurveKey( { 0.0f, 0.0f } ) );
curve.add_key( curve_x::CurveKey( { 1.0f, 1.0f } ) );
// Evaluate the curve at x=0.3f
float time = 0.3f;
float value = curve.evaluate_by_time( time );
printf( "Evaluation for x=%f: y=%f\n\n", time, value );
// Output:
// Evaluation for x=0.300000: y=0.216000
// Serialize the curve into a string
curve_x::CurveSerializer serializer;
std::string data = serializer.serialize( curve );
printf( "Curve serialized data:\n%s\n", data.c_str() );
// Output:
// Curve serialized data:
// version:1
// 0:x=0.000000;y=0.000000,x=-1.000000;y=0.000000,x=1.000000;y=0.000000,0
// 1:x=1.000000;y=1.000000,x=-1.000000;y=0.000000,x=1.000000;y=0.000000,0
// Write the serialized curve into a file
std::ofstream file( "my_curve.cvx" );
file << data;
file.close();
}
For more examples, look at the tests/
folder.
This project is built using CMake 3.11. However, with proper setup it is not required to add it inside your projects.
With CMake
- Clone
arkaht/cpp-curve-x
or download the ZIP and extract it - Move the
curve-x
folder inside your project libraries folder, for example:
<your_project>/
├── libs/
│ ├── curve-x/
│ │ ├── include/
│ │ │ └── ...
│ │ ├── src/
│ │ │ └── ...
│ │ ├── CMakeLists.txt
│ │ └── ...
│ └── ...
├── main.cpp
├── CMakeLists.txt
└── ...
- Optionally, delete folders that aren't required for your project such as
samples/
andtests/
. - In
<your_project>/CMakeLists.txt
:
- Use
add_subdirectory
with the library's path to include it:
add_subdirectory("libs/curve-x")
- Link the library to your project with
target_link_libraries
:
target_link_libraries(<your_project_target> PRIVATE curve-x <your_project_libs>)
- In your code, use the library, for example in your
main.cpp
:
#include <curve-x/curve.h>
// ...
int main()
{
curve_x::Curve curve;
// ...
}
- Compile and run your project, you're ready to go!
Without CMake
- Clone
arkaht/cpp-curve-x
or download the ZIP and extract it - Move the
curve-x
folder inside your project libraries folder, for example:
<your_project>/
├── libs/
│ ├── curve-x/
│ │ ├── include/
│ │ │ └── ...
│ │ ├── src/
│ │ │ └── ...
│ │ └── ...
│ └── ...
├── main.cpp
└── ...
- Optionally, delete folders that aren't required for your project such as
samples/
andtests/
. - Add an additional include directory at
libs/curve-x/include/
. - Add the source files at
libs/curve-x/src/*.cpp
to be compiled. - In your code, use the library, for example in your
main.cpp
:
#include <curve-x/curve.h>
// ...
int main()
{
curve_x::Curve curve;
// ...
}
- Compile and run your project, you're ready to go!
Note
As I don't have Linux or MacOS machines, the following instructions have been written only for Windows. If you know how to do it in those platforms, I'd welcome a pull request!
Visual Studio Code
- Install Visual Studio Code extensions C/C++ and CMake Tools from Microsoft.
- Clone
arkaht/cpp-curve-x
or download the ZIP and extract it - Open the project's folder inside Visual Studio Code
- Configure the project with CMake (
Ctrl+Shift+P > CMake: Configure
) - Build the project with CMake (
Ctrl+Shift+P > CMake: Build
,F7
or⚙ Build
button at the bottom-left) - Run the project examples, you're ready to make changes!
Visual Studio 2022
- Clone
arkaht/cpp-curve-x
or download the ZIP and extract it - Open the project's folder inside Visual Studio 2022
- Once the project has been automatically configured, run the project examples, you're ready to make changes!
Originally, it was because I wanted time-based curves for my game engine so I could better control the feeling of my games, especially when I wanted to tweak each parameter of my explosion effects (i.e. transform scales and color lerps) with precise control and better visualization instead of having to hardcode them one by one. I wanted something very similar to implementations in popular engines like Unreal, Unity or Godot.
I searched but couldn't find a C++ curve library that would suits my needs: a library easy-to-use, small to install and a GUI editor compatible with it.
Then, as I'm still a student, it also became a learning project to know more about curves.
It is also my first time using CMake and Git Submodules (used in the editor repository).
This library has been possible thanks to all these online resources:
- The Continuity of Splines by Freya Holmér
- Cubic Hermite spline from Wikipedia
- Bézier spline from Wikipedia
- Curves and Splines from Catlike Coding
- A Primer on Bézier Curve by Pomax
- Unreal Engine's
FRichCurve
code for evaluation by time