2014-05-11 43 views
5

我正在用Three.JS创建一个几何操作原型。我使用OrbitControls.JS来操作相机,并且无法启用和禁用控件。Three.JS轨道控制 - 无位置跳跃启用和禁用

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

的想法是,当你将鼠标悬停在四面体的顶点,将出现一个灰色球体。通过点击球体,您可以调出一个顶点操作手柄。然后通过单击拖动箭头,可以沿该方向移动顶点。然后,您应该能够从几何体中单击以离开此模式。

当您单击时发生问题。如果在移动顶点后点击&拖动,相机会有点疯狂。根据距离原点的距离,OrbitControls会在相同的方向上旋转相机一段距离。这只是一个真正震动/混淆的行为,它会影响可用性,所以我想解决它,但似乎无法找到问题所在。

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

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

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); 
} 

} 

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

回答

8

我想通了!在仔细观察OrbitControls.JS之后,可以设置一个“noRotate”标志,该标志可以从循环函数中返回,完全消除了像我上面提到的那样创建一个开始向量。

这里的工作演示: http://moczys.com/webGL/Prototype_V02-05-2.html

这里是有改动的代码注释:

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; 

} 

希望有人认为这有用!

+0

非常有用!把我以为会成为令人头疼的事情给我留下了深刻的印象。谢谢! – AndroidNoobie

+0

谢谢,这很有用。我注意到轨道控制的变焦继续工作。 – steveOw

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; 
     controls.onMouseDown (event); // added this line to set the correct state 
    } 
} 
+0

嗯...这似乎没有做任何事情。它看起来不像你可以从函数外调用它,因为它会抛出一个错误,并说它的未定义。 – moczys