3

現在、2 つの球体と (0,0,0) のポイント ライトを含むシーンがあります。球体はコントロールを使用してポイントを中心に回転しますが、球体をドラッグしようとしても球体を動かすことができません。誰かが私のコードを簡単に見てもらえますか、ありがとう!

編集: はい、移動しますが、この例のように、THREE.Controls から独立してドラッグできるようにする必要があります: http://mrdoob.github.com/three.js/examples/webgl_interactive_draggablecubes.html

球体が選択されている場合、THREE.Controls() を防止し、シーンを「回転」せずにその球体を好きな場所にドラッグする必要があります。

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

ブレント

4

1 に答える 1

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

また、メインのアニメーション ループでは、次の条件により、クリックして指定したオブジェクトと衝突しない場合にのみコントロールが更新されます。

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

編集:今日、この回答が賛成票を投じられたときにこれを見て、上記の最後のコードブロックを見て、これはより明確だと思うので、コードでこれに変更しました。もちろん、以下と上記の両方が同等です:

if (killControls) 
    controls.enabled = false;
else 
    controls.update(delta);
于 2012-06-22T18:46:58.210 に答える