我曾经有一个项目,它使用灰度图像在一个简单的平面网格中设置顶点的高度,从而产生了漂亮的高度映射地形。但是,我已经将我的项目转换为C++,并且不能再使用BufferedImage的帮助,例如使用旧的灰度方法从平面网格创建高度映射地形。
正因为如此,我的C++项目现在使用.obj文件作为地形,但是我发现当用户在地形中行走时很难更新播放器/摄像机高度,相反,我只是漂浮在所有内容中,因为玩家高度永远不会改变或只是非常频繁地变化(所以我知道高度至少正在更新, 只是不正确(。
波纹管是一个小代码示例,它根据 terrain.obj 文件实际更新玩家高度,它通过存储 .obj 文件的所有顶点并将其每个 x 和 z 分量与播放器的 x 和 z 分量进行比较来实现这一点,如果有匹配项,则将球员的 y 值设置为当前顶点 y 位置:
Vector3f *playerPos = freeMoveObjects[0]->GetParent()->GetTransform()->GetPos();
float playerXPos = playerPos->GetX();
float playerZPos = playerPos->GetZ();
int playerXPosInt = (int)playerXPos;
int playerZPosInt = (int)playerZPos;
for (Vector3f currentVector : meshObjects[0]->getMeshVertices()) {
int meshHeightXInt = (int)currentVector.GetX();
int meshHeightZInt = (int)currentVector.GetZ();
if (meshHeightXInt == playerXPosInt & meshHeightZInt == playerZPosInt){//currentVector.GetX() <= playerXPos & currentVector.GetZ() <= playerZPos) {
freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->SetY(currentVector.GetY());
}
}
你现在正在做的事情效率非常低;如果你已经有一个可以用来更新玩家位置的高度图,你不应该循环遍历所有顶点。
为什么不将高度图存储在伪 2D 数组中,如下所示:
class HeightMap {
private:
int width;
int height;
std::unique_ptr<int[]> data = std::make_unique<int[]>(width * height);
public:
HeightMap(int width, int height) : width{width}, height{height} {}
// you can default copy, move constructors and assignments
int heightAt(int x, int y) {
return heightmap[x + y * width];
}
}
使用heightAt
您现在可以高效地随机访问地图中的数据。多亏了unique_ptr
您无需手动管理任何内存,并且可以默认使用其他构造函数。
请注意,您需要手动处理 x 或 y 超出范围等错误。