threejs example using a sequence module with hooks
When it comes to starting to make some kind of actual product with threejs rather than just simple code examples for the sake of blog posts, I have started going in the direction of making videos. Thus far I have made a whole bunch of You tube videos for my various blog posts on threejs that I have wrote thus far, and still have a lot more to make if I am going to keep up with that. Anyway when it comes to making videos with a little javaScript code I have found that I like to break things down into what I have code to call sequences. So for this threejs project examples post I will be going over the source code of a new sequences module that I have made.
These sequences are just a way of having not just one update method, but an array of update methods with a current index for an update method that will be set based on a percent value that is based off of a current frame index value relative to that of a max frame value. This is something that I have all ready done with a sequence module that I have all ready made for my various video projects, one collection of which has to do with making video embeds for these blog posts. Anyway after using the module that I have made before for a while now I have found that there are a number of additional features that I should add, one of which is to not just have a collection of objects with an update method, but also before and after hook methods that will always fire before and after the calling of the current update method. This way I can use the before hook to set values that are a kind of default value for the sequence object, rather than repeating lines of code for each update method.
While I was making this module I also thought of a whole bunch of other features that are features that I really should have in this kind of module and managed to sneak them into the module also. This allows for me to set what the percent values should be for each update method by means of seconds values for each object, which I have come to find is a must have feature compared to doing the math manually for that. Also although I have made it so that using seconds values is the default when using the create method of the module, this feature can be disabled in the event that I just want to set percent values for each object like that of what I have been dong thus far.
This video sequences module and what to know first
This is a post on the source code of a javaScript module, and a little additional demo code that I aim to use to make threejs powered videos for my various blog posts here, as well as other video projects that I might start or continue to work in in the future. It should go without saying but I will make it clear here, this is an advanced post on the subject of threejs and client side web programming using javaScript, so I am taking some liberties and assuming that you have at least a little background with these topics.
Know at least the basics of a the request animation frame method or the threejs clock object
In client side javaScript there is the request animation frame method that is often what is used to set up a basic animation loop. There are a few other options for this sort of thing such as set time out, but when it comes to rendering rather than updating a model it is mostly just the request animation frame method that is used. I often just use this method, but there is also a threejs built in clock feature for this sot of thing as well.
Version numbers matter
I was using r135 of threejs when I first wrote this post, and the last time I came around to doing some editing for r1 of the module I was using r140. On my end everything was working fine with these versions of threejs.
source code is up on github
The source code examples I am writing about here can also be found in my test threejs repo On Github. This is a pretty major module that I use regularly when making my various demo videos for these blog posts including this one. I have two versions of this module thus far, both of which I am writing about here in this post, however I might all ready have later revisions in the works at the repo, and it might be a long time until I come around to doing some more editing here.
0 - First version ( r0 ) of this video sequences hooks module
In this section I will be going over the first revision of this sequence hooks module, which might also be the only revision if I never have a need to improve this or fix any bugs. Anyway in this section I will be going over two files then, one of which is the sequence hooks javaScript file itself, and the other is just a demo of this module that tests out the features of this module.
Here I have the source code of the module itself for the state of the first revision of it. When it comes to this there are a few public methods but for the most part there are just the create and set frame methods that I will just be using for most if not all projects. In a video project I will be using the create method to create a standard sequence object, and then that object is what I will be passing to the set frame method that will in turn call the before objects hook method first, then one of the update methods for the current object in the objects array, and then of course the after objects hook.
|
|
0.1 - Basic hello world type example
For this basic demo of the sequence hooks module I will be using the before objects hook to define some default values for a camera, as well as setting the rotation of a mesh over the whole duration of the video. I am then using the after objects hook to make sure that I am always calling the update projection matrix method of the camera after setting values for the camera in the before objects hook as well as the current update method in the objects array of the sequence object.
|
|
0.2 - Part Frame example
One thing that I have found to be a problem with r0 of the sequence hooks module has to do with the expressions that I am using to set the values of the part frame and part frame max properties of the sequence object. In some cases this can result in part percent values that are over that of 1 which I would consider not valid and results in weird rendering issues in some videos. This is then the first major bug that I would like to fix in r1, along with adding other feature that I think I should have in this now that I have used it for a long time when making videos for the javaweaver channel on youtube.
|
|
0.3 - using more than one seq object example
So now for a demo script just for the sake of making sure that this module is working out okay just the way I like it to. I am thinking that I should test out the default feature when it comes to setting secs values for each object, but also a few more nested sequence objects that make use of the per values like I have been doing thus far with the older sequence module. So then I maybe it would be a good idea to have two mesh objects one of which is mutated by making use of one or more nested sequence objects that will be used in a main sequence objects, and then another mesh object that will just be mutated with over time in the before objects method of the main sequence object.
|
|
1 - Revision r1 of the sequence hooks module
I have been using r0 of this module for a few months now, and have found that there are a few features that I should add to help keep me from having to repeat the same code over and over again from on video to the next. That is that I would like to have a get per method that I can call of the seq object to get a value from 0 to 1 that will change depending on the current fame rather to a max frame value for the video as a whole, or a current sequence object. This is all ready the case with a static value but I would like to be able to pass a count argument that will change the number of times 0 progress to 1 over the duration of a sequence or video as a whole.
On top of having a get percent function I would also like to have a get bias function that goes from 0 to 1 back to zero a count of times in a linear way. Also I would like another function that works like this get bias function only it uses the Math sin method to do so in a not so linear way.
There is also the part frame bug that I wanted to tackle in this revision, and so so in a way where I can still use the buggy old behavior if I want to if it turns out that my newer expressions do not work as expect in all situations. With that said all of this has been addresses and added in r1 of the module here.
|
|
1.1 - Demo of new getPer, getBias and getSinBias methods
I then will want to work out at least one demo that tests these new get percent methods out. With that it would seem that the public methods of the seqhooks main global work great. I am not sure if I will need them or not but I do not thing that these should just be internal or usable for the current state of sequence objects alone.
It would seem that the methods that I added for the seq object work great, and the new get sin bias method results in some cool camera movement and mutation of values effects with fov and so forth.
|
|
1.2 - Fix for partFrame bug in r0, still allows for older functionally depending of seq.pff value
There is then also the question of my new expressions that are used to set the part frame and part frame max values. I need to make sure that things look good when using them and that the part percent values do not equal, let alone go over the value of 1. It would seem that the hard coded expressions that I am using for this work well, but there might come a time where I will run into some weird rendering issues again. To address this I can use the new seq.pff value to change to another built in function that sets these part frame values, including the old expressions from r0. In addition I can also define a custom function for this if need be by just setting the value of seg.pff to a function in which I define the expressions I want to use rather than a string value.
|
|
This might be a killing a mosquito with a cannon kind of situation, but if the r1 expressions work well long enough I might remove this bloat in any future revisions of this and just use the r1 expressions alone for this.
2 - Vector3 Paths feature added in r2 of sequence hooks
The main feature that I wanted to add in r2 of the sequence hooks module is a way to define some paths that can be used to define the motion of objects such as mesh objects and the camera. I have started a few projects outside of this module for this sort of thing, but sense this is a module that I use all the time I thought that if i bake something into this they I will have something at the ready to use right away while I explore options for other ways of doing this sort of thing that might involve things like the Curve class for example.
Anyway the way that I use this so to define one or more path objects that contain an array of Vector3 objects, or an array of numbers that can be converted to such an array. One example of an array fo numbers that would work is the array of a position attribute of a buffer geometry instance which is what I am doing in one of the demos for this revision of the module.
|
|
2.1 - Using an array of Vector3 class instances
In this demo I am creating arrays of Vector3 objects by directly calling the Vector3 constructor function. Chances are that I will not be creating paths this way in actually projects but I just want to confirm that I can create paths this way of I want to. I am thinking that the real way that I would want to create these paths would be to use some function that will create and return an array of vector3 objects.
|
|
2.2 - Using an array of numbers
Here I am testing out that the feature that I added where an array of numbers can be used that will then be converted to an array of vector3 objects works. Here I am using an array literal as a way to define the position of a camera over time. When it comes to the position of a mesh object though I am actually using the position attribute of a buffer geometry as that is an array that is formatted thins kind of way and sure enough that works just fine.
|
|
2.3 - Using curve paths to create the points
This demo of the new v3 paths feature will involve the use of curve paths using the quadratic bezier curve3 class. In future revisions of this module I might want to bake in some features that have to do with creating and using paths with curves actually and mainly the use of this quadratic bezier curve class as it creates the kinds of curves that I would often like to use for movement of objects and look at points in a scene.
|
|
Conclusion
This is looking good so far and I think that I will be using this in place of a similar module that I made before hand that I have been using to make my videos thus far. With that sequence module I have found that there are a few features that I should have in a module such as this that I now have which is great. Mainly it was the before and after objects hooks that I wanted to have the most, but a few more ideas came up that I think I will be using now and then for future video projects.
I am sure that I will end up running into other problems that might result in me wanting to have just a few more additional features on top of what I am working with all ready here with this module. So at some point in the future I will likely make another revision of this module, or maybe a whole other project based off of what I worked out here.