Алексей++, спасибо!
Просмотрел информацию по форумам и прочим ... Понял, что нужно мне мат часть подучить, потому что
1 сцена внезапно вращается восьмеркой, в какие-то моменты (не понял от чего зависит)
2 когда сцена поворачивается ко мне задом, то движение по вертикали инвертируется
Сделал так (собственно, перевел алгоритм выше на иррлич):
vector3df Heel3DWidget::cameraPosByMouseMove(QPointF oldMouse, QPointF newMouse)
{
double dX = (oldMouse.x() - newMouse.x()) * 4/1080. * M_PI;
double dY = (oldMouse.y() - newMouse.y()) * 4/1080. * M_PI;
// Yaw Pitch Roll to matrix
vector3df rot1(m_dYRotation,m_dXRotation ,0);
irr::core::quaternion rotQuat1;
rotQuat1.set(rot1);
matrix4 rotationMatrix1 = rotQuat1.getMatrix();
//
vector3df rot2(m_dYRotation + dY,m_dXRotation + dX,0);
irr::core::quaternion rotQuat2;
rotQuat2.set(rot2);
matrix4 rotationMatrix2Inv;
rotQuat2.getMatrix_transposed(rotationMatrix2Inv);
//
// vector3df scaling(-1.,-1.,-1);
//
matrix4 transformationMatrix;
// transformationMatrix.setScale(scaling);
transformationMatrix *= rotationMatrix1;
transformationMatrix *= rotationMatrix2Inv;
// transformationMatrix.setScale(scaling);
// vector3df rotAbout(0.,0.,0.);
// transformationMatrix.setTranslation(rotAbout);
vector3df eyeFinal = camera()->getPosition();
transformationMatrix.transformVect(eyeFinal);
rotateXAxis(dX);
rotateYAxis(dY);
return eyeFinal;
}
void Heel3DWidget::rotateXAxis(const double dRadians) {
m_dXRotation += dRadians;
m_dXRotation = fmod(m_dXRotation, 2 * M_PI);
//m_dXRotation = qMin(m_dXRotation, M_PI * 0.49);
//m_dXRotation = qMax(m_dXRotation, M_PI * -0.49);
}
void Heel3DWidget::rotateYAxis(const double dRadians) {
m_dYRotation += dRadians;
m_dYRotation = fmod(m_dYRotation, 2 * M_PI);
}
Понять, почему получаются такие ошибки, не получается пока что. Разве что с углами эйлера разобраться еще не пробовал.
есть два отличия от алгоритма , который описан по ссылке, которую я давал ранее:
1 Я не умножаю на отрицательную ид. матрицу (см. код выше -- матрица scaling) -- до конца не ясно зачем она, подозреваю, за тем, чтобы убрать как раз этот эффект восьмерки, который возникает из-за неверного задания изначальных углов поворота (которые интерпретируются как углы эйлера, хотя такими не являются)
2 Я не транслэйтаю, как описано в том алгоритме, хотя такая необходимость появляется, если использовать умножение на scaling, т.к. камера начинает отдаляться.
3 Способ перевода углов поворота относительно оси в углы эйлера я нашел такой:
vector3df rot(pitch,yaw,0);
irr::core::quaternion quat;
quat.fromAngleAxis(roll*DEGTORAD,rot.rotationToDirection());
vector3df final;
quat.toEuler(final);
Но он дает матрицу идентичности, если угол roll равен 0. И не совсем уверен, что rotationToDirection дает то, что нужно для метода quaternion::fromAngleAxis(.). Поэтому пользуюсь просто методом quaternion::set для задания квотерниона.
У меня много вопросов, буду рад любой помощи!
Вот самые актуальные:
1 Что делает метод vector3df::rotationToDirection()?
2 правильно ли я применяю преобразования для матриц?
3 Почему при использовании scaling у меня камера "скачет" и обращается то к объекту, то от него?
Спасибо заранее за ответы.