使用控件拖动和单击对象

时间:2012-06-22 17:59:12

标签: javascript webgl three.js

现在我有一个场景,有两个球体和一个点光源(0,0,0)。球体使用控件围绕点旋转,但是当我尝试拖动球体时,我无法移动球体。有人可以快速查看我的代码,谢谢!

编辑:是的,他们移动,但我需要它们可以独立于THREE.Controls拖拽,就像这个例子:http://mrdoob.github.com/three.js/examples/webgl_interactive_draggablecubes.html

当一个球体被选中时,我需要阻止THREE.Controls()并将该球体拖动到我想要的任何地方而不“旋转”场景。

http://jsfiddle.net/bmd0031/MhB2u/3/

布伦特

1 个答案:

答案 0 :(得分:14)

您需要做的是根据您的对象是否被选中动态禁用控件。

所以这是我正在使用的控件:

controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;

现在,THREE.JS中的控件对象会创建允许他们更改摄像头视图的鼠标事件。我们想要的是在选择对象时禁用控件,否则允许控件在我们拖动时更改视图。

为了做到这一点,我们可以声明一个充当标志的全局变量

var killControls = false;

当我们点击并投射光线时,这将设置为true,如果光线与我们指定的对象发生碰撞,我们将设置killControls为真。

/** Event fired when the mouse button is pressed down */
function onDocumentMouseDown(event) {
    event.preventDefault();

    /** Calculate mouse position and project vector through camera and mouse3D */
    mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouse3D.z = 0.5;
    projector.unprojectVector(mouse3D, camera);

    var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());

    var intersects = ray.intersectObject(maskMesh);

    if (intersects.length > 0) {
        SELECTED = intersects[0].object;
        var intersects = ray.intersectObject(plane);
        offset.copy(intersects[0].point).subSelf(plane.position);
        killControls = true;
    }
    else if (controls.enabled == false)
        controls.enabled = true;
}

/** This event handler is only fired after the mouse down event and
    before the mouse up event and only when the mouse moves */
function onDocumentMouseMove(event) {
    event.preventDefault();

    /** Calculate mouse position and project through camera and mouse3D */
    mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouse3D.z = 0.5;
    projector.unprojectVector(mouse3D, camera);

    var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());

    if (SELECTED) {
        var intersects = ray.intersectObject(plane);
        SELECTED.position.copy(intersects[0].point.subSelf(offset));
        killControls = true;
        return;
    }

    var intersects = ray.intersectObject(maskMesh);

    if (intersects.length > 0) {
        if (INTERSECTED != intersects[0].object) {
            INTERSECTED = intersects[0].object;
            INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
            plane.position.copy(INTERSECTED.position);
        }
    }
    else {
        INTERSECTED = null;
    }
}

/** Removes event listeners when the mouse button is let go */
function onDocumentMouseUp(event) {
    event.preventDefault();
    if (INTERSECTED) {
        plane.position.copy(INTERSECTED.position);
        SELECTED = null;
        killControls = false;
    }

}

/** Removes event listeners if the mouse runs off the renderer */
function onDocumentMouseOut(event) {
    event.preventDefault();
    if (INTERSECTED) {
        plane.position.copy(INTERSECTED.position);
        SELECTED = null;
    }
}

在我们的主动画循环中,以下条件将导致仅在我们单击并且不与指定对象发生碰撞时更新控件:

if (!killControls)
    controls.update(delta);
else
    controls.enabled = false;
编辑:我今天看到这个问题时,这个答案得到了提升并查看上面的最后一段代码,我认为我认为这更清楚所以我在我的代码中改为这个,当然下面和上面都是当量:

if (killControls) 
    controls.enabled = false;
else 
    controls.update(delta);