Object3D Class in threejs
The Object3D base class in threejs is one of the most important classes to be aware of when making some kind of project. It is the base class of mesh objects, but also just about every other kind of object that would be added to a scene object such as cameras, groups, lights, various helper objects and so forth. So then to learn a thing or two about object3d is also to learn a thing about all of those kinds of objects that I have mentioned. For example to set the position of a mesh object I need to use the the object3d position property to so so and the same is also true of cameras, groups, and so forth.
In this post I will be going over many of the basics of what the Object3d class is all about in threejs, when it comes to working with the class directly. However more often than not it is a class that I am working with indirectly each time I want to move or rotate a camera, mesh object, or anything to that effect that is based off the the object3d base class. In the process of going over the Object3d class I will also be touching base on many other classes that are important also, such as the Vector3 class and the Euler Class that are used as the values for many note worthy properties of this major base class.
The Object3d class and what to know before hand
Source code examples are up on Github
The source code examples that I am writing about in this post can be found in my test threejs repository on Github. This is also a repo where I park the source code examples for my many other threejs blog posts that I have wrote over the years. So there is a folder in the repo of this post, but also ever other post as well.
Version Numbers matter with three.js big time
As with any post on threejs the version number matters a lot, when I first started this post I was using three.js r91, and the last time I updated the post I was using r146 of threejs. Threejs is a project in motion so if any code in this post or any other threejs post breaks it might very well be because of the version number that you are using, at least that is the first thing that you should check anyway.
1 - Basic object3d class examples
For this first opening section I will be going over just a few quick basic examples of the object3d class. The main focus here will then be just creating an object3d class object, but also working with other objects that are based on the object3d class. Sense this is a basic section the examples will remain fairly simple, and copy and paste style friendly. They will also just involve very simple basic static scenes of just one or two objects just for the sake of demoing some very basic features of object3d.
1.1 - A Very Basic example of Object3d using the position property
Here I made just a simple example where I am just playing with the position property of the object3d class, which is an instance of Vector3. Vector3 is yet another class in threejs that a developer should be familiar with as it has to do with a single point in 3d space, so it goes without saying that class will come up a lot also.
The position property of Object3d can be used to set the center point of the object in a Scene. In the case that the Object is a child of another object it would be the position relative to the parent Object.
1.2 - Basic Object3d rotation example using set and copy of the Euler class
In this example I am directly creating an instance of Object3d, and then using the Euler set method to set some angles for the rotation of this instance of Object3d. I then create a full Mesh object which has Object3d as a base class, so there is a corresponding rotation property of the mesh object that also have an instance of Euler as the value. I then call the copy method of the rotation property of the mesh and pass the rotation property value to it, and the result is the mesh object being set to the same values as this instance of Object3d.
I will not get into the Euler Class in detail here, but it is similar to Vector3 only when using the set method you want to give radians rather than, and x, y, z position in the scene.
1.3 - Setting the Rotation by making use of the Object3d lookAt method
Another property of the Object3D base class that I use often is the rotation property. This property expects an instance of the Euler Class, Which is the Class used in threejs that has anything to do with a set of Euler Angles. So when creating or changing the values of a Euler class instance there are three angles that need to be given in the form of a radian value between 0 and Math.PI * 2.
The set method of a Euler class instance can be used to set the values of these angles by passing three angle values for the Euler instance. Another way to set the value of a Euler class instance is to use the copy method that will set the values of the Euler class instance from which the copy method is called to the given Euler Class instance. So then in this section I will be going over at least a few examples of rotation, but also position while I am at it also.
One very useful method of the Object3d class is the lookAt method which is another way to go about setting the rotation value of an instance of Objected or anything that is based on top of Object3d such as a Mesh object. The look at method can be passed three primitive values for a position in vector space, or an instance of Vector3 such as the position property of another object based off of object3d such as a Camera.
So then there is using the look at method, and then there is working directly with the instance of Euler. However in any case this is a major part of what the Object3d class is about. There is setting the position of an object, and then there is setting the orientation of an object.
2 - Examples of use in other constructors
There are many objects in threejs that inherit from the object3D class, which is why this is a good class to have a solid understanding of object3d as it applies to a lot of different objects that will be worked with all the time in various projects. When it comes to setting the position and orientation of a perspective camera for example the Object3d position and rotation properties is the way to go about doing so. The Object3d look at method can also be used to set the rotation of the camera to look at a given point or object. However all of this does not just apply to cameras, but all objects based off of object3d. So the look at method can be used to have a camera look at an mesh object, and the same method can also be used to make that mesh object face the camera as well sense the look at method is a method of the object3d class.
I have wrote a blog posts on the type property of the object3d class in which I get into this sort of thing in detail. However I think that I should also have a section on this topic in the main object3d blog post as well. So then in this section I will then be going over some source code examples that have to do with using object3d features in the various different kinds of objects that are based off of object3d.
2.1 - Camera objects are based off of object3d
The camera base class is based off of the object3d class, so when it comes to working with a camera such as the perspective camera I can use object3d features as a way to set the position and rotation of a camera. So then in this example I am doing just that, using the object3d features to move a camera around and then also have the camera look at a fixed location again by making use of the look at method.
I have wrote a blog post on the subject of camera movement in threejs, but what applies for cameras also applies for objects in general of course. There is looking into all the various ways to go about moving cameras, and objects in general over time then such as using curves to do so which I think is a great way to do so.
2.2 - Mesh objects are based off of object3d
Mesh objects are one or the major objects that I end up using all the time in a project that are based off of object3d as well. This is a kind of object where I must create a buffer geometry of one kind or another and pass the as the first argument. After getting a geometry together there is also of course looking into the various options when it comes to mesh materials that are used to skin the geometry of the mesh object.
In this example I am once again using the position property of a mesh object to set the position. Also I am making use of the look at method to make it so that the mesh object always faces the origin of the scene object.
2.3 - Points type object3 based objects
There are also points objects that can be used as one alternative option to the typical mesh object. This kind of object will just use the position attribute of a buffer geometry to render just points in space. All other attributes of the buffer geometry will then not be used with this kind of object, with some exceptions such as color attributes if one will like to use vertex coloring as a way to style the points.
When using this kind of object I am limited to just using the points material as a way to skin the points. This is then one major reason why more often than now I would not want to use points to create particles, although the good thing about them is that they will eat up less overhead when it comes to a real time project of some kind.
3 - The name property of the Object3d class
Yet another note worthy aspect of the Object3d class is the name property of the class as well as the get object by name method. This name property is a way to set a unique name for an object, once that is done the get object by name method can be used as a way to gain a reference to the object at a later point in a body of javaScipt code. This can prove to be a useful way to get references to any object that is attached as a child of an object that I have a reference to begin with. So if i have a variable to an object3d based object, and I want to get a reference to a child of that object, one way would be to set and use names to get references to a specific child object. So in this secton I will be going over some quick exmaples of this kind of feature.
3.1 - Basic get object by name object3d class method example
For a basic example here I am adding a whole bunch of child objects to a main scene object. While I am creating the child objects of the scene object I am making sure to set names for all of these objects inside the loop in which I am creating them and adding them t0o the main scene object. Later on I can use the get object by name method of the main scene object to get references to each of the child objects this way.
This might not be the best example of this feature of the object3d class ans there are other ways of getting references to child objects of a single parent object such as just using the children array to do so for example. However for this first example of the section it is just the general idea of this that I want to get out of the way. The use of names becomes very helpful with situations in which I have many nested objects and I would like to set a specific name for each part of an over all larger collection of objects.
4 - The get world positon method
The get world position method of the object3d method is a must known about method when it comes to taking care of certain problems that will come up that have to do with the difference between local space, and world space. What I mean by that is that when dealing with an object that is a child of another parent object the position of the object is relative to the parent object and not the over all world space. In some cases I might want to get the position of a child object relative to world space rather than the local space of the parent object, and for these kinds of tasks there is of course the get world position method.
4.1 - Basic example of the get world position method
Here I have a fairly basic example of the get world position method that should help to showcase what this get world position method is all about. Here I have a parent object, and then one child object of the parent object. I move the position of the parent object so that it is not lined up with the origin of world space, and then I also move the child object to a location relative to the parent object. I then have a loop in which I am using the vector3 lerp method to lerp between two vector3 objects. One vector3 object is the world space relative position of the object and the other is the value that is local to the parent object. The camera then looks back and froth between where the mesh object actually is and then where it would be if the mesh object was not a child of the parent object, but rather lined up with world space.
5 - Setting the Scale of an object
The scale property of an instance of Object3d contains and instance of Vector3 that can be used to change the scale of an object. By default the values for this vector3 instance are 1,1,1 but they can be changed to something like 2,2,2 which would cause the object to be scaled up to a size that is twice the side of the objects original size. So it would go without saying that this also proves to be a very useful property in the object3d class along with position and rotation. In this section then I will be looking at a few examples that have to do with making use of the scale property of the object3d class then.
5.1 - Basic scale property example
For this example then I create a single mesh object that will serve as a source object or sorts that I will make copies of by making use of the clone method of the mesh object class. There are some things that I think I should say about the clone method that is used with mesh objects. One thing to be aware of is that there is a clone method of the mesh class that will supersede the object3d clone method. However maybe the mosu impotent thing to be aware of here is that the clone method will not deep copy geometry and materials. Also when it makes clones of any and all children it will not copy geometry and materials for all children also. However for this example at least this will not present a problem as I just want to scale the objects themselves and using the same geometry and materials for all objects will work fine.
Inside the body of a loop I call the clone method of the source mesh object, and the result that is returned is a clone of the source object. I can then set a new scale for this copy of the source mesh object, and while doing so I can also adjust the position of it as well. The end result is then a whole bunch of mesh objects that are all cloned from a single source mesh object, but with the scale adjusted for each of them.
6 - The user data object.
The user data object is the standard go to object in an instance of Object3d that can be used to park user defined data. In other words when it comes to me making my own modules and applications based off of three.js and I want to append some data to an object in three.js this user data object is how I can go about doing so without messing up anything that three.js depends on.
7 - Animation loop examples
In this section I will not be going over a few animation loop examples of the object3d class. There is a whole lot of what I have covered in the above examples of course, so now it is time to apply what was covered to make at least one if not many cool little animation projects. While I am at it here I can also write about all kinds of other topics that might pop up when making animations as well of course.
7.1 - Basic spin animation example of a rotation
Now I think I should get into at least one or more simple animations that involve just playing around with the Euler instance of a Mesh object, or some other things that make use of the Object3d class and thus the rotation property of the class. To start off with maybe it would be good to just have a simple rotating or spinning cube animation example.
7.2 - An rotation animation making a mesh following a point moving up and down on the z axis
In this object3d rotation animation example I have an instance of vector3 in a state object along with many other little values that have to do with updating the state of an animation. This vector3 instance in the state object is juts having its z axis value move up and down along the z axis and that is it. I can then use that instance of verctor3 to set the position of a mesh object that has a sphere as a geometry. In addition sense this is a demo about rotation I can set the orientation of another mesh object of a box to look at this instance of vector3 with the lookAt method.
So then this is where things can start to get a little run with it comes to playing around with rotation and position. There is not much to look at here, but it is a start at least when it comes to really getting up and running with three.js. When this demo is up and running a sphere is moving up and down along the z axis, and the box ends up facing that sphere. However there is doing much more with rotations than just having a box face another mesh.
7.3 - Object3D loop example that uses the class as a way to group
The Three.Group constructor also inherits from Object3d and is a way of grouping objects together into a collection. However the add method of Object3d is in all objects that inherit from Object3d, and as such grouping can be done with any such object, including just a stand alone instance of Object3d.
I try to make it a habit to have at least one copy and past working demo of what it is that I am writing about in each blog post of mine. In this demo I am making use of an instance of Object3D to group some cubes together. I am also working with many other objects that inherit from Object3D, using the position, and rotation properties often.
So I started off this example of Object3d by creating an createCubeStack helper method. This method will return an object that contains a group property that is what will be added to the scene later on, and also a set method that can be used to change the stack of the stack relative to a value between zero and one.
In this helper I am also using the clone method of a mesh to create a copy of an original mesh that is then mutated just slightly and then added to the group created with the Object3d constructor.
So now that I have a helper method worked out it would be nice to test it out with a scene, renderer, and main app loop, so lets take a look at that then.
So then here I have the rest of the example that makes use of the create cube stack helper. I create a scene, camera, and renderer just like with any threejs example. However I now use my create cube stack helper to create an cube stack object which contains a group property. That group property is then what I add to the scene, and the set method of the cube stack object is what I use to update the stack in a main app loop.
When this example is up and running I get a stack of cubes rotating around and moving up and down. Thanks to the position, and rotation properties of the Object3d class.
It may be true that Object3D by itself is not intended to be used from grouping as there is a separate constructor for that, called simply enough Group. Still Object3D by itself seems to work okay by itself good enough for this simple demo on Object3D.
From here you might choose to make some more demos that have to do with exercising the use of working with objects in three.js. There is working out some examples that involve using the rotation and position properties in an instance of a camera to change the position and orientation of a camera over time.
If you enjoyed this post you might also like to check out my many other posts on the subject of threejs, or better yet by post on my main three.js project examples that I have made thus far. One example that I have made that applies to object3d is my scene shake example, where I have a shake module that will shake the whole scene if I pass the scene object as the object to apply the shake to and I do not add the camera to the scene, however I can also pass anything that is based off of object3d also.