2013-08-24 3 views
0

Я пытаюсь создать кубик из 5 кубоидов один из другого, который вращается на 180 градусов по часовой стрелке каждые две секунды.логика анимации 3d.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

Согласен, глядя на позицию, вероятно, не лучший способ это сделать. Если вы заинтересованы в угле, то угол должен быть вашим фокусом. В принципе, вы хотите, чтобы ваш тест основывался на спине и максимальном вращении - когда вы больше этого, остановитесь и отрегулируйте по мере необходимости (в данном случае это иногда было> 1 с количеством angleChange, поэтому я просто сбросил это к 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(); 
    }); 
} 
Смежные вопросы