我正在尝试实施2x2x2 Rubiks Cube的实验版本。我已经收到了之前两篇文章中关于子对象附件和分离的问题的说明:Three.js: Proper way to add and remove child objects using THREE.SceneUtils.attach/detach functions和Three.js: Adding and Removing Children of Rotated Objects,并且能够成功地了解如何独立旋转两个面。
然而,当我在代码中实现相同的时候,当连续应用旋转时,我得到奇怪的结果,这表明某些变换在某处出错,尽管我似乎无法理解在哪里。但话说回来,在旋转结束后,与父对象相关的每个矩阵都会重置,所以我真的不明白它为什么会发生。但是,当独立应用时,旋转工作正常,这证实我做了大约50%的事情正确:)。可以在此处查看示例:sample 2x2x2 cube.
以下是相关的代码示例: - >用于旋转右脸的事件处理程序
function rotateR()
{
for(var i = 0; i < cubies.length; i++)
if((pos(cubies[i]).x >= 53) && (pos(cubies[i]).x <= 55))
active.push(cubies[i]);
for(var i = 0; i < active.length; i++)
console.log(active[i]);
//reset pivot rotation
pivot.rotation.set( 0, 0, 0 );
pivot.updateMatrixWorld();
//attach active[i] cubies to the pivot
for (var i = 0; i < 4; i++)
THREE.SceneUtils.attach(active[i], scene, pivot);
console.log("attached!");
attachedR = true;
}
在渲染功能中:
if((pivot.rotation.x <= 1.580000000000001) && (attachedR === true))
{
pivot.rotation.x += 0.02;
console.log(pivot.rotation.x);
if(pivot.rotation.x == 1.580000000000001)
{
attachedR = false;
for(var i = 0; i < active.length; i++)
console.log(pos(active[i]).x + ", " + pos(active[i]).y + ", " + pos(active[i]).z);
//Detach active[i] cubies from the parent pivot
pivot.updateMatrixWorld();
for(var i = 0; i < active.length; i++)
{
active[i].updateWorldMatrix();
THREE.SceneUtils.detach(active[i], pivot, scene);
}
}
}
上面的事件处理程序和增量动画功能是相同的并且在同一个地方。 pos(cubies [i])函数返回网格对象的世界坐标。面部旋转我哪里错了? 任何帮助将受到高度赞赏。谢谢。
答案 0 :(得分:1)
我认为最大的问题是主动阵列永远不会被清空
此外,当没有真正需要时,您正在进行大量的矩阵更新
我重做了你的javaScript,现在它只是附加立方体,进行旋转,最后分离立方体并重置旋转。
的JavaScript
//Rotate Right face of cube
function rotateR()
{
//Find cubies that lie in the right face of cube and store them in active[i]
for(var i = 0; i < cubies.length; i++) {
var x = pos(cubies[i]).x;
if(x >= 54 && x <= 56)
active.push(cubies[i]);
}
if (active.length != 4) alert ("active num wrong");
//attach active[i] cubies to the pivot
for (var i = 0; i < 4; i++)
THREE.SceneUtils.attach(active[i], scene, pivot);
attachedR = true;
}
//Rotate Upper face of the cube
function rotateU()
{
//Find cubies that lie in the up face of cube and store them in active[i]
for(var i = 0; i < cubies.length; i++) {
var position = pos(cubies[i]);
if(position.y >= 54 && position.y <= 56) {
active.push(cubies[i]);
}
}
if (active.length != 4) alert ("active num wrong");
//attach active[i] cubies to the pivot
for (var i = 0; i < 4; i++)
THREE.SceneUtils.attach(active[i], scene, pivot);
attachedU = true;
}
function detachAndReset()
{
for(var i = 0; i < active.length; i++)
{
THREE.SceneUtils.detach(active[i], pivot, scene);
}
active.length = 0;
attachedR = false;
attachedU = false;
pivot.rotation.x = 0;
pivot.rotation.y = 0;
}
//get world position of cubies[i]
function pos(object)
{
var position = new THREE.Vector3();
position.setFromMatrixPosition( object.matrixWorld );
return position;
}
function render()
{
var endAnimation = false;
//Math.PI / 2 == 1.580000000000001
//Rotate Right face of cube
if(attachedR === true)
{
pivot.rotation.x += 0.02;
if(pivot.rotation.x >= Math.PI / 2.0) {
pivot.rotation.x = Math.PI / 2.0;
endAnimation = true;
}
}
//Math.PI / 2 == 1.580000000000001
//Rotate Upper face of cube
if(attachedU === true)
{
pivot.rotation.y += 0.02;
if(pivot.rotation.y >= Math.PI / 2.0) {
pivot.rotation.y = Math.PI / 2.0;
endAnimation = true;
}
}
renderer.render(scene, camera);
if (endAnimation) {
detachAndReset();
}
}