Отрицательная строка и столбец в алгоритме следования местности

Я пытаюсь выполнить слежение за местностью и получаю отрицательное положение камеры в плоскости xz. Теперь я получаю исключение за пределами границ, потому что строка или столбец отрицательны. Как правильно преобразовать ячейку сетки в начало координат, указав отрицательные координаты камеры.

Вот две функции

int cGrid::getHeightmapEntry(int row, int col)
{
    return m_heightmap[row * 300 + col];
}

float cGrid::getHeight(float x, float z, float _width, float _depth, int _cellSpacing)
{
    // Translate on xz-plane by the transformation that takes
    // the terrain START point to the origin.
    x = ((float)_width / 2.0f) + x;
    z = ((float)_depth / 2.0f) - z;

    // Scale down by the transformation that makes the 
    // cellspacing equal to one.  This is given by 
    // 1 / cellspacing since; cellspacing * 1 / cellspacing = 1.
    x /= (float)_cellSpacing;
    z /= (float)_cellSpacing;

    // From now on, we will interpret our positive z-axis as
    // going in the 'down' direction, rather than the 'up' direction.
    // This allows to extract the row and column simply by 'flooring'
    // x and z:

    float col = ::floorf(x);
    float row = ::floorf(z);

    if (row < 0 || col<0)
    {
        row = 0;
    }
    // get the heights of the quad we're in:
    // 
    //  A   B
    //  *---*
    //  | / |
    //  *---*  
    //  C   D

    float A = getHeightmapEntry(row, col);
    float B = getHeightmapEntry(row, col + 1);
    float C = getHeightmapEntry(row + 1, col);
    float D = getHeightmapEntry(row + 1, col + 1);

    //
    // Find the triangle we are in:
    //

    // Translate by the transformation that takes the upper-left
    // corner of the cell we are in to the origin.  Recall that our 
    // cellspacing was nomalized to 1.  Thus we have a unit square
    // at the origin of our +x -> 'right' and +z -> 'down' system.
    float dx = x - col;
    float dz = z - row;

    // Note the below compuations of u and v are unneccessary, we really
    // only need the height, but we compute the entire vector to emphasis
    // the books discussion.
    float height = 0.0f;
    if (dz < 1.0f - dx)  // upper triangle ABC
    {
        float uy = B - A; // A->B
        float vy = C - A; // A->C

        // Linearly interpolate on each vector.  The height is the vertex
        // height the vectors u and v originate from {A}, plus the heights
        // found by interpolating on each vector u and v.
        height = A + Lerp(0.0f, uy, dx) +  Lerp(0.0f, vy, dz);
    }
    else // lower triangle DCB
    {
        float uy = C - D; // D->C
        float vy = B - D; // D->B

        // Linearly interpolate on each vector.  The height is the vertex
        // height the vectors u and v originate from {D}, plus the heights
        // found by interpolating on each vector u and v.
        height = D + Lerp(0.0f, uy, 1.0f - dx) +  Lerp(0.0f, vy, 1.0f - dz);
    }

    return height;
}

введите здесь описание изображения

float height = m_Grid.getHeight(position.x, position.y, 49 * 300, 49 * 300, 6.1224489795918367f);
    if (height != 0)
    {
        position.y = height + 10.0f;
    }

    m_Camera.SetPosition(position.x, position.y, position.z);


bool cGrid::readRawFile(std::string fileName, int m, int n)
{

    // A height for each vertex
    std::vector<BYTE> in(m*n);
    std::ifstream inFile(fileName.c_str(), std::ios_base::binary);
    if (!inFile)
        return false;
    inFile.read(
        (char*)&in[0], // buffer
        in.size());// number of bytes to read into buffer
    inFile.close();
    // copy BYTE vector to int vector
    m_heightmap.resize(n*m);
    for (int i = 0; i < in.size(); i++)
        m_heightmap[i] = (float)((in[i])/255)*50.0f;
    return true;
}

m_Grid.readRawFile("castlehm257.raw", 50, 50);

person ahmed andre    schedule 09.05.2016    source источник
comment
Я бы порекомендовал удалить тег dx11 и добавить тег графики ... или что-то еще более уместное - вам нужно будет охватить более широкую аудиторию для этого вопроса. Также попробуйте опубликовать на gamedev.stackexchange.com.   -  person xaxxon    schedule 10.05.2016
comment
спасибо сделал ваши предложения   -  person ahmed andre    schedule 10.05.2016
comment
о, по какой-то причине я думал, что у вас может быть только 4 тега.   -  person xaxxon    schedule 10.05.2016
comment
Я проверил вашу математику и не нашел никаких проблем. Возможно, было бы полезно, если бы вы могли предоставить больше информации, например, определение m_heightmap и фактические значения, которые вы передаете cGrid::getHeight в случае сбоя.   -  person Entropy    schedule 10.05.2016
comment
@Entropy Я отредактировал сообщение. пожалуйста, дайте мне знать, если вам нужна дополнительная информация. Я все еще выхожу из связанного исключения.   -  person ahmed andre    schedule 10.05.2016


Ответы (1)


Я предполагаю, что вы храните матрицу 50 на 50 внутри матрицы 300 на 300, чтобы представить сетку 49 на 49 ячеек. Я также делаю вывод, что m_Grid является объектом типа cGrid. Похоже, ваш код содержит следующие ошибки:

Аргумент(2) вызова m_Grid.getHeight не является значением z.

Аргумент(3) вызова m_Grid.getHeight несовместим с аргументом(5).

Аргумент(4) вызова m_Grid.getHeight несовместим с аргументом(5).

Неявное приведение литерала float к int в аргументе (5) вызова m_Grid.getHeight - значение будет усечено.

Попробуйте изменить вызов функции на это:

float height = m_Grid.getHeight(position.x, position.z, 49 * cellspacing, 49 * cellspacing, cellspacing);

-- где cellspacing определено на вашей диаграмме.

Кроме того, попробуйте изменить параметр (5) cGrid::getHeight с int _cellSpacing на float _cellSpacing.

(Я несколько раз редактировал этот ответ по мере того, как мое понимание вашего кода развивалось.)

person Entropy    schedule 10.05.2016
comment
большое спасибо, но местность сейчас следует, но не точно, на некоторых холмах вообще не следует, а следующее не точно, что мне сделать, чтобы улучшить его - person ahmed andre; 11.05.2016
comment
Я предлагаю вам убедиться, что вы выполнили ВСЕ мои предложения, в том числе и об изменении int на float. Я предлагаю вам также проверить свой код на наличие других случаев неправильного использования int вместо float. Я предлагаю вам рассмотреть возможность изменения m_heightmap[i] = (float)((in[i])/255)*50.0f; на m_heightmap[i] = ((float)in[i])*50.0f/255.0f;. - person Entropy; 12.05.2016
comment
И если эти предложения не решат вашу проблему, я предлагаю вам опубликовать больше вашего кода (возможно, начиная с того, который отображает изображение местности) и больше информации о характере вашей проблемы. Подумайте о том, чтобы опубликовать это как отдельный вопрос, а затем опубликовать ссылку на него в комментарии здесь. Я также рекомендую вам показывать объявления переменных и экземпляров объектов при обращении за помощью, чтобы было ясно, к какому типу относится каждый объект. - person Entropy; 12.05.2016