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.
Samba Dancing (In Place Version) --> Rename to vanguard@samba.fbx
Belly Dancing --> Rename to vanguard@bellydance.fbx
Goofy Running --> Rename to vanguard@goofyrunning.fbx
or direct download and save all models into ./dist/client/models
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/vanguard@samba.fbx',(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/vanguard@bellydance.fbx',(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/vanguard@goofyrunning.fbx',(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()