Модулируйте скорость объекта в цикле while, используя дельта время - PullRequest
1 голос
/ 26 сентября 2019
int i = 0;
void Car_Animation::update(float delta_time)
{
    glm::tvec3<float> tar = { 0,0,0 };
    tar = curve->curve_points_pos[(i+1) % (curve->points_pos.size())] -
        curve->curve_points_pos[(i) % (curve->points_pos.size())];

    m_model_mat = glm::translate(m_model_mat, tar);
    i++;

}

Вышеупомянутая функция вызывается в цикле while, где delta_time - это разница между предыдущим и текущим кадром;

while (!glfwWindowShouldClose(window))
    {
            animation->update(delta_time);
}

Прямо сейчас, в функции update я выполняю переводмоя модель с набором точек в curve->points_pos.curve->points_pos содержит массив точек, близких друг к другу, что создает иллюзию непрерывного движения модели. Но проблема в том, что я хочу модулировать скорость модели.Как я мог это сделать?У меня есть delta_time.Могу ли я использовать это?Я использую только glfw, glew and glm, а не glut.

1 Ответ

1 голос
/ 26 сентября 2019

Поправьте меня, если я ошибаюсь, но похоже, что у вас сейчас есть: * curve->curve_points_pos, который представляет собой массив местоположений, через которые вы хотите, чтобы ваша модель прошла;* m_model_mat - текущая матрица преобразования для вашей модели;и * i, который является текущим индексом в curve->curve_points_pos.

. Затем модель выполняет интегральные шаги от одной записи в curve->curve_points_pos к следующей, хотя вы применяете их как смещения друг от друга, а нечем воспринимать их как абсолюты.

В этом случае то, что у вас в основном есть функция времени, f(t) вычисляется с интегральными шагами t и сохраняется в curve->curve_points_pos.

Так, во-первых: перестаньте думать об обновлении m_model_mat и рассчитайте его целиком для каждой позиции.Например,

m_model_mat = glm::translate(glm::mat4(1.f), 
                             curve->curve_points_pos[(i) % (curve->points_pos.size())]);

Если у вас есть другое преобразование, которое вы также хотите применить - например, если вы хотите отодвинуть его от источника, составьте это как дополнительный шаг.

Второе: преобразованиеi в число с плавающей запятой и интерполировать между записями в curve->curve_points_pos.Итак:

const int i_integral = int(i) % curve->points_pos.size();
const int next_i_integral = int(i+1) % curve->points_pos.size();
const float i_fractional = fmodf(i, 1.f);
const auto curve_point = 
    curve->curve_points_pos[i_integral] * (1.f - i_fractional) + 
    curve->curve_points_pos[next_i_integral] * i_fractional;

m_model_mat = glm::translate(glm::mat4(1.f), curve_point);

Есть несколько бит для распаковки:

  • i теперь число с плавающей запятой, поэтому оно может описывать позицию между записями в curve->points_pos;
  • Я предположил линейную интерполяцию (модель будет проходить прямую линию между каждой парой перечисленных точек), поэтому:
    • каждая позиция может быть разбита на неотъемлемую часть идробная часть;где:
    • неотъемлемая часть идентифицирует две точки, между которыми проходит модель в настоящее время - само целое число будет идентифицировать ту, от которой оно уехало совсем недавно, и, неявно, оно идет к любой точке, следующей за ней;и
    • дробная часть определяет, как далеко она прошла между этими двумя точками, например, если дробная часть равна .0, то модель на самом деле еще не покинула свое происхождение, если она составляет .9999, то модель оченьпочти в следующей точке, если она равна .5, то модель находится точно посередине между ними и т. д .;
  • * curve_point, а затем моделируется эта логика.

Помимо наблюдений:

  • линейная интерполяция не обязательно является лучшей интерполяцией, но ее легко понять и вычислить, и если ваши точки достаточно близки друг к другу, это, вероятно, приемлемо;но
  • , если ваши точки действительно близки друг к другу, вы можете даже умерить интерполяцию всего вместе и просто использовать интегральную часть в качестве прямого поиска точек.Тогда ваша модель будет деформироваться от указанной точки к точке после того, как проведет правильное количество времени для каждой, но если ваши точки очень близки друг к другу, тогда это все еще может быть приемлемым.
...