The rotation property of the object3d class in threejs stores a instance of the THREE.Euler class for the current local rotation of an object. What is nice about Euler objects is that they are easy to work with compared to some alternative options such a Quaternion objects, however it is possible to run into problems like Gimbal Lock that can be addressed with such alternatives.
This rotation property is just one value of the base class known as Object3d that is the base of many objects in the library such as Mesh Objects, Groups, Cameras, and many others including even whole Scene Objects.
There is a bit more to this sort of thing beyond just setting rotation with number values though, for example in some cases I might want to set the orientation of a geometry of a mesh object rather than the mesh object itself. For example I might want to set the orientation of a cone geometry so that the tip of the cone is the front face. With this sort of this there is setting the rotation of the geometry once, then using the object3d rotation property from there. That is just one example that I will be getting to in this post along with many others such as setting rotation from position and the inverse of doing so.
The value of the rotation property in the object3d class is an instance of the Euler class which is worth checking out in detail. There is not a whole lot to work with in terms of prototype methods, which is one reason why alternatives to the Euler class are often used. Still there is looking into the class itself more as this is the kind of object that is stored at the rotation property of an object3d class based object.
There is the rotation property of the object3d class, but there is also the quatrenion property as well. Both of these properties of the Object3d class can be used to rotate a object. However Euler objects, and with that the rotation property of the object3d class, have some limitations that can often be resolved by making use of the quaternion class. Quaternion objects are far more complex compared to Euler objects, so if you are just looking for the next step beyond using the look at method Euler objects might still be a better next step before getting into Quaternions. Although I have a section in this post on quaternion objects as an althertive to Euler Objects, it might be best to check out my main post on the subject of quaternion objects.
When it comes to setting the position of an object3d class based object there is the position property which is an instance of the Vector3 class. There is a whole lot to be aware with respect to the methods that there are to work with in this Vector3 class an how many of them relate to, or work with Euler class instances. There is also just having some basic idea of what a Vector ins in general. Many people might think that it is the state of a position, and it is, but it is also direction and what is often called vector unit length.
The object3d class is a base class of many objects in threejs such as cameras and mesh objects. The rotation property of this class is just one property of the class along with additional properties that have to do with things like position and the scale of the object. There is then also a whole lot of useful methods with this class that one should also be aware of that are related to setting the rotation of the class, as well as doing just about everything else I would want to do with an object that is based off of this class.
There is then also what to be aware of when it comes to additional properties on top of the object3d class. For example a Mesh object will also have a geometry and a material property. An instance of a perspective camera will have a field of view property and methods to update the state of the camera when certain camera specific values are mutated.
When I first wrote this post I was using r135 of threejs, which was still a fairly new version of threejs at the time I started this post. The last time I came around to do some editing I made sure all the examples are still working fine with r146. I take a moment to always mention what version I was using when wrote a post on threejs because I have been using it long enough to know that code breaking changes are made to the library often.
To start out with rotation and the object3d class I made this quick static scene example that involves just a few mesh objects created with the box geometry constructor and the normal material. After setting up the scene object, camera, and renderer I then have a simple create cube helper that will create and return one of these cubes. I am then just calling the array for each method off of an array if values that I want to use for rotations of the y value for each cube that I will be creating and adding to the scene in the body of a function that I give to array for each.
The x, y, and z properties for each axis can be updated this way, or the set method can be used to do so. In any case I want to think in terms of radians, or convert degrees to radian values if I prefer to think that way which I often do. Another way to set the state would be to mutate a separate instance of the Euler class and then use the copy method of the Euler class at the rotation property and pass this separate Euler class instance.
There is working with the rotation property of an object directly, but then there is also using the lookAt method of the object3d class as a way to set rotation. This look at method works by just passing a position in terms of a set of three numbers that are values for x, y and z values, or an instance of Vector3 such as the position property of an object that is the position that I want an object to look at.
For this example then I am creating a group of cubes by using a while loop to create and position each cube that I want. I am then looping over the children of the group and calling the look at method for each cube having each child look at the child in front of it, or behind in the case of the last child in the group. In the body of the function that I give to the for each method that I call of the array of children of the group I am just using the index argument as a way to know what I am dealing with in order to get the desired index value of the other cube in the collection that I want to have the current child cube look at.
The end result is more or less what I had in mind for this example, but I think that I will need to write about at least one if not more examples about this sort of thing. The situation here works okay because each of the cubes look more or less the same on each side, for some other mesh objects this might not always be the case with the nature of the geometry. The thing about this is that the rotation property and the look at method are ways of setting the rotation of the object, but not the geometry of a mesh object. In some cases I might want to adjust the rotation not just of a mesh object, but also the geometry at least once in order to change what the ‘front’ of the geometry is.
The rotation property effects just the local rotation of the object in which I set the rotation property. In addition to this there is also setting the rotation properties of any nested children, or in the case of Mesh objects there is rotating or changing the state of the geometry that is used with the Mesh. With that said there are a number of buffer geometry class prototype methods that have to do with the rotaiton of a geometry, rather than the local rotation of a mesh object.
There is a lot of overlap between setting position of objects and setting the rotation of them. The Vector3 class is generally used for position, but it is also use for scale, and in general it can be used for many tasks that involve three number values. In any case I should have a section here in this post about the Vector3 class as there are many features of that class that are closely tied to that of the rotation of objects.
A really cool and useful method in the Vector3 class is the apply Euler method which is the usual go to method for setting the state of a vector3 class based on the state of a Euler class such as the one at the rotation property of a an object3d class based object such as a mesh object.
When I use the apply Euler method I will often define some kind of start position and start out my copying that to the position property of what I want to effect. This start position is more for the purpose of defining what the start direction should be rather than vector unit length. After I set a start position I can then use the apply Euler method as a way to change the direction relative to the start direction, normalize, and then use a method like multiply scalar to set the desired vector unit length.
Okay so there is using the apply Euler method of the Vector3 class to set position based on rotation, but what if I want to do the inverse of that? In other words to set the rotation of an object based on the state of a Vector3 class instance. In the Euler class there is a set from Vector3 method, so there you go the name says it all.
In this example I am creating and updating a Vector3 class instance. With mesh1 I am just simply coping the current state of this vector3 instance to the position property as a way to know the current state of the Vector. With that out of the way with mesh2 I am using this set from vector method to set the rotation of the mesh object based on the state of this vector3 instance. When doing so I might want to clone and normalize the vector depending on the desired outcome.
There are limitations to using Euler objects, and the look at method. I will not be getting into to much detail about them here but if you spend enough time playing around with threejs you will find out what they are first hand I am sure. In this section I am going over just a few quick examples of using Quaternion objects as an alternative to using Euler objects. In other words using the object3d.quaternion property to set local rotation over that of object3d.rotation.
The best way to get started with with Quaternion would be to make use of the set from axis angle method. This method works by passing a normalized Vector3 object that will be used to define an axis. The second argument is then a radian value that will be used to rotate the object on this axis. These quaternion objects are often described as having a vector part, and a scalar part, and this method is more or less one way how to go about setting those two parts.
This is a demo in which I am showing what the deal is with Gimbal Lock, which is something that happens with Euler objects, and how Quaternion can be used to break free from it. I have two objects that are both created from the same helper function that form what looks like a crude kind of airplane type object. I then have not one but two update methods one of which updates the rotation of one of these objects by way of Euler angles, and the other buy way of Quaternion. Both update methods work find when I yaw the objects back and forth, however when I pitch up 90, the object that is using the Euler update method ends up rolling rather than yawing. On the other hand the update method that uses Quaternion works as exspected.
Now for a simple animation example using the request animation frame method in the body of a loop function. Also while I am at it I also made the cubes all children of a group rather than the scene object. So then in this animation example I am using the rotation property of the object3d class to rotate each child of the group over time, as well as the group as a whole.
The rotation property is then what I often used in order to set the rotation of an object such as a mesh object, group or camera. There is also the position property of the object3d class that holds an instance of the Vector3 class that is what is used to store and change the position of the object as well. There are a whole lot of other properties as well as method to be aware of in the object3d class that come into play allot when making one or more threejs projects such as the scale property and the lookAt method just to name a few.