2014-05-11 8 views
5

Tworzę prototyp manipulacji geometrią z Three.JS. Używam OrbitControls.JS do manipulowania kamerą i mam problemy z włączaniem i wyłączaniem kontrolek.Three.JS Orbit Controls - włączanie i wyłączanie bez przeskoku pozycji

Oto moje demo: http://moczys.com/webGL/Prototype_V02-05.html

Chodzi o to, że po najechaniu na wierzchołku czworościanu, pojawia się szara sfera. Kliknięcie kuli powoduje wyświetlenie uchwytu manipulatora wierzchołków. Następnie klikając przeciągnięcie strzałki, możesz przesunąć wierzchołek w tym kierunku. Następnie powinieneś móc kliknąć z dala od geometrii, aby wyjść z tego trybu.

Problem występuje po kliknięciu. Jeśli klikniesz & przeciągając po przesunięciu wierzchołka, kamera trochę zwariuje. W zależności od tego, jak daleko od pierwotnego punktu jesteś, OrbitControls obróci kamerę na pewną odległość w tym kierunku. Jest to po prostu naprawdę wstrząsające/dezorientujące działanie, które naprawdę wpływa na użyteczność, więc chciałbym to naprawić, ale nie mogę zlokalizować problemu.

Myślę, że rejestruje on początkową pozycję w OrbitControls.js, a następnie zachowuje ją, dopóki nie zostaną ponownie włączone ... jednak nie byłem w stanie ustalić, gdzie. Dzieje się to gdzieś w programach obsługi zdarzeń MouseUp, MouseDown i MouseMove. Miałem nadzieję, że może to być interesujące dla kogoś, kto może wiedzieć więcej o działaniu OrbitControls niż ja.

I tu jest moje kliknięcie/przeciągnięcie kod obsługi zdarzenia:

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

} 

Chciałbym usłyszeć jakieś sugestie, że ludzie mogą mieć, dzięki!

Odpowiedz

8

I zorientowaliśmy się! Po przyjrzeniu się narzędziu OrbitControls.JS istnieje flaga "noRotate", która może zostać ustawiona, która powraca z funkcji obracania, całkowicie eliminując tworzenie wektora startowego, o którym mówiłem powyżej.

Oto demo robocze: http://moczys.com/webGL/Prototype_V02-05-2.html

A oto kod ze zmianami komentuje:

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; 

} 

nadzieję, że ktoś znajdzie to przydatne!

+0

Bardzo przydatne! Uratowałeś to, co myślałem, że będzie dużym bólem głowy. Dziękuję Ci! – AndroidNoobie

+0

Dzięki, to jest przydatne. Zauważyłem, że powiększanie kontroli orbitalnej nadal działa. – steveOw

0

I nie były w stanie go przetestować, ale myślę, że kod powinien być

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

hmm ... to chyba nic nie dało. nie wygląda na to, że możesz wywołać to z zewnątrz funkcji, ponieważ powoduje błąd i stwierdza, że ​​jest niezdefiniowana. – moczys

Powiązane problemy