Я пишу небольшой raytracer и хочу повернуть камеру вокруг какого-нибудь объекта. Таким образом, я могу добиться такого кода:
vecTemp - вектор положения камеры, vecT - первая позиция (я запускаю этот фрагмент для цикла for). Угол поворота - это угол радиана перемещенной камеры.
double yaw = degree * (PI / 180.f);
vecTemp.x() = cos(yaw) * vecT.x() - sin(yaw) * vecT.z();
vecTemp.z() = cos(yaw) * vecT.z() + sin(yaw) * vecT.x();
vecTemp.y() = 0;
sett.camera.buildCameraToWorld(vecTemp, { 0, 0, 0} );
sett.camera.rotateY(2*degree);
void buildCameraToWorld(const arma::dvec3& from, const arma::dvec3& to, const arma::dvec3& tmp = arma::dvec3{ 0, 1, 0 })
{
arma::dvec3 forward = arma::normalise(from - to);
arma::dvec3 right = arma::cross(arma::normalise(tmp), forward);
arma::dvec3 up = arma::cross(forward, right);
this->cameraToWorld.zeros();
this->cameraToWorld(0, 0) = right.x();
this->cameraToWorld(0, 1) = right.y();
this->cameraToWorld(0, 2) = right.z();
this->cameraToWorld(1, 0) = up.x();
this->cameraToWorld(1, 1) = up.y();
this->cameraToWorld(1, 2) = up.z();
this->cameraToWorld(2, 0) = forward.x();
this->cameraToWorld(2, 1) = forward.y();
this->cameraToWorld(2, 2) = forward.z();
this->cameraToWorld(3, 0) = from.x();
this->cameraToWorld(3, 1) = from.y();
this->cameraToWorld(3, 2) = from.z();
this->cameraToWorld = this->cameraToWorld.t();
}
void rotateY(double yaw)
{
yaw = yaw * (PI / 180);
this->cameraToWorld = this->cameraToWorld * arma::dmat44{ { cos(yaw), 0, sin(yaw), 0},
{ 0, 1, 0, 0},
{-sin(yaw), 0, cos(yaw), 0},
{ 0, 0, 0, 1} };
}
Итак, теперь я не понимаю, почему после поворота я поворачиваюсь по оси Y - после buildCameraToWorld я должен получить новую матрицу камеры, смотрящую на мое происхождение, верно? Почему мне нужно повернуть на величину в два градуса?
Я нашел другой способ сделать это - я могу вращать весь мир и не перемещать камеру, как в камере из OpenGL, но это хорошая идея для трассировки лучей?