单击并拖动仅抓取对象的一部分

发布于 2024-12-19 23:04:09 字数 2547 浏览 1 评论 0原文

我正在进行这个项目的最后阶段,但我在单击和拖动对象的能力方面遇到了问题。我已将它们全部添加到一个名为 items 的数组中,现在它可以正常工作了。 此处是指向正在运行的页面的链接。如果您从右上角的菜单中添加任何项目,它将显示出来,但您只能将其逐个拖动。据我所知,问题在于它将每个项目视为一系列项目而不是一个项目。这是有道理的,因为每个模型都是几个模型拼凑在一起的,但我不确定如何解决这个问题。有什么想法吗?

以下是我控制鼠标交互的三个函数:

function onMouseMove( event ){
    event.preventDefault();

    mouse.x = ( event.clientX / width ) * 2 - 1;
    mouse.y = - ( event.clientY / height ) * 2 + 1;

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

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

    if ( SELECTED ) {

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

    }

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            if ( INTERSECTED != intersects[ 0 ] ) {

                    INTERSECTED = intersects[ 0 ].object;

                    plane.position.copy( INTERSECTED.position );
            }

            container.style.cursor = 'pointer';
    }
     else {
                    INTERSECTED = null;
                    container.style.cursor = 'auto';
    }

}

function onMouseDown( event ) {
    event.preventDefault();

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

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

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            SELECTED = intersects[ 0 ].object;

            var intersects = ray.intersectObject( plane );
            offset.copy( intersects[ 0 ].point ).subSelf( plane.position );

            container.style.cursor = 'move';

    }

}

function onMouseUp( event ) {
    event.preventDefault();

    if ( INTERSECTED ) {
            plane.position.copy( INTERSECTED.position );
            SELECTED = null;
    }

    container.style.cursor = 'auto';
}

它很大程度上基于 this 示例,但没有颜色位。

通过更改 onMouseDown 中的代码,

// OLD
SELECTED = intersects[0].object;
// NEW
SELECTED = intersects[0].object.parent;

我现在可以移动整个对象。这只适用于对象只有一个父对象的情况,因此某些项目无法使用此代码移动。有人对确定它是否有父对象以及如果有的话向上移动有什么建议吗?

I'm on the final stretch of a this project I've been working on and I'm having issues with the ability to click and drag objects. I've added them all into an array called items, and it sort of works right now. Here is the link to the page in action. If you add any of the items from the menu in the upper right, it'll show up but you can only drag it around piece by piece. From what I can tell, the issue is that it is treating each item as a series of items instead of as one item. This makes sense as each model is several models pieced together, but I'm not sure how to work around that. Any ideas?

Here are the three functions I have controlling mouse interaction:

function onMouseMove( event ){
    event.preventDefault();

    mouse.x = ( event.clientX / width ) * 2 - 1;
    mouse.y = - ( event.clientY / height ) * 2 + 1;

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

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

    if ( SELECTED ) {

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

    }

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            if ( INTERSECTED != intersects[ 0 ] ) {

                    INTERSECTED = intersects[ 0 ].object;

                    plane.position.copy( INTERSECTED.position );
            }

            container.style.cursor = 'pointer';
    }
     else {
                    INTERSECTED = null;
                    container.style.cursor = 'auto';
    }

}

function onMouseDown( event ) {
    event.preventDefault();

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0 );
    projector.unprojectVector( vector, camera );

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

    var intersects = ray.intersectObjects( items );

    if ( intersects.length > 0 ) {

            SELECTED = intersects[ 0 ].object;

            var intersects = ray.intersectObject( plane );
            offset.copy( intersects[ 0 ].point ).subSelf( plane.position );

            container.style.cursor = 'move';

    }

}

function onMouseUp( event ) {
    event.preventDefault();

    if ( INTERSECTED ) {
            plane.position.copy( INTERSECTED.position );
            SELECTED = null;
    }

    container.style.cursor = 'auto';
}

It's heavily based on this example, but without the color bits.

By changing the code in onMouseDown like so

// OLD
SELECTED = intersects[0].object;
// NEW
SELECTED = intersects[0].object.parent;

I can now move the full object. This only works if the object only has one parent though, and so some items are not able to move with this code. Anyone have a suggestion on determining if it has parent objects and moving up if it does?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

双手揣兜 2024-12-26 23:04:09

如果有人仍然对这个问题感兴趣,subSelf 方法现在称为 sub

If somebody is still interested in this question subSelf method is now called sub.

潜移默化 2024-12-26 23:04:09

通过将以下内容添加到 onMouseDown 来解决

SELECTED = intersects[0].object;
while(SELECTED.parent != scene){
    SELECTED = SELECTED.parent;
}

这可以确保抓取的对象将是不是场景的最高级别,并使所有模型都可拖动。

Resolved by adding the following to onMouseDown

SELECTED = intersects[0].object;
while(SELECTED.parent != scene){
    SELECTED = SELECTED.parent;
}

This ensures that the object grabbed will be the highest level that isn't the scene and makes all the models drag-able.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文