Curves Module threejs project example
The THREE.Curve base class can be used as a way to create custom curve constructor functions, but one might need to even bother with that as there are a number of great built in curve constructor functions as well. In any case Curve objects, regardless if they are custom , or built in, are a great way to go about defining paths in 3d space. I am sure that they may also be useful for many other things in threejs such as creating the position attributes of geometry, but for now I am mainly focused on using curves to define paths that can be used to define the movement of objects over time.
The curves module threejs example and what to know first
Check out the THREE.Curve base class, as well as THREE.QuadraticBezierCurve3
I have wrote a blog post on the base curve class, as well as the Quadratic Bezier Curve class that builds on top of that. There is also of course the official threejs docs on Curves, Bezier Curves and also Curve Paths but I find that the docs do not always do the best job outlined every little detail starting with hello world style copy and paste examples.
In any case it would be a good idea to work out at least one if not a lot of little demos involving the use of curves as there is a lot to be aware of when it comes to suing them. There is the get point method that is a very useful method for example as it will return a vector3 object at any given point along the curve by passing a given alpha value as the first argument.
Check out the Vector3 class, Object3d, and the position property of Object3d
There are a lot of ways that curves can be used in a threejs project, however maybe one of the first and foremost use case examples would be to use it as a way to get points at which to move an object such as a mesh object or camera. As I said the get point method of the curve class can be used to return an instance of the Vector3 class along a given curve. There are a number of things that could be done with this, one of which would be to use it as a way to set the position of an object3d based object. So then there is calling the copy method off of the position property of an obejct3d based object such as a mesh object and passing this returned vector3 object to do just that.
In this post I assume that you are beyond the basics of using the vector3 class and know at least a thing or two about object3d and how it applys to any kind of object that would be added to a main scene object. If not you might want to read my main blog post on the Vector3 class, and maybe also my main post on the Object3d class as well. I also have a post in which I mainly focus on just the position property of the object3d class as well.
The Source code examples here are on Github
I also have the source code examples that I am write about here up on Github as well.
Version Numbers matter
When I first wrote this post I was using r146 of threejs.
1 - Get Alpha method improvements ( R1 ), and DEMOS
I am going to want to make this module the kind of project that I use over and over again as part of an over all typical stack of code to work with from one video project to the next. One of the major use case examples of this module is to not just use if for the sake of creating paths that will be used to update the positions of objects over time, but to also use it as a way to define alpha functions that will be used in the process of creating the values that are used to get points along a curve as well. Anyway much of the work that I did for R1 of this example had to go with creating a few built in get alpha methods for creating alpha functions using curves, as well as a few usual suspect type methods for this as well.
The source code of curves.js R1
Here is then the updated source code for R1 of my curves module that helps me with the process of quickly creating and using curves. In this revision I am now using an updated create alpha curve helper that will work with just a plain linear array form of numbers that are used to define a curve alpha function. I have found that I like to just use this kind of array, rather than the array of arrays format that I was using in the older version of this module.
I now also have a create debug points helper function that is used to create points for the debug helpers that can be used to get a quick idea of what is going on with a curve, or get alpha function.
The main thing here though is all the built in alpha functions that I can now use with the single get alpha function and get alpha public methods. In the old version of the module I have two public methods to choose from, now these are just two of a few built in methods to choose from that I can use by just giving a string value to create an alpha function, or to define what function to use when just calling directly with the curve module.
1.1 - Debug Alpha Function demo
I have this built in debug alpha function that can be used to create a nice standard way of seeing what the deal is with a given alpha function. This is again something that I started in the first version of the curve module, however now I have a lot more built in get alpha functions to choose from. Also on top of this I can also define new ones as needed that I may or may not bake into additional future revisions of the module if need be.
1.1 - Update Alpha functions over time
I am not sure if I will need or want to do so often, but I can tweak the values use for the get alpha functions over time by making the options object that is used a public property of the function that is returned.
1.2 - Custom Get Alpha funcitons
Many of the built in get alpha functions are options that I will often use, but there will be times now and then where I might want to create a custom function real quick. So one change that I made in this revision is to make it so that I can pass a function rather than a string for the type option when calling the get alpha function method. I am sure that I will be using this curve module over and over again from one project to the next, so I will want to have this feature as a way to add other get alpha functions as needed. In time if I find myself using the same custom get alpha functions over and over again I can add them to the collection of baked in methods for creating this kind of method.
2 - The First curves module R0, and demos
There is going over the source code of the curve module itself, and then there is going over the source code of at least a few demos of the module as well. In this section I will be doing just that with the very first version of the curve module, and if I do end up using this often I am sure there will be addition revisions. In any case in this revision of the module the focus was to just have some basic tools for quickly creating curve objects using the threejs built in THREE.QuadraticBezierCurve3 class which is a great way to create curves using a start point, end point, and a single controls point all of which are instances of the Vector3 class. There are methods of the curve module that will return a curve, curve path, and also arrays of Vecotr3 objects that I can then quickly use with other projects that I have outside of this one.
On top of just some methods that will create and return curves and arrays of vector3 objects i also started a method that I can use to create and return an alpha function based on curve data. This is another major use case of curves that came to mind for me beyond just that of defining paths in s3 space. What I mean by an alpha function is something like the THREE.MathUtils.smoothstep function, and if you are not in the know with that, simply put a function that can be used to return a value between 0 and 1. You see there is not just defining a path in space, but also defining the spacing between points along a curve as well if that makes any sense and that is one use case for one of these alpha functions.
I am sure that there will be nay more method and features that I will want to ad to this kind of module actually, but much of that is what I will want to leave for future revisions.
The source code of curves.js R0
Here then is the source code for R0 of my curves tools that I have worked out thus far. At the very top of the module I have thus far just two private helper functions. One of these is a for path data helper function that I use for two methods that create and return a collection by a given array of arrays of data for arguments to be passed to the THREE.QuadraticBezierCurve3 function. By collection I mean one of two things, an array of Vector3 objects, or a curve path. The other helper function will create and return a curve that will be used for one of my functions that will return an alpha function.
I then have a number of methods that will return a something that is based off the the base curve class such as a Quadratic Bezier Curve, or a curve path. There is the QBC3 method that is just an abstraction for the Quadratic Bezer Curve class. Then I have another method that is a little more than just that that I find useful by defining the control points as deltas from a point in the middle of the curve. I then also have another number of methods that are like these methods buy will return an array of vector3 objects rather than a curve.
I then also have some methods that are a starting point for this idea of using curves to create alpha values, and then a number of methods that help me to debug things by getting a visual idea of what is going on using points and lines.
2.1 - Create and return an array of Vector3 objects
Often what it is that I will want is not a Curve, but an array of vector3 objects of points along a curve. So I have a method that will take an object that contains an array of arrays of data and split out an array of vector3 objects. Also I have a method backed into the module thus far that is something that I made while working on my fink series of beta world videos. That is that I have an array of points that follow a curve, and then all of a sudden the path becomes just a bunch of random points moving around all over the place. This kind of motion can often prove to be a little useful in some projects in which I want that kind of camera movement.
2.2 - The Curve path module
I also have another method that is just like that of the one that will return an array of vector3 objects but will return a curve path. I can then use whatever alpha value I want when it comes to getting a point along that curve which is great. For this example thought I am not going to be doing anything fancy with that, and will save that for an additional example in this post.
So then here I am using QB Curve Path method and passing an array of arrays just like that of what I pass when using the method that will return an array of points. One major difference thus is that I do not pass the number of points that I want as I am getting a curve that can be used to get any number of points that I want depending on how I use the curve. I am then just computing some simple, basic alpha values that I often use in various video projects to get the alpha value that I use with the get point method.
The end result here is then a mesh object moving forward and then backward along the curve over the span of the animation here. The reason why though is because of the alpha value that I am giving the results in this kind of behavior. I will be getting more into this in additional demos of the module here, but for now there is just thinking in terms of what other kinds of expressions and methods there are to create these alpha values for the get point method.
2.3 - The get alpha fucntions
I then wanted to create, bake in, and explore with this idea of having a get alpha value function using curves. With that said I made a lot of great progress testing out this idea that will then be further refined in future revisions of the module. I am thinking that I might want to make a another threejs project where the main focus is with alpha functions, but in any case I am sure that this will ether be something that I will want to bake into this module, or at least this curve module will be a foundation for such a module for sure.
I am off to a good start with this curve module, but there is still a lot or more work ahead for me on this one. I will like to refine the get alpha functions for sure, but there are also things that I have not even started with in R0 of this module. The main thing that comes to mind with this would be using curves to create position attributes of custom buffer geometry objects.