在我的项目中,我让一名玩家环游世界。地球不仅仅是一个球体,它还有山脉和山谷,所以我需要改变玩家的 z 位置。为此,我从玩家的位置向单个对象(地球)投射一条光线,并得到它们相交的点并相应地改变玩家的位置。我仅在玩家移动时进行光线投射,而不是在每一帧上进行光线投射。
对于一个复杂的物体来说,它需要很长时间。对于具有约 1m 多边形(面)(1024x512 分段球体)的对象,需要约 200 毫秒。光线投射是否会投射到每一张脸上?
是否有一种传统的快速方法可以在“三”中实现此目的,例如某种加速结构(八叉树?bvh?——说实话,从我的谷歌搜索中我似乎没有找到“三”中包含这样的东西)或其他一些思考-the-box(无光线投射)方法?
var dir = g_Game.earthPosition.clone();
var startPoint = g_Game.cubePlayer.position.clone();
var directionVector = dir.sub(startPoint.multiplyScalar(10));
g_Game.raycaster.set(startPoint, directionVector.clone().normalize());
var t1 = new Date().getTime();
var rayIntersects = g_Game.raycaster.intersectObject(g_Game.earth, true);
if (rayIntersects[0]) {
var dist = rayIntersects[0].point.distanceTo(g_Game.earthPosition);
dist = Math.round(dist * 100 + Number.EPSILON) / 100;
g_Player.DistanceFromCenter = dist + 5;
}
var t2 = new Date().getTime();
console.log(t2-t1);
先感谢您
不要使用 Three.js Raycaster。
考虑Ray.js https://github.com/mrdoob/three.js/blob/dev/src/math/Ray.js提供function intersectTriangle(a, b, c, backfaceCulling, target)
建议的优化:
如果玩家从一些已知位置开始⇒你必须知道他的初始高度,-不需要光线投射(或者只做一次全网格慢速相交)
如果玩家小步移动 ⇒ 下一个光线投射将最有可能的与之前相同的面相交。
优化 #1- 记住之前的脸,并首先对其进行光线投射。
- 如果玩家不跳⇒下一个光线投射将最有可能的将相邻面与玩家之前所在的面相交。
优化#2− 建立一个缓存,以便给定一个面 idx,您可以在 O(1) 时间内检索相邻面。
如果您的星球不是实时生成的,则可以从文件加载此缓存。
因此,按照我的方法,每次移动时,您都会从缓存和光线投射 1-6 个面中执行 O(1) 读取操作。
Win!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)