Как повернуть модель, чтобы следовать пути - PullRequest
2 голосов
/ 26 июня 2019

У меня есть модель космического корабля, по которой я хочу двигаться по круговой траектории.Я хочу, чтобы нос корабля всегда указывал в направлении, в котором он движется.

Вот код, который я должен переместить по кругу прямо сейчас:

glm::mat4 m = glm::mat4(1.0f);

        //time
        long value_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::
                                                                                                                                          high_resolution_clock::now())
                                                                                  .time_since_epoch())
                            .count();
        //translate 
        m = glm::translate(m, translate);
        m = glm::translate(m, glm::vec3(-50, 0, -20));
        m = glm::scale(m, glm::vec3(0.025f, 0.025f, 0.025f));
        m = glm::translate(m, glm::vec3(1800, 0, 3000));

        float speed = .002;
        float x = 100 * cos(value_ms * speed); // + 1800;
        float y = 0;
        float z = 100 * sin(value_ms * speed); // + 3000;
        m = glm::translate(m, glm::vec3(x, y, z));

Как быЯ перемещаю это так, нос всегда указывает вперед?Я попытался выполнить glm :: rotate с осью вращения, установленной как x или y или z, но я не могу заставить ее работать должным образом.

1 Ответ

0 голосов
/ 28 июня 2019

Сначала посмотрите Понимание матриц однородного преобразования 4x4 , поскольку я использую терминологию и прочее оттуда ...

Обычно для целей навигации используется матрица преобразования объекта, а ненаоборот ... Итак, у вас должна быть матрица преобразования M для вашего космического корабля, которая представляет его положение и ориентацию в [GCS] (глобальная система координат).Вдобавок к этому иногда умножается еще одна матрица M0, которая выравнивает сетку вашего космического корабля по первой матрице (вы знаете, что некоторые сетки не центрированы вокруг (0,0,0) и не выровнены по оси ...)

Теперь, когда выперемещая ваш объект, вы просто делаете локальные преобразования на M, поэтому продвижение вперед просто переводит M исходную позицию на кратный базисный вектор передней оси.То же самое касается скольжения в стороны (просто используйте другой базисный вектор), в результате чего объект всегда выровнен относительно того места, где он должен быть (относительно движения).То же самое касается поворотов.Таким образом, движение по кругу - это просто движение вперед и вращение с постоянной скоростью за шаг итерации (таймер).

Сначала вы делаете это в обратном направлении, сначала вычисляете положение и ориентацию, а затем пытаетесь выполнить операции, в результате чего получается матрица, котораясделал бы то же самое ... В таком случае намного проще построить матрицу M вместо создания преобразований, которые будут ее создавать ... Так что вам нужно:

  • исходная позиция
  • 3 перпендикулярных (наиболее вероятных единичных) базисных вектора

Таким образом, источником является ваша x,y,z позиция.Из окружности можно получить 2 базисных вектора, поэтому прямая является касательной (или position-last_position), а вектор по направлению к центру окружности может использоваться как (правый или левый).3-й вектор можно получить с помощью перекрестного произведения, поэтому предположим, что:

  • +X ось направлена ​​
  • +Y ось направлена ​​вверх
  • +Z осьвперед

вы получили:

r=100.0
a=speed*t
pos = (r*cos(a),0.0,r*sin(a))
center = (0.0,0.0,0.0)

так:

Z = (cos(a-0.5*M_PI),0.0,sin(a-0.5*M_PI))
X = (cos(a),0.0,sin(a))-ceneter
Y = cross(X,Z)
O = pos

нормализуйте:

X /= length(X)
Y /= length(Y)
Z /= length(Z)

Так что теперь просто накормитьX,Y,Z,O к вашей матрице (в зависимости от используемых вами соглашений, таких как порядок умножения, прямая / обратная матрица, матрицы строк или столбцов ...)

, например, так:

double M[16]=
 {
 X[0],X[1],X[2],0.0,
 Y[0],Y[1],Y[2],0.0,
 Z[0],Z[1],Z[2],0.0,
 O[0],O[1],O[2],1.0,
 };

или:

double M[16]=
 {
 X[0],Y[0],Z[0],O[0],
 X[1],Y[1],Z[1],O[1],
 X[2],Y[2],Z[2],O[2],
 0.0 ,0.0 ,0.0 ,1.0,
 };

И это все ... Матрица может быть транспонирована, инвертирована и т. Д. В зависимости от используемых вами соглашений.Извините, я не использую GLM, но синтаксис должен быть очень простым ... подача матрицы может быть еще проще, если строки или столбцы загружаются вектором ...

...