到目前为止,我已经成功地使用THREE.Raycaster
来测试我的游戏引擎中的许多内容的碰撞,它很棒并且效果很好。
然而,最近我遇到了一些非常奇怪的东西,我似乎无法弄明白。从我的角度来看,我的逻辑和代码是合理的,但预期的结果是不正确的。 也许我只是错过了一些明显的东西,所以我想我会寻求一些帮助。
我正在从一组网格顶部的中心一个接一个地投射出圆弧。网格都是父Object3D
的子节点,目标是测试原始网格和其他网格之间的碰撞,这些网格也是父网格的子网格。为了测试我的光线,我正在使用THREE.ArrowHelper
。
以下是我的代码结果的图片 - http://imgur.com/ipzYUsa
在此图像中,ArrowHelper
个对象的位置(原点:方向)正是我想要的。但是,是的,这张照片有问题,产生的代码是:
var degree = Math.PI / 16,
tiles = this.tilesContainer.children,
tilesNum = tiles.length,
raycaster = new THREE.Raycaster(),
rayDirections, rayDirectionsNum, rayOrigin, rayDirection, collisions,
tile, i, j, k;
for (i = 0; i < tilesNum; i++) {
tile = tiles[i];
rayOrigin = new THREE.Vector3(
tile.position.x,
tile.geometry.boundingBox.max.y,
tile.position.z
);
rayDirections = [];
for (j = 0; j < Math.PI * 2; j += degree) {
rayDirections.push(new THREE.Vector3(Math.sin(j), 0, Math.cos(j)).normalize());
}
rayDirectionsNum = rayDirections.length;
for (k = 0; k < rayDirectionsNum; k++) {
rayDirection = rayDirections[k];
raycaster.set(rayOrigin, rayDirection);
collisions = raycaster.intersectObjects(tiles);
this.testRay(rayOrigin, rayDirection, collisions);
}
}
testRay
方法如下所示:
testRay: function (origin, direction, collisions) {
var arrowHelper = new THREE.ArrowHelper(
direction,
origin,
1,
(collisions.length === 0) ? 0xFF0000 : 0x0000FF
);
this.scene.add(arrowHelper);
}
现在,很明显,有关此图像的内容尚未解决。与其他网格碰撞的光线应为蓝色,而不碰撞的光线应为红色。 从这张图片可以清楚地看出,某些东西完全不合适,当我检查碰撞时,我得到了一些非常不合理的结果。对于很多在图像中显示为蓝色的光线,我会遇到大量的碰撞,有时像单个光线的30次碰撞,但即使它们紧挨着其他瓷砖也没有其他的碰撞。
我无法弄清楚它可能是什么。怎么这么多应该是蓝色的光线是红色的呢?而且,水平边缘的瓷砖光线如何与不存在的瓷砖发生蓝色碰撞?
真的挠我的头(读:反复抨击我的头),任何帮助都会受到超级赞赏!
答案 0 :(得分:1)
解决方案实际上不在此代码之内,至少我不相信,与过时的r68
版本相关。
制作拼贴网格时,我需要在它们上设置三个属性
tileMesh.matrixAutoUpdate = false;
tileMesh.updateMatrix();
tileMesh.updateMatrixWorld(); // this is new
我正在做前两个,而不是最后一个。为什么这是必要的,我不知道,这对我来说似乎有点奇怪但是这就解决了我的问题。我在场景中有一个AxisHelper
,如果您查看原始图像,您会注意到所有蓝色的ArrowHelper
个对象实际上都指向AxisHelper
。这真的很奇怪,因为AxisHelper
已添加到场景中,而不是tilesContainer
。将ArrowHelper
个对象添加到tilesContainer
没有任何帮助。
渲染场景的过程在将AxisHelper
添加到场景之前和初始渲染发生之前运行了raycaster代码。如果我在添加AxisHelper
后移动了raycaster代码调用,问题也解决了,但这是一个hacky解决方案。
所以真正的解决方法是将.updateMatrixWorld()
添加到切片中。结果现在看起来像http://imgur.com/8LewqxL,这是正确的(ArrowHelper
对象的长度已缩短,因此它们不会重叠。)
非常感谢Manthrax对他的帮助。
答案 1 :(得分:0)
我认为你做了一些本地和全球空间错误。我没有看到你出错的地方,但你所有的位置和方向计算似乎都在tilesContainer
的本地系统中。您在本地与全球坐标系处理方面是否一致?
例如,您将arrowHelper
添加到scene
而不是tilesContainer
。可能是tilesContainer
设置了rotation
,因此箭头指向的是另一个方向。
例如,如果您将箭头添加到tilesContainer
,会发生什么?