Page 5: Hierarchical Modeling in THREE
CS559 Spring 2023 Sample Solution
In THREE, objects (instances of Object3D
) can contain other objects. Rather than adding an object directly to the scene, we can add an object to another object. This parent object can be added to the scene (or to another object). In order to be in the scene, an object either needs to be added to the scene, or added to some object who has a parent that is part of the scene (recursively).
In the previous workbook (and in class), we learned that in THREE, every object (technically, every instance of Object3D
, which is the base class for just about everything), has its own transformation associated with it.
This transformation is relative to the object’s parent. If the object is simply placed in the scene, the transformation is relative to the scene (the scene is not actually an Object3D
). However, if the object is a child of some other object, then its transformation is relative to that object. If you transform the parent, the children are transformed as well.
When an object has a parent, its transformation is composed with the parent transformation. In class we talked about how this trickles along the tree of object containment.
In THREE, there are special Group
objects (documentation for `Group`). These objects have no geometry themselves - they exist only to serve as the parents for other objects.
The THREE documentation for `Object3D` says: Note that this can be used for grouping objects via the .add( object ) method which adds the object as a child, however it is better to use Group for this.
It is unclear why it is better, or when you have to use a group rather than simply adding a child object to some regular object.
Here’s an example
07-05-01.html and
07-05-01.js that creates a simple hierarchy. We use the framework (you’ll get to it on Page 7 (The CS559 Framework Code (GraphicsTown))) because it makes the sliders easy. Don’t worry about SliderCube
for now - think of it as making a normal THREE cube, except that it has its parameters connected to sliders. Similarly, the GrWorld
has the THREE Scene
and Renderer
inside of it (it takes care of setting everything up for us).
The important part is that it makes 2 cubes (a green one and a cyan one). The cubes are obj0
and obj1
(they were created inside of framework objects, and pulled out around line 49). You can change their position and scale using the sliders.
In the code it does obj0.add(obj1);
which is the normal three hierarchy building. obj0
and obj1
are THREE Object3D
objects (Mesh
- if you want to be precise).
07-05-01
Notice how the green cube is in the “world” coordinate system ((0,0,0) is the center of the ground plane). It has height 1, so its center is 1 unit above the floor (which means it floats, since it is 1 unit in size). The cyan cube is in the green cube’s coordinate system - it sits on top of the green cube since its center is 1 unit above the green cube. You can change these with the sliders. Notice that scale does affect the children: when you change the scale of green cube, the cyan cube is affected. Its position and scale depend on the coordinate system them are in.
One detail: the green cube is added to the Scene
(technically, it is added to world
which has a Scene
inside of it), the cyan cube is added to the green cube. Each object is just added to its “parent”.
Other Compositions
Notice that in the previous example, the cubes rotate around their centers. In THREE, objects rotate and scale around their centers. If we were making transformations ourselves, we could change that (by composing translations and the rotate/scale - hopefully you remember how to do that). Using THREE, we will need to use hierarchy as a mechanism to achieve this.
So, if I want to rotate an object (the cyan cube) around a point other than its center, what I need to do is make another object (a Group
is good for this), place this new object’s center where a want to rotate around, and then place the original object (cyan) properly in the coordinate system of the new object.
Here’s an example ( 07-05-02.html and 07-05-02.js). Typically, you can’t see groups, so I’ve added lines for the X,Y and Z axes of the group so you can see where it is.
07-05-02
Notice that rotating the cyan cube still rotates it about its center - if we want to rotate the cyan cube around its corner, we use the rotation of the group. The group has been strategically place such that its center is where the corner of the cyan cube will go (and the cyan cube is place in the group so its corner is at the origin). We actually use the same positive/negative transformations we used to create rotation around center transformations.
|
|
Notice how the green cube is placed above the table (the last three parameters are the initial x,y, and z). The group is place at the top corner of the cube (since that’s where we want to rotate around). The cyan cube is placed relative to the group.
For now, try to understand how we use hierarchy in THREE to achieve the transformations we want. Later, after you learn about the framework (on page Page 7 (The CS559 Framework Code (GraphicsTown))), you may want to come back to 07-05-02.js to understand how it works.
What about save/restore
When we did hierarchical modeling in 2D Canvas, we had to worry about saving and restoring transformations. We talked about how we use the “transformation stack” to implement hierarchy.
When we use a scene graph API like THREE, the steps of applying and saving transformations are taken care of as part of the scene graph traversal process. Basically, in order to do drawing, the tree must be traversed to visit all objects. As part of this process, the transformations are applied appropriately. The algorithm for doing this involves saving the state before descending down the tree to a child node, and restoring the state when returning to a higher level node in the tree. This is usually (but not always) implemented using a matrix stack. The books FCG4_Ch12.pdf (0.9mb) (section 12.2) and Hart07-jan19.pdf (14.5mb) discuss this if you’re curious. But for now, THREE will take care of it for us.
Summary: Hierarchical Modeling in THREE.JS
Now we’ve seen how hierarchical modeling works in THREE. On the next pages, you’ll get to try it. First, to make a quadcopter again (like you did in 2D), and then to use the CS559 code framework. Be sure to do all three exercises.
Start with the quadcopter on Page 6 (Exercise 1: Quadcopter / Multi-Rotor), and then read about the CS559 code framework on Page 7 (The CS559 Framework Code (GraphicsTown)) before the last two exercises.