如何用three.js'在'球体上“包裹”一架飞机?

时间:2014-05-01 10:08:59

标签: javascript 3d three.js collision-detection raycasting

我对于three.js相对比较新,我试图定位和操纵一个平面物体,以便在球体物体(或任何物体)的表面上铺设效果,这样飞机就会采取以下形式:物体表面。目的是稍后能够在平面上移动平面。

我将平面定位在球体前方并通过平面的顶点进行索引,将光线投射到球体上以检测与球体的交点。然后我尝试改变所述顶点的z位置,但是它没有达到预期的结果。任何人都可以给我一些关于如何使其工作的指导,或者确实提出另一种方法吗?

这是我尝试更改顶点的方法(偏移量为1,以便在球体表面上显示);

planeMesh.geometry.vertices[vertexIndex].z = collisionResults[0].distance - 1;

确保在渲染之前设置以下内容;

planeMesh.geometry.verticesNeedUpdate = true;
planeMesh.geometry.normalsNeedUpdate = true;

我有一个小提琴,显示我在哪里,在这里我将光线投射到z中,我不会与球体发生交叉(碰撞),也不能以我希望的方式改变飞机。

http://jsfiddle.net/stokewoggle/vuezL/

您可以使用左右箭头(无论如何都是镀铬)在场景周围旋转相机,以查看平面的形状。我已经让球体看到了,因为我发现更好地看到飞机是有用的。

编辑:更新了小提琴并更正了描述错误。

2 个答案:

答案 0 :(得分:4)

很抱歉延迟了,但我花了几天时间才想出这个。碰撞不起作用的原因是因为(就像我们怀疑的那样)planeMesh顶点在局部空间中,这与在球体中心开始而不是你所期望的基本相同。起初,我认为快速解决方法是应用worldkatrix,就像在他的github three.js碰撞示例中我所连接的那样,但是由于平面本身是用x定义的,所以它并没有结束。 y坐标,上下,左右 - 但在创建平面2D平面时,本地不会生成z信息(深度)。

最终工作的是手动设置平面每个顶点的z分量。你原本想要飞机在z = 201,所以我只是将代码移动到遍历每个顶点的循环中,我手动将每个顶点设置为z = 201;现在,所有光线起始位置都是正确的(全局)并且光线方向为(0,0,-1)导致正确的碰撞。

var localVertex = planeMesh.geometry.vertices[vertexIndex].clone();
localVertex.z = 201;

还有一件事是为了使平面包裹在形状上绝对完美,而不是使用(0,0,-1)作为每个光线方向,我通过从球体中减去每个顶点来手动计算每个光线方向&# 39; s中心位置定位并对结果向量进行归一化。现在,collisionResult交点会更好。

var directionVector = new THREE.Vector3();
directionVector.subVectors(sphereMesh.position, localVertex);
directionVector.normalize();
var ray = new THREE.Raycaster(localVertex, directionVector);

这是一个工作示例: http://jsfiddle.net/FLyaY/1/

如你所见,planeMesh紧贴球体,有点像补丁或创可贴。 :)

希望这会有所帮助。感谢您在three.js的github页面上发布问题 - 我不会在这里看到它。起初我认为这是THREE.Raycaster中的一个错误,但最终只是用户(我的)错误。我从处理这个问题中学到了很多关于碰撞代码的知识,我将在以后的3D游戏项目中使用它。您可以在https://github.com/erichlof/SpacePong3D

查看我的某个游戏

祝你好运! -Erich

答案 1 :(得分:0)

你的光线开始位置不好。可能是由于顶点坐标是平面的局部。你从球体内部开始射线投射,因此它永远不会击中任何东西。

我将这样的光线开始位置更改为测试并获得726次碰撞:

var rayStart = new THREE.Vector3(0, 0, 500);
var ray = new THREE.Raycaster(rayStart, new THREE.Vector3(0, 0, -1));

分叉的jsfiddle:http://jsfiddle.net/H5YSL/

我认为您需要将顶点坐标转换为世界坐标以正确获取位置。从文档和示例中可以很容易地理解这一点。