在使用鼠标选择对象时,主要的困难是单击的是3D对象,而屏幕是平面2D显示。
以下是一个在三维场景中获取鼠标位置的例子:
通过babylonjs中的内置函数,可以轻易地获取鼠标在三维空间中的坐标:
在创建了表示墙壁的平面和带有impact图像的平面之后,我们必须检测UI(用户界面)上的单击。一旦事件被触发,使用“选择”函数来获取一些关于点击和场景之间关系的强大信息。
//When click event is raised
window.addEventListener("click", function () {
// We try to pick an object
var pickResult = scene.pick(scene.pointerX, scene.pointerY);
}),
效果为:
图中四个参数的含义为:
- hit:是一个布尔值,当点击中场景中的对象时为true,反之为false
- distance:是一个浮点数,指活动的相机和点击的对象点之间的距离,当hit为false时,距离为0
- pickedPoint:点击的点坐标转换成的三维坐标,取决于你点击的对象,若未选中则为null
- pickMesh:选中的mesh对象,若未选中,则为null
现在我们有了构建场景所需的所有数据。我们只需要定位我们的枪的撞击画面(一架早些时候制造的飞机…)当用户点击墙面平面时:
// if the click hits the wall object, we change the impact picture position
if (pickResult.hit) {
impact.position.x = pickResult.pickedPoint.x;
impact.position.y = pickResult.pickedPoint.y;
}
- 高级选择功能
pickResult对象可以提供额外的信息,具体如下:
1.ficeId:得到所选mesh的索引在索引数组中的位置
var indices = pickResult.pickedMesh.getIndices();//获取索引
var index0 = indices[pickResult.faceId ];//获取当前对象的索引位置
var index1 = indices[pickResult.faceId * 3 + 1];
var index2 = indices[pickResult.faceId * 3 + 2];
2.submeshId:所选的mesh中的submesh的id
3.bu、bv:选中点所在的面的质心坐标,选取的面是由3个顶点组成的多边形,选取的点是这3个顶点的重心,权重如下
4.getTextureCoordinates():计算所选点的纹理坐标,返回值是一个Vector2类型的值,值域为(0,1),可能会被用到:
- 使用DynamicTexture功能更新纹理
- 修改一个被点击的面(删除,移动顶点,改变颜色…)
-
改变submesh的材质
参考资料: https://doc.babylonjs.com/babylon101/picking_collisions