Как применить перевод после поворота без изменения направления перевода? - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь применить перевод к матрице модели объекта в моей программе OpenGL, но если я применю перевод после применения масштаба или поворота к матрице модели, я получу результаты, отличные от ожидаемых: применение перевода после шкалы приводит к умножению перевода на шкалу, применение перевода после поворота приводит к тому, что перевод применяется в другом направлении.Я понимаю, как работают матрицы в игре и как они изменяют матрицу модели, поэтому я использовал эту реализацию, чтобы отменить изменения перед применением перевода:

void Entity::scale(float scaleFactor) {
  this->modelMatrix = glm::scale(this->modelMatrix, glm::vec3(scaleFactor));
  this->scaleFactor *= scaleFactor;
}

void Entity::move(glm::vec3 position, glm::mat4 viewMatrix) {
  float oldScaleFactor = this->scaleFactor;
  float oldRotateFactorX = this->rotateFactorX;
  float oldRotateFactorY = this->rotateFactorY;
  float oldRotateFactorZ = this->rotateFactorZ;

  scale(1 / this->scaleFactor);

  rotate(-this->rotateFactorX, -this->rotateFactorY, -this->rotateFactorZ);

  this->modelMatrix = glm::translate(modelMatrix, position);

  glm::mat4 worldModelMatrix = glm::inverse(viewMatrix) * (viewMatrix * this->modelMatrix);

  this->worldPosition.x = worldModelMatrix[3][0];
  this->worldPosition.y = worldModelMatrix[3][1];
  this->worldPosition.z = worldModelMatrix[3][2];

  rotate(oldRotateFactorX, oldRotateFactorY, oldRotateFactorZ);

  scale(oldScaleFactor);
}

void Entity::rotate(float x, float y, float z) {
  this->rotateFactorX += x;
  this->rotateFactorY += y;
  this->rotateFactorZ += z;
  this->modelMatrix = glm::rotate(this->modelMatrix, glm::radians(x), glm::vec3(1.0f, 0.0f, 0.0f));
  this->modelMatrix = glm::rotate(this->modelMatrix, glm::radians(y), glm::vec3(0.0f, 1.0f, 0.0f));
  this->modelMatrix = glm::rotate(this->modelMatrix, glm::radians(z), glm::vec3(0.0f, 0.0f, 1.0f));
}

В основном я обращаю операции масштабирования и поворота перед применениемперевод, а затем положить их обратно, как они были раньше.Эта реализация работает для масштаба, но она не работает для вращения, что приводит к увеличению скорости вращения, которая выходит из-под контроля (то есть коэффициент вращения постоянно увеличивается).Правильно ли я возвращаю вращение?или даже лучше: есть ли лучший способ разделить 3 операции без их взаимодействия друг с другом?

1 Ответ

0 голосов
/ 30 марта 2019

Оказывается, я применял преобразования в неправильном порядке (масштабирование перед вращением) при попытке отменить изменения. Чтобы избежать необходимости полностью отменять изменения, вы можете просто установить 3 разные матрицы идентичности (одну для перевода, одну для вращения и одну для масштаба) и применить правильное преобразование к каждой матрице в отдельности, а затем умножить 3 матрицы вместе, чтобы получить Модель матрицы, порядок важен: модель = перевод * вращение * масштаб таким образом, вы всегда применяете преобразования в правильном порядке, и вам не нужно беспокоиться о том, что 3 преобразования мешают друг другу

...