In this exercise, we import a different FBX model, and we also import several animation clips for the model. We then create buttons to smoothly transition the model between each animation clip.
For this exercise, you should download the character model named "Vanguard By T. Choonyung" from Mixamo and save it into your ./dist/client/models/ folder. Save it as vanguard_t_choonyung.fbx using the options FBX Binary(.fbx) and T-Pose.
Also download the animations separately, save them into your ./dist/client/models/ folder using the options FBX Binary(.fbx) and Without Skin. Rename them as below.
import*asTHREEfrom'three'import{OrbitControls}from'three/examples/jsm/controls/OrbitControls'import{FBXLoader}from'three/examples/jsm/loaders/FBXLoader'importStatsfrom'three/examples/jsm/libs/stats.module'import{GUI}from'dat.gui'constscene=newTHREE.Scene()scene.add(newTHREE.AxesHelper(5))constlight=newTHREE.PointLight(0xffffff,1000)light.position.set(2.5,7.5,15)scene.add(light)constcamera=newTHREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)camera.position.set(0.8,1.4,1.0)constrenderer=newTHREE.WebGLRenderer()renderer.setSize(window.innerWidth,window.innerHeight)document.body.appendChild(renderer.domElement)constcontrols=newOrbitControls(camera,renderer.domElement)controls.enableDamping=truecontrols.target.set(0,1,0)letmixer:THREE.AnimationMixerletmodelReady=falseconstanimationActions:THREE.AnimationAction[]=[]letactiveAction:THREE.AnimationActionletlastAction:THREE.AnimationActionconstfbxLoader:FBXLoader=newFBXLoader()fbxLoader.load('models/vanguard_t_choonyung.fbx',(object)=>{object.scale.set(0.01,0.01,0.01)mixer=newTHREE.AnimationMixer(object)constanimationAction=mixer.clipAction((objectasTHREE.Object3D).animations[0])animationActions.push(animationAction)animationsFolder.add(animations,'default')activeAction=animationActions[0]scene.add(object)//add an animation from another filefbxLoader.load('models/[email protected]',(object)=>{console.log('loaded samba')constanimationAction=mixer.clipAction((objectasTHREE.Object3D).animations[0])animationActions.push(animationAction)animationsFolder.add(animations,'samba')//add an animation from another filefbxLoader.load('models/[email protected]',(object)=>{console.log('loaded bellydance')constanimationAction=mixer.clipAction((objectasTHREE.Object3D).animations[0])animationActions.push(animationAction)animationsFolder.add(animations,'bellydance')//add an animation from another filefbxLoader.load('models/[email protected]',(object)=>{console.log('loaded goofyrunning');(objectasTHREE.Object3D).animations[0].tracks.shift()//delete the specific track that moves the object forward while running//console.dir((object as THREE.Object3D).animations[0])constanimationAction=mixer.clipAction((objectasTHREE.Object3D).animations[0])animationActions.push(animationAction)animationsFolder.add(animations,'goofyrunning')modelReady=true},(xhr)=>{console.log((xhr.loaded/xhr.total)*100+'% loaded')},(error)=>{console.log(error)})},(xhr)=>{console.log((xhr.loaded/xhr.total)*100+'% loaded')},(error)=>{console.log(error)})},(xhr)=>{console.log((xhr.loaded/xhr.total)*100+'% loaded')},(error)=>{console.log(error)})},(xhr)=>{console.log((xhr.loaded/xhr.total)*100+'% loaded')},(error)=>{console.log(error)})window.addEventListener('resize',onWindowResize,false)functiononWindowResize(){camera.aspect=window.innerWidth/window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth,window.innerHeight)render()}conststats=newStats()document.body.appendChild(stats.dom)constanimations={default:function(){setAction(animationActions[0])},samba:function(){setAction(animationActions[1])},bellydance:function(){setAction(animationActions[2])},goofyrunning:function(){setAction(animationActions[3])},}constsetAction=(toAction:THREE.AnimationAction)=>{if(toAction!=activeAction){lastAction=activeActionactiveAction=toAction//lastAction.stop()lastAction.fadeOut(1)activeAction.reset()activeAction.fadeIn(1)activeAction.play()}}constgui=newGUI()constanimationsFolder=gui.addFolder('Animations')animationsFolder.open()constclock=newTHREE.Clock()functionanimate(){requestAnimationFrame(animate)controls.update()if(modelReady)mixer.update(clock.getDelta())render()stats.update()}functionrender(){renderer.render(scene,camera)}animate()