05: transformations
Intro
There are 4 positions which we can use to change a mesh's orientation and position on screen:
position: the object's position in 3d spacescale: the object's sizerotation: the object's rotationquaternion: the object's rotation, but using a different system
Axes helper
The AxesHelper class is a visual aid that shows the axes of the 3D coordinate system on screen. It's useful for debugging and visualising the orientation of objects in 3D space.
To add it, all you have to do is to create an instance of the class and add it to the scene. The constructor takes in a single argument, the unit size of the axes.
const axesHelper = new THREE.AxesHelper(unitSize);
const axesHelper = new THREE.AxesHelper(2);
scene.add(axesHelper);
- The red line corresponds to the
xaxis - The green line corresponds to the
yaxis - The blue line corresponds to the
zaxis
OrbitControls
-
Import the
OrbitControlsclass from thethree/examples/jsm/controls/OrbitControlsmodule.import { OrbitControls } from "three/addons/controls/OrbitControls.js"; -
Instantiate the controls class, passing in the camera and the renderer's DOM element.
const controls = new OrbitControls(camera, renderer.domElement);
Position
The position property on a mesh is actually a Vector3 instance, so it has special properties we can take advantage of.
const mesh = new THREE.Mesh(geometry, material);
mesh.position.x = 2;
mesh.position.y = 1;
mesh.position.z = 1;
Here are some useful properties and methods on the mesh.position property. Also keep in mind that these same properties will exist on the Vector3 class as well.
mesh.position.x: the x position of the meshmesh.position.y: the y position of the meshmesh.position.z: the z position of the meshmesh.position.set(x, y, z): sets the position of the mesh to the given x, y, and z valuesmesh.position.copy(vector3): sets the position of the mesh to the givenVector3instancemesh.position.distanceTo(vector3): returns the distance between the mesh and the givenVector3instancemesh.position.normalize(): normalizes the mesh's position, returns a unit vector.
Vector3 class
const a = new THREE.Vector3(0, 1, 0);
//no arguments; will be initialised to (0, 0, 0)
const b = new THREE.Vector3();
const d = a.distanceTo(b);
Here are some helpful methods you can use on the Vector3 class:
vector3.distanceToSquared(vector3): returns the squared distance between the vector and the givenVector3instancevector3.add(vector3): adds the givenVector3instance to the vector's positionvector3.sub(vector3): subtracts the givenVector3instance from the vector's positionvector3.multiply(vector3): multiplies the vector's position by the givenVector3instancevector3.divide(vector3): divides the vector's position by the givenVector3instancevector3.length(): returns the Euclidean magnitude of the vectorvector3.set(x, y, z): sets the position of the vector to the given x, y, and z valuesvector3.copy(vector3): sets the position of the vector to the givenVector3instancevector3.distanceTo(vector3): returns the distance between the vector and the givenVector3instancevector3.normalize(): normalizes the vector's position, returns a unit vector.
Scaling
The mesh.scale property is also an instance of the Vector3 class, so we can use vector properties and methods to modify the scale.
const mesh = new THREE.Mesh(geometry, material);
mesh.scale.x = 2;
mesh.scale.y = 1;
mesh.scale.z = 1;
Rotation
The mesh.roation property is an instance of the Euler class.
The important thing with rotation is that the units are in radians, so we should use Math.PI in our calculations.
const mesh = new THREE.Mesh(geometry, material);
// rotate 360 degrees
mesh.rotation.x = Math.PI * 2;
Reordering axes
Another thing to consider is that the axes will also rotate as you rotate the object, so to avoid this unpredictable behavior, you can reorder the axes.
Reorder your axes before doing any rotations.
mesh.rotation.reorder("YXZ");
Grouping
Groups in threejs are a way of applying transformations to multiple meshes at once. You add the group to the scene, and then add the meshes to the group.
You achieve this by adding meshes to the group, and then since a group inherits from a 3D object class, it has the same 4 transformation properties available on all objects, like position and scale.
You then modify those vector transformation properties to transform all the meshes in the group at once.
This is how you create a group:
const group = new THREE.Group();
scene.add(group);
And this is how you add a mesh to a group, using group.add(mesh):
const cube1 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
cube1.position.x = -1.5;
group.add(cube1);
group.scale.y = 2;
In the example above, we created a group, added it to the scene, create a cube, added it to the group, and then applied a transformation on the entire group.