jjzjj

javascript - Three.js 拖动控件固定与相机的距离

coder 2024-07-25 原文

我正在使用 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);
}

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

最佳答案

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

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

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

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

然后您需要注释掉将平面移动到相机 View 的线(大约在中途向下):

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

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

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

然后在您的脚本中使用新函数。其余的 DragControls 已经完成了剩下的工作,但您可能需要对其进行更多修改才能使用球体。这对我有用,至少对平面有用。也许先生。 doob 可以很快将其添加为实际功能,眨眼 眨眼。如果你让它在球体上工作,请告诉我!我不希望对此投票,因为它不是完整的答案,但希望它能帮助那里的人!

关于javascript - Three.js 拖动控件固定与相机的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41706568/

有关javascript - Three.js 拖动控件固定与相机的距离的更多相关文章

  1. Ruby 元类 : why three when defined singleton methods? - 2

    让我们计算MRI范围内的类别:defcount_classesObjectSpace.count_objects[:T_CLASS]endk=count_classes用类方法定义类:classAdefself.foonilendend然后运行:putscount_classes-k#=>3请解释一下,为什么是三个? 最佳答案 查看MRI代码,每次你创建一个Class时,在Ruby中它是Class类型的对象,ruby会自动为这个新类创建“元类”类,这是另一个单例类型的Class对象。C函数调用(class.c)是:rb_define

  2. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  3. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

  4. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  5. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  6. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  7. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  8. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  9. 最新版人脸识别小程序 图片识别 生成二维码签到 地图上选点进行位置签到 计算签到距离 课程会议活动打卡日常考勤 上课签到打卡考勤口令签到 - 2

    技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进

  10. ruby - 如何在 Ruby 中返回整数的固定长度二进制表示? - 2

    我知道我可以使用Fixnum#to_s将整数表示为二进制格式的字符串。但是1.to_s(2)生成1而我希望它生成00000001。我怎样才能使所有返回的字符串都以零作为填充到8个字符?我可以使用类似的东西:binary="#{'0'*(8-(1.to_s(2)).size)}#{1.to_s(2)}"if(1.to_s(2)).size但这看起来不是很优雅。 最佳答案 使用字符串格式。"%08b"%1#=>"00000001" 关于ruby-如何在Ruby中返回整数的固定长度二进制表示?

随机推荐