地形碰撞问题
Terrain Collision issues
我正在尝试为我的高度图地形实现地形碰撞,我正在遵循这一点。本教程是针对java的,但我使用的是C++,尽管原理是一样的,所以这应该不是问题。
首先,我们需要一个函数来根据相机的位置获得地形的高度。WorldX和WorldZ是摄影机的位置(x,z),heights是包含所有顶点高度的2D阵列。
float HeightMap::getHeightOfTerrain(float worldX, float worldZ, float heights[][256])
{
//Image is (256 x 256)
float gridLength = 256;
float terrainLength = 256;
float terrainX = worldX;
float terrainZ = worldZ;
float gridSquareLength = terrainLength / ((float)gridLength - 1);
int gridX = (int)std::floor(terrainX / gridSquareLength);
int gridZ = (int)std::floor(terrainZ / gridSquareLength);
//Check if position is on the terrain
if (gridX >= gridLength - 1 || gridZ >= gridLength - 1 || gridX < 0 || gridZ < 0)
{
return 0;
}
//Find out where the player is on the grid square
float xCoord = std::fmod(terrainX, gridSquareLength) / gridSquareLength;
float zCoord = std::fmod(terrainZ, gridSquareLength) / gridSquareLength;
float answer = 0.0;
//Top triangle of a square else the bottom
if (xCoord <= (1 - zCoord))
{
answer = barryCentric(glm::vec3(0, heights[gridX][gridZ], 0),
glm::vec3(1, heights[gridX + 1][gridZ], 0), glm::vec3(0, heights[gridX][gridZ + 1], 1),
glm::vec2(xCoord, zCoord));
}
else
{
answer = barryCentric(glm::vec3(1, heights[gridX + 1][gridZ], 0),
glm::vec3(1, heights[gridX + 1][gridZ + 1], 1), glm::vec3(0, heights[gridX][gridZ + 1], 1),
glm::vec2(xCoord, zCoord));
}
return answer;
}
为了找到相机当前所在三角形的高度,我们使用重心插值函数。
float HeightMap::barryCentric(glm::vec3 p1, glm::vec3 p2, glm::vec3 p3, glm::vec2 pos)
{
float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
float l3 = 1.0f - l1 - l2;
return l1 * p1.y + l2 * p2.y + l3 * p3.y;
}
然后我们只需要使用我们计算的高度来检查游戏中的碰撞
float terrainHeight = heightMap.getHeightOfTerrain(camera.Position.x, camera.Position.z, heights);
if (camera.Position.y < terrainHeight)
{
camera.Position.y = terrainHeight;
};
现在,根据教程,这应该可以很好地工作,但高度相当偏离,在某些地方甚至不起作用。我想这可能与地形的平移和缩放部分有关
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, -0.3f, -15.0f));
model = glm::scale(model, glm::vec3(0.1f, 0.1f, 0.1f));
我应该把高度数组的值乘以0.1,因为缩放对GPU侧的地形起到了作用,但这并没有起到作用。
注意
在教程中,getHeightOfTerrain函数的第一行显示
float terrainX = worldX - x;
float terrainZ = worldZ - z;
其中x和z是地形的世界位置。这样做是为了获得玩家相对于地形位置的位置。我试着使用翻译部分的值,但也不起作用。我更改了这些行,因为这似乎没有必要。
float terrainX = worldX - x; float terrainZ = worldZ - z;
事实上,这些线是非常必要的,除非你的地形总是在原点。
您的代码资源(教程)假设您没有以任何方式缩放或旋转地形。x
和z
变量是地形的XZ位置,用于处理地形平移的情况。
理想情况下,应该将世界位置向量从世界空间转换到对象空间(使用用于地形的model
矩阵的逆矩阵),类似
vec3 localPosition = inverse(model) * vec4(worldPosition, 1)
然后用localPosition.x
和localPosition.z
代替terrainX
和terrainZ
。
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- 玩家移动和碰撞之间的交互问题
- 圆形与方形碰撞检测以及需要响应C++ |OpenGL。我的问题就是这个"I need to keep the circle outside the square"
- 三角形-三角形碰撞检测问题
- 使用碰撞检测来增加SFML 2.4中的游戏分数的问题
- 乒乓球碰撞问题
- 快板乒乓球碰撞问题
- 轴对齐边界框碰撞检测问题
- 关于游戏中碰撞检测的问题
- 简单的碰撞问题,利用c++和sfml
- c++ SDL2 /滚动碰撞问题
- 地形碰撞问题
- 碰撞响应(SAT)问题
- 基本碰撞问题