2013-08-24 35 views
0

我正在試圖從5個立方體之一創建一個長方體,其中一個頂部 - 每旋轉180度旋轉180度。three.js旋轉立方體的動畫邏輯

這是有點工作,但我沒有得到平滑的結果......我認爲一個好的策略是,在旋轉期間 - 單個臉部的左上角和右上角的z位置將進行比較 - 如果它們相同,那麼該停止旋轉週期了。

問題是,頂點之間的差異永遠不會是零..它非常接近零...所以我檢查它是否在0.1的邊距,因此我有一個旋轉開始的問題是卡住,因爲有時它小於0.1。有時,當他們應該停止時,旋轉繼續,因爲差值不小於0.1。

var spinningPeriod = false, counter = 0, lastTime = 0; 
function animate(){ 
    counter++; 
    var time = (new Date()).getTime(); 
    var timeDiff = time - lastTime; 
    var angleChange = 0.2 * timeDiff * 2 * Math.PI/1000; 

    if (counter%200==0 && counter > 0) { 
     spinningPeriod = true; 
    } 
    if (spinningPeriod) { 
     var v1 = cubes[0].geometry.vertices[0].clone(); 
     var v2 = cubes[0].geometry.vertices[3].clone(); 
     cubes[0].updateMatrixWorld(); 
     cubes[0].localToWorld(v1); 
     cubes[0].localToWorld(v2); 

     if (Math.abs(v1.x - v2.x) < 0.1) { 
      spinningPeriod = false; 
     } 

     for (var ii =0; ii<5; ++ii) { 
     cubes[ii].rotation.y += angleChange; 
     } 
    } 
    lastTime = time; 
    renderer.render(scene, camera); 

    // request new frame 
    requestAnimationFrame(function(){ 
     animate(); 
    }); 
    } 

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

    // camera 
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000); 
    camera.position.z = 500; 

    // scene 
    var scene = new THREE.Scene(); 


    // cube 
    var cubes = new Array(); 
    var currentHeight = -150; 
    for (var ii =0; ii<5; ++ii) { 
    cubes[ii] = new THREE.Mesh(new THREE.CubeGeometry(400, 50, 20)); 
    currentHeight += 50; 
    cubes[ii].position.y = currentHeight; 
    cubes[ii].overdraw = true; 
    scene.add(cubes[ii]); 
    } 

    // start animation 
    animate(); 

回答

0

我同意,看着位置可能不是最好的辦法。如果你關注角度,那麼角度應該是你關注的焦點。基本上你想讓你的測試基於自旋與最大旋轉 - 當你超過這個範圍時,根據需要停止和調整(在這種情況下,angleChange量有時大於1,所以我剛剛重置它到1)。

而不是你上面的動畫功能,試試這個 - 它看起來像它對我來說非常可靠。

var spinningPeriod = false, counter = 0, lastTime = 0; 
var spinAngle = 0, spinMax = 1 * Math.PI; 
function animate(){ 
    counter++; 
    var time = (new Date()).getTime(), 
     timeDiff = time - lastTime, 
     speed = 0.2 * 2 * Math.PI/1000, 
     angleChange = speed * timeDiff; 

    if (counter%200==0 && counter > 0) { 
     spinningPeriod = true; 
     spinAngle = 0; 
    } 
    console.log(counter, spinningPeriod, cubes[0].rotation.y/Math.PI); 
    if (spinningPeriod) { 
     spinAngle += angleChange; 
     if (spinAngle > spinMax) { 
      spinningPeriod = false; 
      spinAngle = spinMax; 
     } 
     for (var ii =0; ii<5; ++ii) { 
      cubes[ii].rotation.y = spinAngle; 
     } 
    } 
    lastTime = time; 
    renderer.render(scene, camera); 

    // request new frame 
    requestAnimationFrame(function(){ 
     animate(); 
    }); 
}