84 Three.js AnimationMixerを使用した変形アニメーション

15635 ワード

前言
ここ数日ずっと小さなゲームのケースを作っています.前に学んだことを強固にしましょう.私が作ったケースの特効を見たいなら、ウェブサイトを見ることができます.http://www.wjceo.com/blog/demo/2018-04-09/144.html 次はこの節の内容を始めます.
概要
外部ソフトウェア(Blenderなど)を使用してアニメーションを作成する場合、通常、 の2つの主要なアニメーション定義方法があります.このセクションでは、 について説明します.変形アニメーションを使用するには、メッシュの変形後の状態、またはキー位置を定義する必要があります.変形ターゲットの場合、すべての頂点位置が格納されます.必要なのは、すべての頂点を1つの位置から別の定義されたキー位置に移動し、このプロセスを繰り返すことです. の利点は、各動作の各頂点の位置を格納するため、ファイルが大きくなるという欠点があるため、より良い効果を得ることができることである.
実装事例
ケース・ビューのアドレス:http://www.wjceo.com/blog/threejs/2018-04-13/145.html -まず、JSON形式のモデルを導入し、テクスチャを追加し、sceneにインポートしました.
        //    
        var loader = new THREE.JSONLoader();
        loader.load("/lib/models/animated/horse.js", function (geometry) {
            mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
                vertexColors: THREE.FaceColors,
                morphTargets: true
            }));
            mesh.scale.set(0.1, 0.1, 0.1);
            scene.add(mesh);
        });
  • 次に、meshによってAnimationMixerオブジェクト:
  • を取得するアニメーションの処理を開始します.
    //AnimationMixer              。              ,           AnimationMixer
    mixer = new THREE.AnimationMixer(mesh);
    AnimationMixerオブジェクトは、シーン内の特定のオブジェクトのアニメーションプレーヤーである.シーン内の複数のオブジェクトが独立してアニメーション化されている場合、各オブジェクトに対して1つのAnimationMixerを使用できます.このオブジェクトを介してアニメーションを実装する必要があります.
  • その後、AnimationClipの静的方法CreateFromMorphTargetSequenceによって、実行する必要があるアニメーションセグメント:
  • を取得する.
    //CreateFromMorphTargetSequence   geometry.morphTargets    AnimationClip  ,             
    var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('run', geometry.morphTargets, 30);
  • は、AnimationMixerオブジェクトのclipActionメソッドを使用して、アニメーションの実行を制御できるインスタンスを生成する.
  • action = mixer.clipAction(clip);
  • 最後に、setDurationを使用してサイクル時間を設定し、playメソッドを呼び出してアニメーションを開始すればよい:
  • action.setDuration(1).play();

    ケースコード
    
    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <style type="text/css">
            html, body {
                margin: 0;
                height: 100%;
            }
    
            canvas {
                display: block;
            }
        style>
    head>
    
    <body onload="draw();">
    body>
    <script src="/lib/three.js">script>
    <script src="/lib/js/controls/OrbitControls.js">script>
    <script src="/lib/js/libs/stats.min.js">script>
    <script src="/lib/js/libs/dat.gui.min.js">script>
    <script src="/lib/js/Detector.js">script>
    
    <script>
        var renderer, camera, scene, gui, light, stats, controls, mesh, mixer, action;
        var clock = new THREE.Clock();
    
        function initRender() {
            renderer = new THREE.WebGLRenderer({antialias: true});
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor(0xeeeeee);
            //           
            document.body.appendChild(renderer.domElement);
        }
    
        function initCamera() {
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(0, 40, 50);
        }
    
        function initScene() {
            scene = new THREE.Scene();
        }
    
        //   dat.GUI      
        function initGui() {
            //                  
            gui = {
                animation: true
            };
            var datGui = new dat.GUI();
            //        gui  ,gui.add(  ,  ,   ,   )
            datGui.add(gui, "animation").onChange(function (e) {
                if (e) {
                    action.play();
                }
                else {
                    action.stop();
                }
            });
        }
    
        function initLight() {
            scene.add(new THREE.AmbientLight(0x444444));
    
            light = new THREE.PointLight(0xffffff);
            light.position.set(0, 50, 0);
    
            //             
            light.castShadow = true;
    
            scene.add(light);
        }
    
        function initModel() {
    
            //    
            var helper = new THREE.AxesHelper(50);
            scene.add(helper);
    
            //    
            var loader = new THREE.JSONLoader();
            loader.load("/lib/models/animated/horse.js", function (geometry) {
                console.log(geometry);
    
                mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
                    vertexColors: THREE.FaceColors,
                    morphTargets: true
                }));
                mesh.scale.set(0.1, 0.1, 0.1);
                scene.add(mesh);
                //AnimationMixer              。              ,           AnimationMixer
                mixer = new THREE.AnimationMixer(mesh);
    
                //CreateFromMorphTargetSequence   geometry.morphTargets    AnimationClip  ,             
                var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('run', geometry.morphTargets, 30);
    
                //mixer.clipAction            AnimationAction          AnimationClip   
                //AnimationAction.setDuration             ,       
                //  AnimationAction     
                action = mixer.clipAction(clip);
                action.setDuration(1).play();
            });
        }
    
        //       
        function initStats() {
            stats = new Stats();
            document.body.appendChild(stats.dom);
        }
    
        function initControls() {
    
            controls = new THREE.OrbitControls(camera, renderer.domElement);
    
            //     animate   ,      
            //controls.addEventListener( 'change', render );
            //                      
            controls.enableDamping = true;
            //                  
            //controls.dampingFactor = 0.25;
            //      
            controls.enableZoom = true;
            //      
            controls.autoRotate = true;
            controls.autoRotateSpeed = 0.5;
            //             
            controls.minDistance = 1;
            //             
            controls.maxDistance = 2000;
            //        
            controls.enablePan = true;
        }
    
        function render() {
    
            var time = clock.getDelta();
            if (mixer) {
                mixer.update(time);
            }
    
            controls.update();
        }
    
        //         
        function onWindowResize() {
    
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            render();
            renderer.setSize(window.innerWidth, window.innerHeight);
    
        }
    
        function animate() {
            //     
            render();
    
            //      
            stats.update();
    
            renderer.render(scene, camera);
    
            requestAnimationFrame(animate);
        }
    
        function draw() {
            //     
            if (!Detector.webgl) Detector.addGetWebGLMessage();
    
            initGui();
            initRender();
            initScene();
            initCamera();
            initLight();
            initModel();
            initControls();
            initStats();
    
            animate();
            window.onresize = onWindowResize;
        }
    
    
    script>
    html>