我想在我的游戏引擎中进行平滑的地形碰撞,当我说光滑时我的意思是玩家的高度不是由一个顶点决定的。我相信重心坐标是要走的路。我花了7个小时来研究这个问题,但是我所看到的代码中没有一个实际上有效,而且它也不能用简单的英语解释它。
到目前为止,这就是我所拥有的一切。 :(
public float getHeightAt(float xPos, float zPos) {
Vector3f one = new Vector3f((float)xPos, ((float)new Color(heightMap.getRGB((int)xPos, (int)zPos)).getRed())/255f*exaggeration*scale, (float)zPos);
Vector3f two = new Vector3f((float)xPos+1, ((float)new Color(heightMap.getRGB((int)xPos+1, (int)zPos)).getRed())/255f*exaggeration*scale, (float)zPos);
Vector3f three = new Vector3f((float)xPos, ((float)new Color(heightMap.getRGB((int)xPos, (int)zPos+1)).getRed())/255f*exaggeration*scale, (float)zPos+1);
float height = mid(one, two, three, new Vector3f(xPos, 0f, zPos));
System.out.println(height);
return height + 0.25f;
}
private float mid(Vector3f a, Vector3f b, Vector3f c, Vector3f p) {
Vector3f AB = a.mul(b);
Vector3f BC = b.mul(c);
Vector3f norm = AB.cross(BC);
float n0 = norm.getX();
float n1 = norm.getY();
float n2 = norm.getZ();
return (n0*a.getX() + n1*a.getY() + n2*a.getZ() - n0*p.getX() - n2*p.getZ()) / n1;
}
虽然有效,但它并不顺畅,我甚至不知道它是否是重心。
答案 0 :(得分:0)
球员位置可以由一个点确定。这里的情况是从高度图上的不同值创建一个相对平滑的函数。
插值应该可以解决问题。在最简单的情况下,它将在整个高度图上提供斜率。
在任何时间点,palyer位于高度图的某个矩形(四边形)中。我们可以通过双线性插值来评估该矩形的任何点的高度。
我们对两个边上的一个轴进行此操作,然后对剩余边进行第二个轴。
^
| A--------B
| | |
| | P |
| | |
| C--------D
Y
*X------------>
// This could be different depending on how you get points
// (basically generates a [0, 1] value depending on the position in quad;
px = P.x - (int)P.x
py = P.y - (int)P.y
AB = A.h * (1.0 - px) + B.h * px;
CD = C.h * (1.0 - px) + D.h * px;
ABCD = AB * (1.0 - py) + CD * py;
ABCD
是生成的高度
此方法并不完美,可能会产生视觉故障,具体取决于您在渲染管道中实际绘制四边形的方式。
另请注意,如果四边形比实际移动的演员更大,这种效果最佳。如果演员同时站在几个瓷砖上,则应使用某种平均方法。
答案 1 :(得分:0)
要获得平滑的高度,有两个主要步骤:
按照以下说明创建函数public float getHeightAt(float xPos, float zPos)
:
检查相机/播放器是否在地面正方形
if(xPos > 0 && xPos < nbVerticesX && zPos > 0 && zPos < nbVerticesZ)
获取 P 最接近 xPos 和 zPos
获取正常 N 或计算
计算平面方程
的常数 ddouble d = -(P.x * N.x + P.y * N.y + P.z * N.z);
返回计算高度
return -(d + N.z * zPos + N.x * xPos)/N.y;
使用此功能获得平滑的高度:
public float getHeightApprox(float x, float z)
{
return ( (getHeightAt(x,z)
+ getHeightAt(x + 1, z)
+ getHeightAt(x - 1, z)
+ getHeightAt(x, z + 1)
+ getHeightAt(x, z - 1)) / 5);
}
也许你必须调整你的代码,但这些代码对我来说很好。希望这会对你有所帮助。