Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как мне преобразовать уголы накл. (yaw), тангаж (pitch) и крен (roll) в Irrlicht  (Прочитано 13470 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Juriy
Новенький

ru
Offline Offline

« : 07-04-2016 10:26 » 

Привет всем! Я реализую перемещения камеры в стиле Блендера (Blender) на движке Irrlicht. Правильное решение я нашел здесь. http://stackoverflow.com/questions/11470978/implementing-a-complex-rotation-based-camera
Какие методы есть в иррличте (Irrlicht), чтобы использовать для таких манипуляций ? Есть ли здесь Irrlicht специалисты ?

Как я должен закодировать следующие строки в Irllicht?

Код:
D3DXMATRIX oRotationMatrix1; // The camera orientation before mouse-change
D3DXMatrixRotationYawPitchRoll(&oRotationMatrix1, m_dRotationX, m_dRotationY, 0.0);

D3DXMATRIX oRotationMatrix2; // The camera orientation after mouse-change
D3DXMatrixRotationYawPitchRoll(&oRotationMatrix2, m_dRotationX + dX, m_dRotationY + dY, 0.0);

D3DXMATRIX oRotationMatrix2Inv; // The inverse of the orientation
D3DXMatrixTranspose(&oRotationMatrix2Inv,&oRotationMatrix2); // Transpose is the same in this case

D3DXMATRIX oScaleMatrix; // Negative scaling matrix for negating the translation
D3DXMatrixScaling(&oScaleMatrix,-1,-1,-1);

D3DXMATRIX oTranslationMatrix; // Translation by the reference point
D3DXMatrixTranslation(&oTranslationMatrix,
     m_oRotateAroundPos.x,m_oRotateAroundPos.y,m_oRotateAroundPos.z);

...

D3DXVECTOR4 oEyeFinal;
D3DXVec3Transform(&oEyeFinal, &m_oEyePos, &oTransformMatrix);

Спасибо за любую помощь!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 08-04-2016 04:05 » 

сам не занимался, но вот тут, по-моему, достаточно инфы
http://irrlicht.sourceforge.net/?page_id=291
http://irrlicht.sourceforge.net/docu/
http://irrlicht.sourceforge.net/docu/example003.html
« Последнее редактирование: 08-04-2016 04:08 от Алексей++ » Записан

Juriy
Новенький

ru
Offline Offline

« Ответ #2 : 12-04-2016 10:30 » 

Алексей++, спасибо!

Просмотрел информацию по форумам и прочим ... Понял, что нужно мне мат часть подучить, потому что
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 у меня камера "скачет" и  обращается то к объекту, то от него?

Спасибо заранее за ответы.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 13-04-2016 05:28 » 

1 -
(click to show)
http://irrlicht.sourceforge.net/docu/classirr_1_1core_1_1vector3d.html#a4db5cfbb71995227e37334a19278474d

судя по описанию,

v_rotated_by_R = R.rotationToDirection(v);

R - вектор поворота, построенный из углов Эйлера в градусах
v - изначальный вектор, который надо повернуть


3 -
(click to show)
вероятно, не задаёшь центр масштабирования (по умолчанию он у тебя будет в точке 0,0,0 сцены) . Порядок действий

 translate в нужную точку O (-Ox,-Oy,-Oz)
 scale
 translate обратно (+Ox,+Oy,+Oz)

 все три действия можно объединить в одну матрицу преобразования (как - не спрашивай, я не помню и не копался сейчас в коде Отлично )

С поворотом такая же штука - сначала нужно задать ось вращения, повернуться, вернуться
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 13-04-2016 09:18 » new

Леш, матрицы можно перемножать между собой, чтобы потом применять только результирующую матрицу.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines