【问题标题】:Detect click on mesh of 3DObject检测点击 3D 对象的网格
【发布时间】:2017-05-03 19:20:33
【问题描述】:

我从 .obj 和 .mtl 加载了一个模型,我希望用户能够单击模型的特定部分,例如,更改它们的颜色。即点击车门并能够更改该门网的颜色。

这是我的模型加载代码,如果需要的话。

var mtlLoader = new THREE.MTLLoader();
    mtlLoader.setPath('Models/Aventador/');
    mtlLoader.load('Avent.mtl', function (materials) {
        materials.preload();
        var objLoader = new THREE.OBJLoader();
        objLoader.setMaterials(materials);
        objLoader.setPath('Models/Aventador/');
        objLoader.load('Avent.obj', function (object) {
            object.position.y = 0;          
            scene.add(object);
        }, onProgress, onError);
    });

编辑: 我现在有以下代码,它没有给出错误并按预期将“mouseup”打印到控制台,但没有按预期打印出任何交叉点,有什么想法吗?

var mouse = new THREE.Vector2();
function onDocumentMouseUp(event) {
    console.log("mouseUp")
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    var raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, camera);
    var intersects = raycaster.intersectObjects(scene.children);
    for (var i = 0; i < intersects.length; i++) {
        console.log(intersects[i]);
        intersects[i].object.material.color.set(0x0000ff);
    }
}

编辑 2

【问题讨论】:

  • 我有一种感觉,你可以做到这一点的唯一方法是,如果网格的每个“可点击”部分(例如门)都是加载到场景中的单独网格。你有能力把它拆成这样吗?
  • @Hectate 我不确定,我对 3D 模型没有太多经验。我发现了一些可以遍历 3DObject 的子网格并单独更改它们的属性的东西,但是无法识别哪个网格是哪个
  • 很公平,我也不知道。如果它由您可以修改的子网格组成,那么您正在寻找的答案是光线投射,以检测哪个组件被“触摸”并修改该组件的设置。试试:stackoverflow.com/questions/9275628/…
  • @Hectate 在那个例子中什么是objects in ray.intersectObjects( objects );?
  • 如果我不得不猜测这将是场景中的一组对象。让我提供一个应该有更多帮助的答案。

标签: javascript model 3d three.js


【解决方案1】:

因此,对于单击部分,您需要从鼠标位置向模型投射光线。下面的链接应该会为您提供足够的信息以帮助您入门:

Raycaster

光线投射应该告诉你你击中了哪个对象,然后你可以记住该对象以供使用(例如更改颜色属性)。

在回答您的其他问题时,objects 类似于上面链接中的scene.children。您也可以只将网格传递给它,看看它是否击中它(而不是说,你让汽车坐在一个光或平面上作为表面)。

编辑:因为它是一个 Obj,我们在聊天中发现我们需要跟随 this answer 并在光线投射上启用递归以使其检测所需的模型部分。

【讨论】:

  • 试过了,好像不行,或者我有问题。见编辑
  • 这几乎可以肯定是因为您直接使用鼠标坐标。如果您查看其中的一些示例,您会发现它们做了一些数学运算来将鼠标位置转换为屏幕空间:github.com/mrdoob/three.js/blob/master/examples/…
  • 添加了建议的数学。仍然得到与以前相同的结果
  • 或许可以沿着射线绘制一个 ArrowHelper 以查看它的实际走向?如果它仍然看起来相交,那么可能还有其他事情发生。这是 StackOverflow 上其他地方的简单代码:scene.add(new Three.ArrowHelper( raycaster.ray.direction, raycaster.ray.origin, 100, Math.random() * 0xffffff ));
  • 它肯定会检测到正确位置的点击并获得正确的向量,请参阅编辑 2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 2014-12-14
  • 2013-04-02
  • 2016-10-26
  • 2018-03-25
相关资源
最近更新 更多