Отображение высоты Android Импортированный файл OBJ в OpenGL ES 2.0?
Я работаю над примером проекта на Java, в частности Android, с OpenGL ES 2.0. Я стремлюсь создать ландшафт, по которому игрок будет перемещаться. Игрок должен двигаться вверх и вниз по местности, следуя карте высот. Рельеф не ровный. Я использую Blender для создания карты местности и высоты. Ландшафт импортируется как файл obj.
Импорт и рисование работает нормально, но у меня есть проблемы, заставляющие координаты следовать карте высот. Кажется, это не соответствует 100%. Игрок слишком часто поднимается или опускается слишком рано или падает ниже рельефа.
Что у меня так далеко:
1) Я занимаюсь импортом файла OBJ в проект. Чтение самой далекой точки от объекта местности и использование ее в качестве длины объекта (это значение * 2). Это говорит мне, сколько вершин в объекте вдоль одной стороны.
2) Затем я получаю разницу в положении игроков относительно происхождения местности в мировых координатах. Я беру значения x и z и делю каждое из них на длину объекта OBJ * 2, чтобы получить область ландшафта, в которой находится объект. Это даст мне процент от того, где положение x и z игрока находится относительно ландшафта,
3) Я открываю карту высот и умножаю вышеприведенные проценты на изображение карты высот, чтобы получить координаты x и y на карте высот, чтобы считывать высоту.
Ниже то, с чем я работаю.
public float getHeightOfTerrain(float worldX, float worldZ){
// worldX and worldZ are the players position
// Currentmatrix is the matrix used for positioning the terrain
float terrainX = worldX - CurrentMatrix[12] + objLength;
float terrainZ = worldZ - CurrentMatrix[14] + objLength;
return getHeight(terrainX, terrainZ);
}
................
float MAX_HEIGHT = 20;
float MAX_PIXEL_COLOR = 256*256*256;
................
public float getHeight(float x, float z){
float posX = x / (objLength*2);
float posZ = z / (objLength*2);
if(posX < 0 || posX > 1 || posZ < 0 || posZ > 1){ // if over 1 which is 100% of terrain then return
return 0;
}
float imgX = posX * bitmapOfMap.getWidth();
float imgZ = bitmapOfMap.getHeight() - (posZ * bitmapOfMap.getHeight()); // subtract BC bitmap y reads in reverse
if(imgX < 0 || imgX >= bitmapOfMap.getWidth() || imgZ < 0 || imgZ >= bitmapOfMap.getHeight()){ // if over then return
return 0;
}
float height = bitmapOfMap.getPixel((int)imgX, (int)imgZ);
height += MAX_PIXEL_COLOR/2f;
height /= MAX_PIXEL_COLOR/2f;
height *= MAX_HEIGHT;
return height;
}
Чем меньше высота местности, тем лучше работает эта настройка. Чем больше изменение высоты местности, тем хуже работает эта система. Я пробовал разные obj и карты высот, воссоздавая снова и снова, думая, что это может быть проблемой, но существуют те же проблемы.
Я делаю это совершенно неправильно? Любая помощь будет оценена. Кто-нибудь знает лучший способ? Я действительно хочу сохранить импорт файла OBJ и прочитать его для настройки.
1 ответ
Я пошел дальше и создал ландшафт только по карте высот, без импорта OBJ. Затем применил мой код выше и имел точно такую же проблему. Поэтому я немного углубился в то, что происходит шаг за шагом. Все началось с того, как я следил за местоположением местности на x, y и z, а затем вычел это из позиции игроков. Я отслеживал положение игроков из отдельного массива x, y, z, а затем положение ландшафта из матрицы [12], матрицы [13], матрицы [14] как x, y, z.
Это была проблема. Я не могу использовать поплавки в матрицах для позиционирования относительных значений. Я должен был сохранить отдельные x, y, z для местности.
Так что из.....
float terrainX = worldX - CurrentMatrix[12] + objLength;
float terrainZ = worldZ - CurrentMatrix[14] + objLength;
в
float x, y, z = 0;
.....
float terrainX = z;
float terrainZ = x;
Теперь модель работает отлично! .... перемещается вверх и вниз по местности соответственно карте высот. Я надеюсь, что это поможет любому, у кого может быть такая же проблема.