如何正确利用settimeout函数使用three.js旋转多维数据集

时间:2019-03-25 20:47:17

标签: javascript three.js settimeout requestanimationframe

我正在编写的程序将用于旋转立方体。该html文件将允许用户输入带有四元数数据的csv文件。然后,javascript代码使用数据文件中的每个四元数以恒定速率旋转多维数据集。在这种情况下,每16.7毫秒(60 fps)将每个新的四元数应用于多维数据集。我编写的当前程序使用setTimeout执行此目标。

这是我当前拥有的javascript代码:

    <script>

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( { color: 0x00ff70 } );
    var cube = new THREE.Mesh( geometry, material );
    scene.add( cube );

    camera.position.z = 5;
    renderer.render(scene,camera);


    var animate = function() {

        quat_data = [];

        var rotate = function(quat) {
          cube.applyQuaternion(quat);
        }

        for(i=0; i<quat_data.length; i++) {
            time = 16.7;
            var next_quat = quat_data[i];
            setTimeout(rotate(next_quat), time);
        }


    }



    </script>

用户单击浏览器显示屏顶部的按钮以执行动画功能。另外,请注意quat_data当前为空。为了测试javascript代码,我将quat_data设置为样本四元数数组。我尚未编写将输入的csv文件转换为数组的代码。一旦完成,我将使用它代替样本四元数。

问题是,当我运行该程序时,该多维数据集会显示,但不会旋转。我包括足够的样本四元数以能够观察旋转,因此缺少四元数不是问题。我没有控制台错误。我已经尝试过添加行

renderer.render(scene,camera);

在rotate函数内以及代码中的其他几个位置,但这并没有重新渲染多维数据集。

应用每个四元数后,我应在动画函数中包括哪些代码以重新渲染多维数据集?或者,是否可以使用requestAnimationFrame执行相同的任务?

1 个答案:

答案 0 :(得分:1)

第一件事是,您需要在renderer.render(scene,camera);函数内使用rotate,因为在更改立方体的方向后,您需要重新渲染场景。

第二件事是,您以错误的方式使用了setTimeout函数。您想在每16.7、33.4、50.1 ...毫秒后调用一次rotate函数。因此,您必须通过这种方式打发时间。另外,您必须传递一个回调函数,而不是直接调用该函数。试试下面的代码-

let time = 0;
 for(let i=0; i<quat_data.length; i++) {
     time += 16.7;
     setTimeout(function() { 
         rotate(quat_data[i])
     }, time);
 }

最后一件事是,尝试避免使用setTimeout进行动画处理,而应使用window.requestAnimationFrame。浏览器将在下次重画之前调用此函数,您可以在此函数中更改立方体方向并渲染场景。这是示例代码-

let i= 0;
var animate = function () {
    requestAnimationFrame( animate );

    i++;
    if (i >= quat_data.length)
        i = quat_data.length - 1;

    let quat = quat_data[i];
    cube.applyQuaternion(quat);

    renderer.render( scene, camera );
};

animate();