使用控件拖动和单击对象 [英] Dragging and Clicking Objects with Controls

查看:93
本文介绍了使用控件拖动和单击对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Right now I have a scene with two spheres and a point light at (0,0,0). The spheres rotate around the point using Controls, but I can't get the spheres to move when I attempt to drag them. Can someone give my code a quick look, thanks!

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

Yes they move, but I need them to be draggable independently from the THREE.Controls, just like this example: http://mrdoob.github.com/three.js/examples/webgl_interactive_draggablecubes.html

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

When a sphere is SELECTED, i need to prevent THREE.Controls() and drag that sphere wherever I want without 'rotating' the scene.

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

布伦特

推荐答案

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

What you need to do is disable the controls dynamically based on whether your object is selected.

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

So here are the controls I am using:

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中的控件对象会创建允许他们更改摄像头视图的鼠标事件。我们想要的是在我们选择一个对象时禁用控件,否则允许控件在我们拖动时更改视图。

Now the controls objects in THREE.JS create mouse events that allow them to change the camera view. What we want is to disable the controls when we have an object selected, otherwise allow the controls to change the view when we drag.

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

In order to do this we can declare a global variable that will act as a flag

var killControls = false;

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

This will be set to true when we click and cast a ray, if the ray collides with our specified object we will set killControls true.

/** 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;
    }
}

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

And in our main animation loop, the following conditional will cause the controls to only be updated when we click and do not collide with our specified object:

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

编辑:我今天看到这个答案,当这个答案得到投票并观察最后一块上面的代码我决定我认为这更清楚,所以我在我的代码中改为这个,当然下面和上面都是等价的:

I got to looking at this today when this answer got upvoted and looking at this last block of code above I decided I think this is clearer so I changed to this in my code, of course both the below and above are equivalent:

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

这篇关于使用控件拖动和单击对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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