Чтобы правильно сопоставить каждый пиксель изображения карты высот с ландшафтом, мы получим ландшафт как по ширине, так и по длине на 1 единицу меньше, чем фактическая ширина и длина карты высот. Например, если у нас есть изображение шириной всего 2 пикселя, каждый пиксель будет отображаться на каждую вершину четырехугольника. У нас есть 2 пикселя, но только 1 единица ландшафта.
Я пытаюсь «исправить» эту проблему, масштабируя ландшафт, чтобы заполнить пустой четырехугольник в конце ландшафта. Однако это проблематично, когда я пытаюсь получить высоту местности в некоторой точке (x, z). Проблема не в масштабировании, как вы увидите.
Во-первых, давайте посмотрим на код, который работает. Тот, где масштабирование не учитывает недостающий квад. У меня есть карта высот 1024x1024, которая создаст ландшафт с квадратами 1023x1023 (на самом деле я использую треугольники, но это легко объяснить с помощью четырехугольников) без какого-либо масштабирования.
Теперь давайте масштабируем местность примерно до 2000x2000, передав соответствующие аргументы следующей функции:
void Terrain::ScaleDimension(float dimWidth, float dimLength) {
if(dimWidth <= 0.0f || dimLength <= 0.0f) return;
stepWidth = dimWidth / width; // 1.953125 = 2000 / 1024
stepLength = dimLength / length; // 1.953125 = 2000 / 1024
}
Когда я рисую ландшафт, я использую stepWidth
и stepLength
для соответствующего масштабирования ландшафта. Ландшафт будет масштабирован, но будет использоваться только 1023 квадрацикла, всегда 1023, не более (что нормально). Теперь предположим, что я перемещаю своего игрового персонажа, и мне нужно получить высоту местности в текущей позиции игрока. У меня есть функция, которая принимает координаты x
и z
позиции игрока и возвращает высоту в этой точке. Но поскольку размер ландшафта масштабируется, я не могу просто использовать x
и z
, переданные функции, мне нужно вычислить правильные, например:
x = x / stepWidth;
z = z / stepLength;
После этого мне просто нужно найти 4 соседние вершины новых x
и z
и выполнить билинейную интерполяцию по всем высотам вершин, чтобы вычислить правильную высоту в позиции игрока.
Все работает нормально. Ландшафт прорисован правильно, и все высоты рассчитаны правильно. Моя проблема заключается в том, что я пытаюсь обойти «ограничение», описанное в начале этого вопроса.
Чтобы обойти проблему, я меняю свою функцию масштабирования на это:
void Terrain::ScaleDimension(float dimWidth, float dimLength) {
if(dimWidth <= 0.0f || dimLength <= 0.0f) return;
stepWidth = dimWidth / (width - 1.0f);
stepLength = dimLength / (length - 1.0f);
}
Скажем, мой размер ландшафта (значения, которые я передаю функции масштабирования выше) точно такой же, как и у карты высот, то есть 1024x1204. Это даст мне шаг 1.000977517106549364613880742913
, который заставит 1023 квадроциклов точно соответствовать от 0 до 1024 (размер местности). Пока все хорошо, местность прорисована именно так, как я ожидал.
Настоящая проблема - это вычисление высоты. Я пробовал много вещей, но просто не могу понять уравнение для вычисления правильных x
и z
, которые будут использоваться в функции, возвращающей высоту, с учетом нового вычисления шага выше. Погружение x
и z
с размером шага, как я делал раньше, просто не поможет. Шаг теперь рассчитывается немного иначе и не так просто, как раньше.