When it comes to moving and rotating objects around in threejs there are two general classed that come to mind THREE.Vector3, and THREE.Euler. The Vector3 class has to do with creating an object that represents a Vector in Vector space, and as such the Vector3 class is great for working with a set of numbers that have to do with a specific position in space.
However a Vector can also be though of as a way to go about having a direction in space when it comes to the distance of the vector from the origin. In fact Vectors are often descried as being a direction and a magnitude, that is a normalized set of values between 0 and one for each axis that is then raised to what is often called a euclidean distance from the origin. There is another way of thinking about this though, such as having angels using the Euler class and using that as a way to set the position, or direction and magnitude of a Vector if you prefer.
So in this post I will be looking at the Vector3.applyEuler method and how it can be combined with various other Vector3 prototype methods to accomplish some various tasks.
It might be a good idea to take a second look at the Vector3 class in general and look over what there is to work with when it comes to the various prototype methods beyond that of the apply Euler method. In the examples that I am going over in this post I am not just using the apply Euler method, but a few other Vector3 class methods that have to do with normalizing a Vector3 instance to a Vector3 that is a unit vector of a length of 1 for example. So it might make sense to look into the class more if you still find something like that a little confusing.
In order to use the apply Euler method of the Vector3 class it should go without saying that an instance of the Euler class will be needed. This is then another class that is worth checking out in detail if you have not done so all ready, it is similar to that of Vector3, but is has to do with a collation of three angles.
The source code examples that I am writing about in this post can also be found in my test threejs repo on Github. This is also where I park the code for my many other posts on threejs as well as additional draft demos, noted for future examples and so forth. If you are on Github and see something that might require a pull request that would be where to do so. There is also the comments section of this post that can be used as a means of bringing something up.
When I wrote this post I was using r127 of threejs, and the last time I came around to do a little editing I was using r140 of the library. I have made a habit of making sure that I always mentioning what version I was using when writing a post like this because of code breaking changes that are made to the library often.
For this section I will be going over a few basic examples of the apply Euler method before getting into some more advanced examples that have to do with animation loops, mutation of geometry, and so forth. There is starting out with just the apply Euler method alone, but often when I use the apply Euler method I do so with a number of other vector3 class methods, as well as make use of many other features in the threejs java Script library.
So then lets start out with a basic example of this apply user Vector3 method to gain a scene as to how it works. Here I have an example where I have a create cube helper method that will create and return a Mesh object that uses the Box geometry, and the Mesh normal material. The intention is that I will be creating one or more cubes with this method and using Euler and Vector3 class instances along with the apply Euler Vector3 prototype method as a way to set the position of this cube in a scene.
When positioning the cube I create an Instance of the Euler class that I will be using as the argument value for the apply Euler method. For this example I am using the THREE.MathUtils.getToRad convenience method to convert a degree value to a radian value that is used with the Euler class. For now I am creating a Euler class instance where I have a 45 degree angle for the y value of the Euler class, and I am just leaving the other values at 0.
Next I want to create a new Instance of the THREE.Vector3 class and here is where things get a little tricky. I want to make sure that the length of the Vector3 instance is not zero. The default values for a Vector3 are 0,0,0 and if that is the case applying any Euler value to the vector will not change anything when it comes to the direction of the vector because everything is 0. So for now I am just setting the starting position of the vector at some kind of starting direction such as any positive number on the x axis. I can now call the apply Euler method off of the vector, and apply the Euler instance to the vector.
Now there is doing something with that Vector3 class instance to say set the position of a cube mesh object. When it comes to this the position property of a mesh object is also an instance of Vector3, and as such I can use the copy method of the position property of the mesh to copy the values of this stand alone vector3 to the position property. The result then is that the position of the cube is set to the position of the vector to which I have applied the Euler instance to and I have expected results. The cube is now 45 degrees from the starting position of the vector, and it would seem that the Vector still has the same length that I have set for it.
1.2 - Making a vector from angles and vector unit length using applyEuler, normalize, multiplyScalar
Now that I have a real basic example of the apply Euler method out of the way it is time to get into another example in which I am making use of a few vector3 class methods. For this example I am making a vector from angles method in which I give to angles, and a unit length to get a position from an origin. The angle values that I give are in degrees and once again I am using the Math Utils degree to radian method to convert these values to the radian values that are used for Euler class Objects. The first angle that I give will have a range from 0 to 360, and the second will have a range from 0 to 180, and then the third argument given will be a vector unit length.
So then when it comes to creating and returning a vector I once again start out with a standard starting position, and then call the apply Euler method passing the Euler object that I want to use that has values set from the angle arguments that I given when calling the helper function. I then call the normalize method to set the length of the vector to one while preserving the direction of the vector, and then call multiply scalar to set the unit length to the desired value.
Once again I am making use of the Vector from angles method that I covered in an above example. So then once again I am making use of the apply Euler method as well as normalize, and multiply scalar Vector3 class methods. However I am not making use of additional helper functions that have to do with creating and updating the state of a group of mesh objects. I have one helper function that will just create a group of mesh objects, and then another that will loop over each mesh object in the group and preform actions on each.
One of the actions that is preformed when looping over the mesh objects is to change the position of each mesh object. For this I am of course using the vector from angles method, but I am also making n use of the add method of the Vector3 class to apply an additional delta for each mesh object. On top of this I am also using the Lerp method of the Vector3 class to Lerp all of the mesh objects between a final position based on arguments given as well as another fixed point.
So now that I have a basic example of this worked out, I often like to make at least one or more examples that involve an animation loop function using something like request animation frame, or some other means to do so. This will allow for me to use the apply Euler method over and over again with a range of values to get a better sense of what the apply Euler method does, and why it can prove to be a useful tool when working out various things that have to do with the movement of objects in space.
This example then involves the use of a vector from angles helper method in which I can pass values for the various angles along with a length, and a start vector as a way to create and return a Vector3 instance created with these arguments. It is with this vector from angled helper function that I am using the apply Euler method along with other vector3 class methods to get a desired outcome. I can then use the copy method of the Vector3 class to copy the result that is returned to by the helper as a way to update the position property of an object3d based object such as the mesh objects as I am doing here.
The result is then having the cube move around in a circle around the origin of the scene as expected. So then it is possible to create all kinds of helper methods like this that might come in handy when it comes to creating Vectors than can be applied to a mesh object, or used fr any other purpose that might come up.
This animation loop example is just a continuation of the basic section example that had to do with creating and updating a group. The only real difference is that I am calling the set group method in an update method that is being called over and over again in the animation loop function.
On top of getting values for calling the set group method I can also again use my apply Euler powered vector from angles method to move the group object around as a whole. Both the mesh objects and the group object are object3d based objects that both contain position properties that are instances of Vector3 that I can copy to with the results of the vector from angles helper function calls.
Another Idea of an animation example would involve the mutation of the position attribute of a buffer geometry that is used with a mesh object. When it comes to buffer geometry the position attribute is the first and for most attribute that comes to mind that is used to store the position of each vertex cor each triangle. So the Vector3 apply Euler method could be used to cause some interesting chanced to geometry if I am to create an array of Vector3 instances for each point and use apply Euler as part of the expressions to change the values of the array of vector3 objects, then use this array to update the position attribute if that makes nay sense.
It would seem like there is at times a lot of over lap between the Vector3 class and the Euler class, and there is a lot of similarities between the two. I remember that when I was first getting started wit threejs that I would often confuse the two, but it is a good idea to work out the confusion. When it comes to Vector3 instances I am dealing with three properties that have to do with an x, y, and z, values and these values often have to do with a position in space. However they can be used for many other things such as ratios that have to do with these values that can then be applied to another Vector3 instance, or a Euler instance. With a Euler class instance it is a similar situation when it comes to the property values, however now I am dealing with radian values that represent angles.