2017-11-17 3 views
0

Ich verwende THREE.OrbitControls in meinem experimentellen Projekt und habe etwas sehr ähnlich zu this Beispiel.Warum funktioniert OrbitControls nicht wie erwartet? (Three.js)

Ich habe verschiedene Radio-Tasten an der Spitze und ich möchte nur aktivieren, wenn der rotate Radio-Button aktiv ist.

Ich habe den Code innerhalb der if Anweisung bilden den Code Pen Beispiel ersetzt:

function doMouseMove(x,y,evt,prevX,prevY) { 
    if (mouseAction == ROTATE) { 
     var dx = x - prevX; 
     world.rotateY(dx/200); 
     render(); 
     } 

mit:

function doMouseMove(x,y,evt,prevX,prevY) { 
    if (mouseAction == ROTATE) { 

    controls = new THREE.OrbitControls(camera, canvas); 
    controls.rotateSpeed = 0.1; 
    controls.zoomSpeed = 1; 
    controls.update(); 

}

Dies funktioniert perfekt, aber wenn ich wieder aus die rotate Taste auf die drag Taste (oder eine andere Taste), die OrbitControls ist immer noch aktiv, und die ca mera bewegt sich mit dem Objekt, das gezogen/hinzugefügt/entfernt wird.

Dies war nicht der Fall mit dem ursprünglichen Beispiel (wie man sehen kann) und so fragte ich mich, ob ich weitere Funktionen hinzufügen muss, um die OrbitControls zu deaktivieren.

Ich habe versucht:

controls.reset(); 

Allerdings ist die orbitControls noch aktiv, auch nach dem Drehen Radioknopf gedrückt wird, nicht!

Ich möchte hinzufügen, dass die orbitControls (wie erwartet) nicht aktiv ist, wenn die Seite auf die Zieh-Schaltfläche (oder eine andere Schaltfläche) neu geladen wird. Sobald jedoch der Drehknopf gedrückt wurde, bleibt er während der gesamten Sitzung aktiv, unabhängig davon, welcher Eingang gedrückt wurde.

Gibt es irgendwelche Hinweise, wie ich diese Funktionalität lösen kann?

Im Folgenden ist der vollständige Code Umriss aus dem Beispiel (ohne HTML-Datei mit Referenzen) des Codes:

var canvas, scene, renderer, camera, controls; 

var raycaster; // A THREE.Raycaster for user mouse input. 

var ground; // A square base on which the cylinders stand. 
var cylinder; // A cylinder that will be cloned to make the visible 
cylinders. 

var world; 
var ROTATE = 1, 
DRAG = 2, 
ADD = 3, 
DELETE = 4; // Possible mouse actions 
var mouseAction; // currently selected mouse action 
var dragItem; // the cylinder that is being dragged, during a drag operation 
var intersects; //the objects intersected 

var targetForDragging; // An invisible object that is used as the target for 
raycasting while 

// call functions to initialise trackballcontrols 
init(); 
// animate(); 

function init() { 

canvas = document.getElementById("maincanvas"); 
renderer = new THREE.WebGLRenderer({ 
    canvas: canvas, 
    antialias: true 
}); 

document.getElementById("mouseDrag").checked = true; 
mouseAction = DRAG; 
document.getElementById("mouseRotate").onchange = doChangeMouseAction; 
document.getElementById("mouseDrag").onchange = doChangeMouseAction; 
document.getElementById("mouseAdd").onchange = doChangeMouseAction; 
document.getElementById("mouseDelete").onchange = doChangeMouseAction; 
createWorld(); 

setUpMouseHander(canvas, doMouseDown, doMouseMove); 
setUpTouchHander(canvas, doMouseDown, doMouseMove); 
raycaster = new THREE.Raycaster(); 
render(); 
} 

// loop that causes the renderer to draw the scene 60 times per second. 
function render() { 
renderer.render(scene, camera); 
} 

function createWorld() { 

renderer.setClearColor(0x222222); 
// First parameter is FOV in degrees. Second: Aspect ratio. Third/Fourth: 
Near/Far clipping plane 
camera = new THREE.PerspectiveCamera(37, canvas.width/canvas.height, 1, 
10000); 
camera.position.z = 5; 
camera.position.y = 60; 

/**Creating the scene */ 
scene = new THREE.Scene(); 


camera.lookAt(new THREE.Vector3(0, 1, 0)); 
camera.add(new THREE.PointLight(0xffffff, 0.7)); // point light at camera 
position 
scene.add(camera); 
scene.add(new THREE.DirectionalLight(0xffffff, 0.5)); // light shining from 
above. 

world = new THREE.Object3D(); 

ground = new THREE.Mesh(
    new THREE.BoxGeometry(40, 1, 40), 
    new THREE.MeshLambertMaterial({ color: "gray" }) 
); 
ground.position.y = -0.5; // top of base lies in the plane y = -5; 
world.add(ground); 



targetForDragging = new THREE.Mesh(
    new THREE.BoxGeometry(1000, 0.01, 1000), 
    new THREE.MeshBasicMaterial() 
); 
targetForDragging.material.visible = false; 


cylinder = new THREE.Mesh(
    new THREE.CylinderGeometry(1, 2, 6, 16, 32), 
    new THREE.MeshLambertMaterial({ color: "yellow" }) 
); 
cylinder.position.y = 3; // places base at y = 0; 

addCylinder(10, 10); 
addCylinder(0, 15); 
addCylinder(-15, -7); 
addCylinder(-8, 5); 
addCylinder(5, -12); 

} 

function addCylinder(x, z) { 
var obj = cylinder.clone(); 
obj.position.x = x; 
obj.position.z = z; 
world.add(obj); 
} 

function doMouseDown(x, y) { 
//enable rotate 
if (mouseAction == ROTATE) { 
    return true; 
} 
if (mouseAction != ROTATE) { 
    controls = 0; 
    controls.enabled = false; 
} 

// Affecting drag function 
if (targetForDragging.parent == world) { 
    world.remove(targetForDragging); // I don't want to check for hits on 
targetForDragging 

} 

var a = 2 * x/canvas.width - 1; 
var b = 1 - 2 * y/canvas.height; 
raycaster.setFromCamera(new THREE.Vector2(a, b), camera); 
intersects = raycaster.intersectObjects(world.children); // no need for 
recusion since all objects are top-level 

if (intersects.length == 0) { 
    return false; 
} 

var item = intersects[0]; 
var objectHit = item.object; 

switch (mouseAction) { 
    case DRAG: 
     if (objectHit == ground) { 
      return false; 
     } else { 
      dragItem = objectHit; 
      world.add(targetForDragging); 
      targetForDragging.position.set(0, item.point.y, 0); 
      render(); 
      return true; 
     } 
    case ADD: 
     if (objectHit == ground) { 

      var locationX = item.point.x; // Gives the point of intersection 
in world coords 
      var locationZ = item.point.z; 
      var coords = new THREE.Vector3(locationX, 0, locationZ); 
      world.worldToLocal(coords); // to add cylider in correct 
    position, neew local coords for the world object 
      addCylinder(coords.x, coords.z); 
      render(); 
     } 
     return false; 
    default: // DELETE 
     if (objectHit != ground) { 
      world.remove(objectHit); 
      render(); 
     } 
     return false; 
    } 
} 

//this function is used when dragging OR rotating 
function doMouseMove(x, y, evt, prevX, prevY) { 

if (mouseAction == ROTATE) { 
    controls = new THREE.OrbitControls(camera, canvas); 
    controls.rotateSpeed = 0.1; 
    controls.zoomSpeed = 1; 
    controls.addEventListener('change', render, renderer.domElement); 
    controls.update(); 

} else { // drag 

    var a = 2 * x/canvas.width - 1; 
    var b = 1 - 2 * y/canvas.height; 
    raycaster.setFromCamera(new THREE.Vector2(a, b), camera); 
    intersects = raycaster.intersectObject(targetForDragging); 
    if (intersects.length == 0) { 
     return; 
    } 
    var locationX = intersects[0].point.x; 
    var locationZ = intersects[0].point.z; 
    var coords = new THREE.Vector3(locationX, 0, locationZ); 
    world.worldToLocal(coords); 
    a = Math.min(19, Math.max(-19, coords.x)); // clamp coords to the range 
    -19 to 19, so object stays on ground 
    b = Math.min(19, Math.max(-19, coords.z)); 
    dragItem.position.set(a, 3, b); 
    render(); 
} 
} 

    function doChangeMouseAction() { 
    if (document.getElementById("mouseRotate").checked) { 
     mouseAction = ROTATE; 
    } else if (document.getElementById("mouseDrag").checked) { 
     mouseAction = DRAG; 
    } else if (document.getElementById("mouseAdd").checked) { 
     mouseAction = ADD; 
    } else { 
     mouseAction = DELETE; 
    } 
} 
window.requestAnimationFrame = 
window.requestAnimationFrame || 
window.mozRequestAnimationFrame || 
window.webkitRequestAnimationFrame || 
window.msRequestAnimationFrame || 
window.oRequestAnimationFrame || 
function(callback) { 
    setTimeout(function() { 
     callback(Date.now()); 
    }, 1000/60); 
}; 

function setUpMouseHander(element, mouseDownFunc, mouseDragFunc, 
mouseUpFunc) { 

if (!element || !mouseDownFunc || !(typeof mouseDownFunc == "function")) { 
    throw "Illegal arguments in setUpMouseHander"; 
} 
if (typeof element == "string") { 
    element = document.getElementById(element); 
} 
if (!element || !element.addEventListener) { 
    throw "first argument in setUpMouseHander is not a valid element"; 
} 
var dragging = false; 
var startX, startY; 
var prevX, prevY; 

function doMouseDown(evt) { 
    if (dragging) { 
     return; 
    } 
    var r = element.getBoundingClientRect(); 
    var x = evt.clientX - r.left; 
    var y = evt.clientY - r.top; 
    prevX = startX = x; 
    prevY = startY = y; 
    dragging = mouseDownFunc(x, y, evt); 
    if (dragging) { 
     document.addEventListener("mousemove", doMouseMove); 
     document.addEventListener("mouseup", doMouseUp); 
    } 
} 

function doMouseMove(evt) { 
    if (dragging) { 
     if (mouseDragFunc) { 
      var r = element.getBoundingClientRect(); 
      var x = evt.clientX - r.left; 
      var y = evt.clientY - r.top; 
      mouseDragFunc(x, y, evt, prevX, prevY, startX, startY); 
     } 
     prevX = x; 
     prevY = y; 
    } 
} 

function doMouseUp(evt) { 
    if (dragging) { 
     document.removeEventListener("mousemove", doMouseMove); 
     document.removeEventListener("mouseup", doMouseUp); 
     if (mouseUpFunc) { 
      var r = element.getBoundingClientRect(); 
      var x = evt.clientX - r.left; 
      var y = evt.clientY - r.top; 
      mouseUpFunc(x, y, evt, prevX, prevY, startX, startY); 
     } 
     dragging = false; 
    } 
} 
element.addEventListener("mousedown", doMouseDown); 
} 

function setUpTouchHander(element, touchStartFunc, touchMoveFunc, t 
touchEndFunc, touchCancelFunc) { 

if (!element || !touchStartFunc || !(typeof touchStartFunc == "function")) { 
    throw "Illegal arguments in setUpTouchHander"; 
} 
if (typeof element == "string") { 
    element = document.getElementById(element); 
} 
if (!element || !element.addEventListener) { 
    throw "first argument in setUpTouchHander is not a valid element"; 
} 
var dragging = false; 
var startX, startY; 
var prevX, prevY; 

function doTouchStart(evt) { 
    if (evt.touches.length != 1) { 
     doTouchEnd(evt); 
     return; 
    } 
    evt.preventDefault(); 
    if (dragging) { 
     doTouchEnd(); 
    } 
    var r = element.getBoundingClientRect(); 
    var x = evt.touches[0].clientX - r.left; 
    var y = evt.touches[0].clientY - r.top; 
    prevX = startX = x; 
    prevY = startY = y; 
    dragging = touchStartFunc(x, y, evt); 
    if (dragging) { 
     element.addEventListener("touchmove", doTouchMove); 
     element.addEventListener("touchend", doTouchEnd); 
     element.addEventListener("touchcancel", doTouchCancel); 
    } 
} 

function doTouchMove(evt) { 
    if (dragging) { 
     if (evt.touches.length != 1) { 
      doTouchEnd(evt); 
      return; 
     } 
     evt.preventDefault(); 
     if (touchMoveFunc) { 
      var r = element.getBoundingClientRect(); 
      var x = evt.touches[0].clientX - r.left; 
      var y = evt.touches[0].clientY - r.top; 
      touchMoveFunc(x, y, evt, prevX, prevY, startX, startY); 
     } 
     prevX = x; 
     prevY = y; 
    } 
} 

function doTouchCancel() { 
    if (touchCancelFunc) { 
     touchCancelFunc(); 
    } 
} 

function doTouchEnd(evt) { 
    if (dragging) { 
     dragging = false; 
     element.removeEventListener("touchmove", doTouchMove); 
     element.removeEventListener("touchend", doTouchEnd); 
     element.removeEventListener("touchcancel", doTouchCancel); 
     if (touchEndFunc) { 
      touchEndFunc(evt, prevX, prevY, startX, startY); 
     } 
    } 
} 
element.addEventListener("touchstart", doTouchStart); 
} 

Antwort

1

Sie können Steuerelemente einmal instanziiert:

controls = new THREE.OrbitControls(camera, canvas); 
controls.enableZoom = false; 
controls.enablePan = false; 
controls.enableRotate = false; 

und wechseln Sie dann nur controls.enableRotate zwischen true und false. Zum Beispiel in der doChangeMouseAction() Funktion. Kreativität liegt bei dir.

Verwandte Themen