Странное поведение с матрицами вращения - PullRequest
2 голосов
/ 14 июля 2011

Я пытаюсь сделать космический корабль прямо перед камерой, с моделью, вращающейся вокруг камеры. Это работает, пока игрок только зевает или кренится. Если он делает и то, и другое, он падает. Видео проблемы здесь: http://youtu.be/voKTsdy5TFY

Ниже приведен соответствующий код, отредактированный для ясности:

D3DXMatrixRotationAxis(&playeryaw, &up, yawangle);
D3DXMatrixRotationAxis(&playerpitch, &right, pitchangle);

playerrot =  playeryaw * playerpitch;
D3DXMatrixTranslation(&playertrans, pos.x, pos.y, pos.z);
D3DXMatrixScaling(&playerscale, 0.05 / ((float)i + 1),  0.05 / ((float)i + 1),  0.05 / ((float)i + 1));
playercom = playerscale * playerrot *  playertrans;
device->SetTransform(D3DTS_WORLD, &playercom);
playermesh.render();

РЕДАКТИРОВАТЬ: расширенный код по поручению команды Optillect.

Ответы [ 3 ]

2 голосов
/ 15 июля 2011

Na7coldwater может быть прямо на замке подвеса. Используемые вами два угла, угол рыскания и угол наклона, являются углами Эйлера и, следовательно, подвержены блокировке подвески.

Вы можете избежать блокировки карданного подвеса, используя кватернионы или сохраняя текущее вращение, а затем построить матрицу дельта-вращения и умножить на предыдущую матрицу вращения.

т.е. где вы строите свою матрицу вращения, вы будете хранить дельту из предыдущего вращения, а не абсолютное вращение из исходного состояния модели.

1007 * например *

D3DXMatrixRotationAxis(&playeryaw, &up, yawanglethisframe);
D3DXMatrixRotationAxis(&playerpitch, &right, pitchanglethisframe);

playerrot =  playerrot * (playeryaw * playerpitch); // This line has changed!!
D3DXMatrixTranslation(&playertrans, pos.x, pos.y, pos.z);
D3DXMatrixScaling(&playerscale, 0.05 / ((float)i + 1),  0.05 / ((float)i + 1),  0.05 / ((float)i + 1));
playercom = playerscale * playerrot *  playertrans;
device->SetTransform(D3DTS_WORLD, &playercom);
playermesh.render();

где playerrot хранится от кадра к кадру.

2 голосов
/ 15 июля 2011

Кажется, вы применяете такое же преобразование к космическому кораблю. Вы должны:

  1. Применение матриц вращения к космическому кораблю, затем матрица перевода (положение космического корабля).
  2. Примените эти матрицы для векторов вверх и вправо.
  3. Построить матрицу вида (камеры) на основе векторов вверх и вправо (сначала переведите заднюю часть космического корабля, затем поверните, затем переведите в положение космического корабля)

Примерно так:

    D3DXMatrixRotationAxis(&shipyaw, &up, yawangle);
    D3DXMatrixRotationAxis(&shippitch, &right, pitchangle);
    D3DXMatrixTranslate(&shippos, x, y, z);
    shipmatrix = shippitch * shipyaw * shippos;

    D3DXMatrixTranslate(&viewoffset, 0, 0, -10);
    D3DXMatrixRotationAxis(&viewyaw, &up, -yawangle);
    D3DXMatrixRotationAxis(&viewpitch, &right, -pitchangle);
    D3DXMatrixTranslate(&viewpos, -x, -y, -z);
    viewmatrix = viewoffset * viewpitch * viewyaw * viewpos;
1 голос
/ 15 июля 2011

Это похоже на замок Гимбола , который является известным ограничением использования углов Эйлера для представления трехмерных поворотов.Вы можете использовать матрицы или кватернионы вместо того, чтобы представлять вращение вашего космического корабля.

...