Эмуляция gluLookAt с glm :: Quat (ernions)

Я пытался эмулировать функциональность gluLookAt, но с Quaternions. Каждый из моих игровых объектов имеет TranslationComponent. Этот компонент хранит объект позиция (glm::vec3), вращение (glm::quat) а также масштаб (glm::vec3). Камера рассчитывает свою позицию каждый тик, выполняя следующие действия:

// UP = glm::vec3(0,1,0);
//FORWARD = glm::vec3(0,0,1);
cameraPosition = playerPosition - (UP * distanceUP) - (FORWARD * distanceAway);

Этот код положения работает в режиме ожидания, камера находится на 3 метра позади игрока и на 1 метр вверх. Теперь Quaternion камеры настроен на следующее:

//Looking at the player's feet
cameraRotation = quatFromToRotation(FORWARD, playerPosition);

Механизм рендеринга теперь принимает эти значения и генерирует ViewMatrix (камера) и ModelMatrix (проигрыватель), а затем визуализирует сцену. Код выглядит так:

 glm::mat4 viewTranslationMatrix =
glm::translate(glm::mat4(1.0f), cameraTransform->getPosition());
glm::mat4 viewScaleMatrix =
glm::scale(glm::mat4(1.0f), cameraTransform->getScale());
glm::mat4 viewRotationMatrix =
glm::mat4_cast(cameraTransform->getRotation());

viewMatrix = viewTranslationMatrix * viewRotationMatrix * viewScaleMatrix;

quatFromToRotation (glm :: vec3 из, glm :: vec3 в) определяется как следующее:

glm::quat quatFromToRotation(glm::vec3 from, glm::vec3 to)
{
from = glm::normalize(from); to = glm::normalize(to);

float cosTheta = glm::dot(from, to);
glm::vec3 rotationAxis;

if (cosTheta < -1 + 0.001f)
{
rotationAxis = glm::cross(glm::vec3(0.0f, 0.0f, 1.0f), from);
if (glm::length2(rotationAxis) < 0.01f)
rotationAxis = glm::cross(glm::vec3(1.0f, 0.0f, 0.0f), from);

rotationAxis = glm::normalize(rotationAxis);
return glm::angleAxis(180.0f, rotationAxis);
}

rotationAxis = glm::cross(from, to);

float s = sqrt((1.0f + cosTheta) * 2.0f);
float invis = 1.0f / s;

return glm::quat(
s * 0.5f,
rotationAxis.x * invis,
rotationAxis.y * invis,
rotationAxis.z * invis
);
}

У меня проблемы с тем, что CameraRotation настроен неправильно. Независимо от того, где находится игрок, впереди камеры всегда (0,0, -1)

0

Решение

Ваша проблема в линии

//Looking at the player's feet
cameraRotation = quatToFromRotation(FORWARD, playerPosition);

Вам нужно посмотреть из положения камеры к ногам игрока — не от «одного метра над игроком» (при условии, что игрок находится на (0,0,0), когда вы изначально делаете это). замещать FORWARD с cameraPosition:

cameraRotation = quatToFromRotation(cameraPosition, playerPosition);

РЕДАКТИРОВАТЬ Я полагаю, у вас есть ошибка в вашем quatToFromRotation функция также. Увидеть https://stackoverflow.com/a/11741520/1967396 за очень хорошее объяснение (и некоторый псевдокод) вращения кватернионов.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]