Three.JS轨道控制 - 无需位置跳跃即可启用和禁用 [英] Three.JS Orbit Controls - enabling and disabling without position jumping

查看:115
本文介绍了Three.JS轨道控制 - 无需位置跳跃即可启用和禁用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Three.JS创建几何操作原型。我正在使用OrbitControls.JS来操作相机并且无法启用和禁用控件。

I am creating a geometry manipulation prototype with Three.JS. I am using OrbitControls.JS to manipulate the camera and am having trouble enabling and disabling the controls.

这是我的演示:
http://moczys.com/webGL/Prototype_V02-05.html

我们的想法是,当您将鼠标悬停在四面体的顶点上时,会出现一个灰色球体。通过单击球体,可以调出顶点操作手柄。然后通过单击箭头上的拖动,可以在该方向上移动顶点。然后,您应该可以单击几何体以退出此模式。

The idea is that when you hover over a vertex of the Tetrahedron, a grey sphere appears. By clicking on the sphere, you bring up a vertex manipulation handle. Then by clicking an dragging on an arrow, you can move the vertex in that direction. You should then be able to click away from the geometry to get out of this mode.

单击此处时会出现问题。如果你点击&移动顶点后拖动,相机有点疯狂。根据您与原始点的距离,OrbitControls会将相机旋转一段距离。这只是一个非常刺耳/混乱的行为,真正影响可用性,所以我想解决它,但似乎无法找到问题。

The problem occurs when you click away. If you click & drag after moving the vertex, the camera goes a little crazy. Depending on how far away from the original point you are, the OrbitControls will spin the camera a distance in that direction. This is just a really jarring/confusing action that really impacts the usability, so I'd like to fix it, but can't seem to locate the problem.

I认为它正在记录OrbitControls.js中的初始位置,然后保持它直到它们被重新启用...但是我无法弄清楚在哪里。这发生在MouseUp,MouseDown和MouseMove事件处理程序中的某处。我希望对于那些可能比我更了解OrbitControls操作的人来说,这可能会很有趣。

I think that it is recording the initial position in the OrbitControls.js, and then keeping that until they are re-enabled... however I haven't been able to figure out where. This occurs somewhere in the MouseUp, MouseDown, and MouseMove event handlers. I was hoping this might be interesting to someone who might know more about the operation of OrbitControls than I do.

这是我的点击/拖动事件处理程序代码:

And here is my clicking/dragging event handler code:

    function onDocumentMouseMove( event ) 
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
//event.preventDefault();

// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

if(MOUSEDOWN&&editMode==2)
{
    var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
    projector.unprojectVector( vector, camera );

    var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
    //lastPoint = vertexIntersects[0].object;
    var instance = vertexTargets.indexOf(lastPoint);
    if(vertexEdit==1){
        var intersects = raycaster.intersectObject(XYplane);

        vertexTargets[instance].position.x=intersects[0].point.x;
        targetList[0].geometry.vertices[instance].x=intersects[0].point.x;
        //console.log("x = "+intersects[0].point.x);
    }
    else if(vertexEdit==2){
        var intersects = raycaster.intersectObject(XYplane);
        vertexTargets[instance].position.y=intersects[0].point.y;
        targetList[0].geometry.vertices[instance].y=intersects[0].point.y;
        //console.log("y = "+intersects[0].point.y);
    }
    else if(vertexEdit==3){
        var intersects = raycaster.intersectObject(YZplane);
        vertexTargets[instance].position.z=intersects[0].point.z;
        targetList[0].geometry.vertices[instance].z=intersects[0].point.z;
        //console.log("z = "+intersects[0].point.z);
    }
    setAxisPosition(vertexTargets[instance].position.clone());
    var geom = targetList[0].geometry;
    geom.computeCentroids();
    geom.computeFaceNormals();
    geom.computeVertexNormals();
    geom.verticesNeedUpdate = true;
    geom.normalsNeedUpdate = true;
    updatePanels(targetList[0]);

    }
}


function onDocumentMouseDown( event ) 
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();

//console.log("Click.");
MOUSEDOWN = true;
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

checkSelection();   
if(editMode==2){
    controls.enabled = false;
    controls.rotate = false;
}
else{
    controls.enabled = true;
    controls.rotate = true;
}

}

function onDocumentMouseUp( event ) 
{
//event.preventDefault();
if (editMode!=2){
   controls.enabled = true;
   controls.rotate = true;
}
MOUSEDOWN = false;
if(editMode==2){
    //editMode=1;
    //updateVertexTargets(targetList[0].geometry);
}

}

我很想听到任何人们可能有的建议,谢谢!

I'd love to hear any suggestions that people might have, thanks!

推荐答案

更新2019年第一季度

noRotate 现已弃用,请改用 enableRotate

我想通了!仔细观察OrbitControls.JS后,可以设置一个noRotate标志,该标志返回旋转功能,完全消除了我上面讨论的启动向量的创建。

I figured it out! After looking closer at OrbitControls.JS, there is a "noRotate" flag that can be set that returns out of the rotate function, completely eliminating the creation of a start vector like I was talking about above.

以下是工作演示:
http://moczys.com/webGL/Prototype_V02-05-2.html

以下是更改评论的代码:

And here is the code with changes commented:

function onDocumentMouseMove( event ) 
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
//event.preventDefault();

// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;


if(MOUSEDOWN&&editMode==2)
{
// Added to stop rotation while moving a vertex with the arrow handles
    controls.noRotate = true;

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
    projector.unprojectVector( vector, camera );

    var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
    //lastPoint = vertexIntersects[0].object;
    var instance = vertexTargets.indexOf(lastPoint);
    if(vertexEdit==1){
        var intersects = raycaster.intersectObject(XYplane);

        vertexTargets[instance].position.x=intersects[0].point.x;
        targetList[0].geometry.vertices[instance].x=intersects[0].point.x;
        //console.log("x = "+intersects[0].point.x);
    }
    else if(vertexEdit==2){
        var intersects = raycaster.intersectObject(XYplane);
        vertexTargets[instance].position.y=intersects[0].point.y;
        targetList[0].geometry.vertices[instance].y=intersects[0].point.y;
        //console.log("y = "+intersects[0].point.y);
    }
    else if(vertexEdit==3){
        var intersects = raycaster.intersectObject(YZplane);
        vertexTargets[instance].position.z=intersects[0].point.z;
        targetList[0].geometry.vertices[instance].z=intersects[0].point.z;
        //console.log("z = "+intersects[0].point.z);
    }
    setAxisPosition(vertexTargets[instance].position.clone());
    var geom = targetList[0].geometry;
    geom.computeCentroids();
    geom.computeFaceNormals();
    geom.computeVertexNormals();
    geom.verticesNeedUpdate = true;
    geom.normalsNeedUpdate = true;
    updatePanels(targetList[0]);

}
}


function onDocumentMouseDown( event ) 
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();

//console.log("Click.");
MOUSEDOWN = true;
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

checkSelection();   
if(editMode==2){
    //controls.enabled = false;
    //controls.rotate = false;

// Added here to disable rotation when the arrow handles are active
    controls.noRotate = true;
}
else{
    //controls.enabled = true;
    //controls.rotate = true;

// Added here to enable rotation all other times
    controls.noRotate = false;
}

}

function onDocumentMouseUp( event ) 
{
//event.preventDefault();
if (editMode!=2){
    //controls.enabled = true;
    //controls.rotate = true;
}
MOUSEDOWN = false;

// add here to enable rotation whenever the mouse button is lifted
controls.noRotate = false;

}

希望有人觉得这很有用!

Hope somebody finds this useful!

这篇关于Three.JS轨道控制 - 无需位置跳跃即可启用和禁用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆