Manipulating and Animating 3D Model in Three.js
Load 3D Model
To load a 3D model in Three.js, we use the GLTFLoader to load GLTF or GLB files. Here's how you can load a 3D model
1import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
2
3const loader = new GLTFLoader();
4 loader.load(
5 "/3d/dog.glb",
6 (gltf) => {
7 const model = gltf.scene;
8 this.scene.add(model);
9 },
10 function (xhr) {
11 console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
12 },
13
14 function (err) {
15 console.log(err.message);
16 }
17 );
The loaded 3D model consists of several objects, often with a hierarchy. To manipulate the 3D model, you need to traverse its children.
Manipulating Loaded Model
1. Position
To set the position of the entire model
1const loader = new GLTFLoader();
2loader.load(
3 "/3d/dog.glb",
4 (gltf) => {
5 const model = gltf.scene;
6 model.position.set(x,y,z)
7 }
8);
To set the position of a specific child object
1model.traverse((child) => {
2 if (child.isMesh && child.name === 'specificChildName') {
3 child.position.set(2, 2, 2);
4 }
5});
2. Color
You need to traverse the model to set the color of each mesh
1const loader = new GLTFLoader();
2loader.load("/3d/dog.glb",
3 (gltf) => {
4 const model = gltf.scene;
5 model.traverse(child => {
6 if(child.isMesh) {
7 child.material.color.set(0xff0000)
8 }
9 })
10 }
11);
Why gltf.scene.material.color.set() doesn't work?
gltf.scene is usually a Group or Object3D that contains other objects, such as meshes. Only mesh objects have materials, so you need to traverse the scene and apply the color change to each mesh's material individually.
3. Size
To set the scale of the entire model
1const loader = new GLTFLoader();
2loader.load(
3 "/3d/dog.glb",
4 (gltf) => {
5 const model = gltf.scene;
6 model.scale.set(x,y,z)
7 }
8);
To set the scale of a specific child object
1model.traverse((child) => {
2 if (child.isMesh && child.name === 'specificChildName') {
3 child.scale.set(1.5, 1.5, 1.5);
4 }
5});
4. Rotation
To set the rotation of entire model
1const loader = new GLTFLoader();
2loader.load(
3 "/3d/dog.glb",
4 (gltf) => {
5 const model = gltf.scene;
6 model.rotation.set(x,y,z)
7 }
8);
To set the rotation of a specific child object
1model.traverse((child) => {
2 if (child.isMesh && child.name === 'specificChildName') {
3 child.rotation.set(1.5, 1.5, 1.5);
4 }
5});
Controling Animation
1. AnimationMixer
The AnimationMixer is a player for animations on a particular object in the scene.
1const loader = new GLTFLoader();
2const clock = new THREE.Clock()
3const actions = {}
4
5loader.load("/3d/dog.glb",
6 (gltf) => {
7 const mixer = new THREE.AnimationMixer(gltf.scene)
8 gltf.animations.forEach(clip => {
9 //.clipAnimation return AnimationAction from clip
10
11 const animationAction = mixer.clipAction(clip)
12 actions[clip.name] = animationAction
13
14 })
15 }
16);
17
18const animate = () => {
19 requestAnimationFrame(animate)
20 mixer.update(clock.getDelta())
21}
2. AnimationClip
AnimationClip is a reusable set of keyframe track which represent an animation. These AnimationClips stored in gltf.animation property
1loader.load("/3d/dog.glb",
2 (gltf) => {
3 gltf.animations.forEach(clip => {
4 //.clipAction return AnimationAction from clip
5 const animationAction = mixer.clipAction(clip)
6 actions[clip.name] = animationAction
7 })
8 }
9);
3. AnimationAction
AnimationAction is an object that controls the playback of an animation clip. It is part of the animation system and work with AnimationMixer, AnimationClip and KeyframeTrack to create, control and play animations on objects in the scene
1actions['actionA'].play() // plays the animation
2actions['actionA'].stop() // stops the animation
3actions['actionA'].reset() // resets the animation to the start
4actions['actionA'].fadeIn(duration) // fades in the animation over the specified duration
5actions['actionA'].fadeOut(duration) // fades out the animation over the specified duration
6actions['actionA'].setLoop(mode, repetitions) // sets the loop mode and number of repetitions
7actions['actionA'].setEffectiveTimeScale(timeScale) // sets the playback speed of the animation
8actions['actionA'].setEffectiveWeight(weight) // sets the blend weight of the animation