ПрограммированиеФорумГрафика

Своя координатная система

#0
8:18, 10 апр 2010

Значит бился я пару дней,
читал гугл, эксперементировал,
но кроме мега кустарного work
around ничего не нашёл.

Спрашиваю прямо:
Что мне сотворить с ProjectionMatrix,
ViewMatrix или WorldMatrix такое, чтобы
работать как и обычно, но дабы ось Z направлена в верх.
т.к писать везде:
D3DXVECTOR3  outVec( inVec.y, inVec.z, inVec.x );
но это пол беды, сюда прибавляем
неверные анимации из неверно прочитанных кватернионов,
неверный порядок перемножения углов эйлера
неверное чтение из VB...

Махинации с довращением матриц / кватернионов, свопом координат
векторов и прочего не канает...

В общем у меня координатная система как в id и valve,
как подружить с ней DX ?

как работают, и как конвертить RH -> LH и обратно уже разобрал по косточкам,
т.е OGL->DX визуализаторы переключать легко,
а что делать с основными матрицами ?

#1
9:31, 10 апр 2010

домножить на  матрицу, диагональ которой состоит из единиц, кроме Z, где стоит минус единица

#2
9:47, 10 апр 2010

Домножить что?
Если ты про матрицу вида, то
до или после того как применяются
вращение и перемещение?
Сейчас сварганил после всех операций,
матрицу вида домножить вот так:

  D3DXMatrixMultiply(&matView, &matView, 
    &D3DXMATRIX( 0, 0, 1, 0,
                 1, 0, 0, 0,
                 0, 1, 0, 0,
                 0, 0, 0, 1 ) );

После чего, вроде даже начинает работать,
но вот с вращениями камеры косяк,
может я где-то ошибся?

#3
14:30, 10 апр 2010

Lolmen
> Сейчас сварганил после всех операций,
> матрицу вида домножить вот так:

это что, похоже на диагонально-единичную с минусом в столбце-Z?

#4
14:38, 10 апр 2010

В чём смысл менять направление оси Z, если надо поменять местами Y и Z?

[ 1 0 0 0 ]
[ 0 0 1 0 ]
[ 0 -1 0 0 ]
[ 0 0 0 1 ]

Если Y из глубины.

Что не так с вращениями? В каком порядке перемножаются матрицы?

#5
14:42, 10 апр 2010

Lolmen
http://www.gamedev.ru/community/toolcorner/articles/?id=5
вот тут написано как переводить матрицы из одной системы координат в другую

#6
14:53, 10 апр 2010

2 keltar
в вывороте faces на изнанку...

2 Kloun
Уже почитал,
так собственно домножать на такую вот доворачивающую матрицу
нужно только матрицу вида?
после всех преобразований?

2 All
Сча на работе, потестить не получиться...

#7
14:57, 10 апр 2010

keltar
> В чём смысл менять направление оси Z, если надо поменять местами Y и Z?

в том, что топикстартер просил поменять Z, а не XY

#8
15:19, 10 апр 2010

orly?
> outVec( inVec.y, inVec.z, inVec.x );

> но дабы ось Z направлена в верх

> как конвертить RH -> LH и обратно уже разобрал

Ни о чём не говорит?

Lolmen
Направление обхода меняется, если у меня не склероз. glFrontFace(GL_CW).

#9
17:06, 10 апр 2010

keltar
Ну твой предыдущий пост True для GL с RH,
и false for DX :)

#10
23:27, 11 апр 2010

И так, итог, работает всё отлично, в частности визуализация:
+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 );
    
}

Глазик от всего этого замылился
уже, на отказ не видит,
где я мог затутить неподецки? :)

ПрограммированиеФорумГрафика

Тема в архиве.