【问题标题】:How do I 'wrap' a plane over a sphere with three.js?如何使用 three.js 在球体上“包裹”飞机?
【发布时间】:2014-06-17 19:29:51
【问题描述】:

我对 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/

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

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

【问题讨论】:

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


    【解决方案1】:

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

    我像这样更改了光线开始位置作为测试并获得了 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/

    我认为您需要将顶点坐标转换为世界坐标才能正确获取位置。这应该很容易从文档和示例中弄清楚。

    【讨论】:

      【解决方案2】:

      抱歉耽搁了,但我花了几天时间才弄清楚这一点。碰撞不起作用的原因是(正如我们所怀疑的)planeMesh 顶点位于局部空间中,这与从球体中心开始基本相同,而不是您所期望的。起初,我认为一个快速解决方法是像 stemkoski 在我链接到的 github three.js 碰撞示例中那样应用 worldMatrix,但最终也没有成功,因为平面本身是在 x 和 y 坐标中定义的、上下、左右 - 但在创建平面二维平面网格时不会在本地生成 z 信息(深度)。

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

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

      还有一件事是为了使平面包裹在形状上绝对完美,而不是使用 (0,0,-1) 作为每个光线方向,我通过从球体中心减去每个顶点来手动计算每个光线方向定位位置并对结果向量进行归一化。现在,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

      祝你好运! -埃里希

      【讨论】:

      • 非常感谢,正是我想要的!我对光线投射器也有同样的怀疑,因此在另一个网站上发布了帖子。同样,我分享了相同的用户错误。自从我的原始帖子以来,我还没有机会自己回复它,我非常感谢您的帮助,您甚至更进一步完善了它!我会检查你的工作,希望有一天能对你有所帮助。
      • 由于某种原因我无法访问顶点 -> planeMesh.geometry.vertices 几何不再暴露顶点?
      猜你喜欢
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多