【问题标题】:Smooth Terrain Collision - 3D平滑地形碰撞 - 3D
【发布时间】:2014-10-09 07:55:38
【问题描述】:

我想在我的游戏引擎中实现平滑的地形碰撞,当我说平滑时,我的意思是玩家的高度不是由一个顶点决定的。我相信重心坐标是要走的路。我花了 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;
    }

它可以工作,但它不平滑,我什至不知道它是否是重心的。

这是我想要的示例:https://www.youtube.com/watch?v=ngJ6ISfXG3I

【问题讨论】:

  • 您可能想尝试双线性插值。

标签: java opengl collision smooth terrain


【解决方案1】:

要获得平滑的高度,主要有两个步骤:

I - 创建一个函数从位置获取高度

按照以下说明创建函数public float getHeightAt(float xPos, float zPos)

  1. 检查相机/播放器是否在地面方块内

    if(xPos > 0 && xPos < nbVerticesX && zPos > 0 && zPos < nbVerticesZ) 
    
  2. 获取最近xPoszPos

  3. 的点P
  4. 获取正常的N或计算它

  5. 计算平面方程的常数d

    double d = -(P.x * N.x + P.y * N.y + P.z * N.z);
    
  6. 返回计算高度

    return -(d + N.z * zPos + N.x * xPos)/N.y;
    

II - 计算近似高度

使用此函数获得平滑高度:

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);
}

也许您将不得不调整您的代码,但这些代码对我来说很好用。希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    位置和坡度

    玩家的位置可以由一个点决定。这里的情况是从高度图上的不同值创建一个相对平滑的函数。

    插值应该可以解决问题。在最简单的情况下,它将在整个高度图上提供一个坡度。

    双线性插值(四边形)

    在任何时间点,高度图的某个矩形(四边形)中的图层位置。我们可以通过做双线性插值来评估这个矩形任意点的高度。

    我们在两条边上的一个轴上执行此操作,然后在剩余边上的第二个轴上执行此操作。

    ^
    | 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 是结果高度

    注意事项

    此方法并不完美,可能会产生视觉故障,具体取决于您在渲染管道中实际绘制四边形的方式。

    另外请记住,如果四边形比实际移动的演员大,这种方法效果最好。如果演员同时站在几个瓷砖上,则应使用某种平均方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-27
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 2013-08-10
      相关资源
      最近更新 更多