【问题标题】:Three.js drag controls fix distance from cameraThree.js 拖动控件修复与相机的距离
【发布时间】:2017-06-02 01:45:05
【问题描述】:

我正在使用Three.DragControls 在场景中拖动对象。随着物体被拖动,它与相机的距离似乎越来越远。

我的问题类似于这个未回答的Drag object locked at certain distance/radius from camera view

有没有一种聪明的方法可以将 _intersection.sub( _offset ) 与场景中心的相机保持一定距离?

我在场景中添加了一个球体

    dragSphere = new THREE.Mesh(new THREE.SphereGeometry(200, 60, 40 ),new THREE.MeshBasicMaterial());
    dragSphere.name = "dragSphere";
    dragSphere.visible = false;
    dragSphere.scale.x = -1;
    scene.add(dragSphere);

这里的某个地方

  function onDocumentMouseMove( event ) {

    event.preventDefault();

    var offset = $("#container").offset();
    var rect = _domElement.getBoundingClientRect();
    _mouse.x = ( ( event.clientX - rect.left - (offset.left/2) ) / ( rect.width - rect.left ) ) * 2 - 1;
    _mouse.y = - ( ( event.clientY - rect.top ) / ( rect.bottom - rect.top) ) * 2 + 1;

    _raycaster.setFromCamera( _mouse, _camera );

    if ( _selected && scope.enabled ) {

        if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {

            if(_right){

                _deltaX = event.x - _startPoint.x;
                _deltaY = event.y - _startPoint.y;

                _selected.rotation.y += (_deltaX/50);
                _selected.rotation.x += (_deltaY/50);

                console.log(_selected.position);

                _startPoint.x = event.x;
                _startPoint.y = event.y;

                _lastMoveTimestamp = new Date();
            }
            else{
                _selected.position.copy( _intersection.sub( _offset ) );
                _selected.lookAt(camera.position);
            }

        }

        scope.dispatchEvent( { type: 'drag', object: _selected } );

        return;

    }

    _raycaster.setFromCamera( _mouse, _camera );

    var intersects = _raycaster.intersectObjects( _objects , true  );

    if ( intersects.length > 0 ) {

        var object = intersects[ 0 ].object;

        if(object.type === "Mesh")
            if(object.parent)
                if(object.parent.type == "Object3D")
                    object = object.parent;

        _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), object.position );

        if ( _hovered !== object ) {

            scope.dispatchEvent( { type: 'hoveron', object: object } );

            _domElement.style.cursor = 'pointer';
            _hovered = object;

        }

    } else {

        if ( _hovered !== null ) {

            scope.dispatchEvent( { type: 'hoveroff', object: _hovered } );

            _domElement.style.cursor = 'auto';
            _hovered = null;

        }

    }

}

function onDocumentMouseDown( event ) {

    event.preventDefault();

    _right = event.which == 3 || event.button == 2;

    _raycaster.setFromCamera( _mouse, _camera );

    var intersects = _raycaster.intersectObjects( _objects , true );

    if ( intersects.length > 0 ) {

        _selected = intersects[ 0 ].object;

       if(_selected.type == "Mesh" && _selected.parent.type == "Object3D")
         _selected = _selected.parent;

        if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {

            if(_right){
                _mouseDown = true;

                _startPoint = {
                    x: event.clientX,
                    y: event.clientY
                };

                _rotateStartPoint = _rotateEndPoint = projectOnTrackball(0, 0);
            }
            else
                _offset.copy( _intersection ).sub( _selected.position );
        }

        _domElement.style.cursor = 'move';

        scope.dispatchEvent( { type: 'dragstart', object: _selected } );

    }
    else
        scope.dispatchEvent( { type: 'nodrag' } );


}

在拖动的部分,即

if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
    _selected.position.copy( _intersection.sub( _offset ) );
    _selected.lookAt(camera.position);
}

我需要让它使用球体交点来应用位置,以便它沿着球体的表面拖动。

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    这可能不是一个完整的答案,但可以让你指出正确的方向,因为我处于类似的情况,我试图让物体沿着飞机拖动。我创建了自己的 DragControls.js 函数的修改版本,以支持将平面作为参数传递(首先将其重命名为 DragControlsPlane.js),如下所示:

    THREE.DragControlsPlane = function (_objects, _camera, _domElement, _plane)
    

    这是原始 DragControls.js 的顶部。然后注释掉初始化_plane var的那一行:

    //var _plane = new THREE.Plane();
    

    然后您需要注释掉将飞机转移到相机视图的线(大约在中途):

    //_plane.setFromNormalAndCoplanarPoint(_camera.getWorldDirection(_plane.normal), object.position);
    

    然后在底部重命名这些以与您的新函数名称对齐:

    THREE.DragControlsPlane.prototype = Object.create(THREE.EventDispatcher.prototype);
    THREE.DragControlsPlane.prototype.constructor = THREE.DragControlsPlane;
    

    然后在您的脚本中使用新功能。 DragControls 的其余部分已经完成了其余部分,但您可能需要对其进行更多修改才能使用球体。这对我有用,至少对于平面而言。也许先生。 doob 很快就会将其添加为实际功能,wink wink。如果你让它适用于一个球体,请告诉我!我不希望对此给予支持,因为它不是完整的答案,但希望它会帮助那里的人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 2014-10-27
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-17
      相关资源
      最近更新 更多