Значит бился я пару дней,
читал гугл, эксперементировал,
но кроме мега кустарного work
around ничего не нашёл.
Спрашиваю прямо:
Что мне сотворить с ProjectionMatrix,
ViewMatrix или WorldMatrix такое, чтобы
работать как и обычно, но дабы ось Z направлена в верх.
т.к писать везде:
D3DXVECTOR3 outVec( inVec.y, inVec.z, inVec.x );
но это пол беды, сюда прибавляем
неверные анимации из неверно прочитанных кватернионов,
неверный порядок перемножения углов эйлера
неверное чтение из VB...
Махинации с довращением матриц / кватернионов, свопом координат
векторов и прочего не канает...
В общем у меня координатная система как в id и valve,
как подружить с ней DX ?
как работают, и как конвертить RH -> LH и обратно уже разобрал по косточкам,
т.е OGL->DX визуализаторы переключать легко,
а что делать с основными матрицами ?
домножить на матрицу, диагональ которой состоит из единиц, кроме Z, где стоит минус единица
Домножить что?
Если ты про матрицу вида, то
до или после того как применяются
вращение и перемещение?
Сейчас сварганил после всех операций,
матрицу вида домножить вот так:
D3DXMatrixMultiply(&matView, &matView, &D3DXMATRIX( 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 ) );
После чего, вроде даже начинает работать,
но вот с вращениями камеры косяк,
может я где-то ошибся?
Lolmen
> Сейчас сварганил после всех операций,
> матрицу вида домножить вот так:
это что, похоже на диагонально-единичную с минусом в столбце-Z?
В чём смысл менять направление оси Z, если надо поменять местами Y и Z?
[ 1 0 0 0 ] [ 0 0 1 0 ] [ 0 -1 0 0 ] [ 0 0 0 1 ]
Если Y из глубины.
Что не так с вращениями? В каком порядке перемножаются матрицы?
Lolmen
http://www.gamedev.ru/community/toolcorner/articles/?id=5
вот тут написано как переводить матрицы из одной системы координат в другую
2 keltar
в вывороте faces на изнанку...
2 Kloun
Уже почитал,
так собственно домножать на такую вот доворачивающую матрицу
нужно только матрицу вида?
после всех преобразований?
2 All
Сча на работе, потестить не получиться...
keltar
> В чём смысл менять направление оси Z, если надо поменять местами Y и Z?
в том, что топикстартер просил поменять Z, а не XY
orly?
> outVec( inVec.y, inVec.z, inVec.x );
> но дабы ось Z направлена в верх
> как конвертить RH -> LH и обратно уже разобрал
Ни о чём не говорит?
Lolmen
Направление обхода меняется, если у меня не склероз. glFrontFace(GL_CW).
keltar
Ну твой предыдущий пост True для GL с RH,
и false for DX :)
И так, итог, работает всё отлично, в частности визуализация:
+X ось смотрит в глубь,
+Y ось смотрит в право,
+Z ось смотрит в верх,
только после некоторых мутаций с ориентацией,
перемещение уже вычисляется неверно,
т.е если pitch = 90, yaw = 0, то всё нормально
как не изменяй roll, при приращении к позиции
правого (локального) вектора, камера правильно летит
в том направлении куда надо, с учётом roll,
а вот если yaw например довращать на -90
то ориентация roll считается уже неверно...
Я уже извёлся, дебажить, думал, может
дело в том как я локальные векторы считаю, а нет,
не тут проблема...
В чём дело?
Сейчас я понимаю, что просьба конечно немаленькая,
но кто более менее набил руку на 3д математике, окиньте взглядом,
в том ли порядке я считаю матрицу вида:
//--------------------------------------------------------------------------------------------------------------------------------------- // Purpose: view matrix from camera orientation // Origin -> camera position in world space // pitch, yaw, roll euclidian orientation of camera // NOTE: should be in radians //---------------------------------------------------------------------------------------------------------------------------------------- void ViewMatrixFromPYR(D3DXMATRIX &matView, const lVec3d &origin, real32 pitch, real32 yaw, real32 roll ) { ::D3DXMatrixIdentity( &matView); D3DXVECTOR3 xAxis( 1,0,0), yAxis( 0,1,0), zAxis( 0,0,1); // Rotate x and y axis round z axis if ( !lMath::IsZero( yaw) ) { ::D3DXMatrixRotationAxis( &matView, &zAxis, yaw ); ::D3DXVec3TransformCoord( &xAxis, &xAxis, &matView ); ::D3DXVec3TransformCoord( &yAxis, &yAxis, &matView ); } // Rotate x and z axis around y axis if ( !lMath::IsZero( pitch) ) { ::D3DXMatrixRotationAxis( &matView, &yAxis, pitch ); ::D3DXVec3TransformCoord( &xAxis, &xAxis, &matView ); ::D3DXVec3TransformCoord( &zAxis, &zAxis, &matView ); } // Rotate y and z axis around x axis if ( !lMath::IsZero( roll) ) { ::D3DXMatrixRotationAxis( &matView, &xAxis, roll ); ::D3DXVec3TransformCoord( &yAxis, &yAxis, &matView ); ::D3DXVec3TransformCoord( &zAxis, &zAxis, &matView ); } // set up view matrix orientation matView( 0,0) = xAxis.x; matView( 1,0) = xAxis.y; matView( 2,0) = xAxis.z; matView( 3,0) = 0; matView( 0,1) = yAxis.x; matView( 1,1) = yAxis.y; matView( 2,1) = yAxis.z; matView( 3,1) = 0; matView( 0,2) = zAxis.x; matView( 1,2) = zAxis.y; matView( 2,2) = zAxis.z; matView( 3,2) = 0; // set up translation D3DXMATRIX matTrans; D3DXVECTOR3 vecTrans( origin.x, origin.y, origin.z ); // final view matrix D3DXMatrixTranslation( &matTrans, -D3DXVec3Dot( &vecTrans, &xAxis ), -D3DXVec3Dot( &vecTrans, &yAxis ), -D3DXVec3Dot( &vecTrans, &zAxis ) ); D3DXMatrixMultiply( &matView, &matView, &matTrans); // flip coordinate system D3DXMatrixMultiply( &matView, &matView, &D3DXMATRIX( 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1) ); }
Углы храню в форме [ -180 < angle <= 180 ] градусов
Подсекая, превышения ( нормализация )
Собсно перемещение камеры:
// F,L,U AngleVectors(camAngles, &vLook, &vLeft, 0 ); lVec3d mov( 0,0,0); // Forward / back if( keys['W'] & 0x80 ) { mov += vLook * cam_speed * dt; } else if ( keys['S'] & 0x80 ) { mov -= vLook * cam_speed * dt; } // Left / right if( keys['A'] & 0x80 ) { mov += vLeft * cam_speed * dt; } else if ( keys['D'] & 0x80 ) { mov -= vLeft * cam_speed * dt; } // Up / down [ used global z axis (0,0,1) ] if( keys['Q'] & 0x80 ) { mov += vec3_zAxis * cam_speed * dt; } else if ( keys['E'] & 0x80 ) { mov -= vec3_zAxis * cam_speed * dt; }
Собсно векторы из углов получаются так:
LF_INLINE void AngleVectors(const lAng3 &ang, lVec3 *fwd, lVec3 *left, lVec3 *up ) { real32 sr, sp, sy, cr, cp, cy, spsy; lMath::SinCos( lMath::Deg2Rad( ang.yaw ), sy, cy ); lMath::SinCos( lMath::Deg2Rad( ang.pitch ), sp, cp ); lMath::SinCos( lMath::Deg2Rad( ang.roll ), sr, cr ); if ( fwd != nullptr ) fwd->Set( cp * cy, cp * sy, -sp ); sr = -sr; sy = -sy; spsy = sp * sy; if ( up != nullptr ) up->Set( cr * sp * cy + sr * sy, cr * spsy + sr * cy, cr * cp ); cr = -cr; if ( left != nullptr ) left->Set( sr * sp * cy + cr * sy, sr * spsy + cr * cy, sr * cp ); }
Глазик от всего этого замылился
уже, на отказ не видит,
где я мог затутить неподецки? :)
Тема в архиве.