Объект не движется в направлении, к которому он обращен, если вращение не составляет 0 или 180 градусов - PullRequest
0 голосов
/ 08 марта 2012

Как видно из заголовка, объект не движется правильно, если смотреть в любом направлении, которое не равно 0 или 180 градусам.Это в трехмерном пространстве, но вращение происходит только на 1 ось (вверх), поэтому объект поворачивается влево и вправо.Вот диаграмма рисования, чтобы помочь визуализировать проблему: http://dl.dropbox.com/u/60309894/rotationissue.png Удерживая правую кнопку мыши нажатой, объект вращается в зависимости от положения x дельта мыши.Вот код:

// Check & calculate rotation.
if (mouse->ButtonIsDown(NiInputMouse::NIM_RIGHT))
{
    int iDeltaX = 0, iDeltaY = 0, iDeltaZ = 0;
    mouse->GetPositionDelta(iDeltaX,iDeltaY,iDeltaZ);
    if (iDeltaX != 0)
    {
        NiMatrix3 mMat;
        mMat.MakeRotation(iDeltaX / 100.0f,NiPoint3::UNIT_Z);
        SetRotate(  GetRotate() * mMat  );
    }
}

// Check & calculate movement.
m_vVelocity = NiPoint3::ZERO;
if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_W) == true)
    m_vVelocity.y++;
if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_S) == true)
    m_vVelocity.y-- ;
if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_A) == true)
    m_vVelocity.x--;
if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_D) == true)
    m_vVelocity.x++;
m_vVelocity.Unitize();

// Move the object.
m_spNode->SetTranslate(GetTranslate() + m_vVelocity * GetRotate() * m_fSpeed * dt );

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Предполагая, что X в левом и правом углу на примере изображения выглядит так, будто ваша x-скорость отрицается.Если это так, то изменение направления влево и вправо или отрицание x-скорости должно исправить это:

if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_A) == true)
    m_vVelocity.x++;
if ( keyboard->KeyIsDown(NiInputKeyboard::KEY_D) == true)
    m_vVelocity.x--;

Если предположить, что z находится вне монитора, это будет соответствовать левой системе координатпо сравнению с правшей в исходном коде.

0 голосов
/ 08 марта 2012

Полагаю, GetRotate() возвращает двумерный вектор (или 3D, который на самом деле не имеет значения, если z не имеет значения), представляющий компоненты x и y вращения. Если это так, вам, возможно, понадобится другой подход при настройке перевода Это связано с тем, что m_vVelocity кажется локальным по отношению к объекту (то есть положительное значение y вперед, но зависит от вращения объекта).

Вам могут помочь:

Умножить GetRotate() на m_vVelocity.y

Затем получите нормаль к вектору, возвращаемому GetRotate(). Умножьте этот вектор на m_vVelocity.x.

Добавьте эти два вектора вместе, чтобы получить окончательный относительный вектор перевода. Итак, теперь вы получаете что-то вроде следующего:

// Move the object.
Vector2f forwardVec = GetRotate() * m_vVelocity.y;
Vector2f sideVec    = GetRotate().GetNormal() * m_vVelocity.x;
// Obviously above you need a real method to get the normal of GetRotate,
// I used a "pseudo" method.
m_spNode->SetTranslate(GetTranslate() + forwardVec + sideVec );

РЕДАКТИРОВАТЬ: имейте в виду, что метод поиска векторной нормали отличается от 2D-пространства к 3D-пространству (Нет единой определенной нормали для одного вектора в 3D-пространстве, но в 2D-пространстве я использовал 2D-вектор в пример выше по этой причине)

...