XNA Quaternion.createFromAxisAngle

Я пишу программу симулятора полета (похожую на Star fox 64) в XNA, и у меня возникла проблема с моими вращениями. Моя идея состоит в том, чтобы иметь вектор скорости и вектор положения. Элементы управления, которые я разрешаю, делают так, что углы Эйлера могут вызывать проблемы, поэтому я хочу использовать кватернионы.

Я еще не очень хорошо знаком с визуализацией графики, но я подумал, что могу использовать Quaternion.createFromAxisAngle(vector, roll) (roll - это вращение вокруг моего вектора скорости), но он работает неправильно. В основном всякий раз, когда я пытаюсь повернуть тангаж или рыскание, ничего не происходит. Когда я катаюсь, это работает, но не так, как я ожидал. Является ли это правильным использованием метода createFromAxisAngle? Спасибо.

Вот код позиции обновления для моего корабля:

    public override void UpdatePositions()
    {
        float sinRoll = (float)Math.Sin(roll);
        float cosRoll = (float)Math.Cos(roll);
        float sinPitch = (float)Math.Sin(pitch);
        float cosPitch = (float)Math.Cos(pitch);
        float sinYaw = (float)Math.Sin(yaw);
        float cosYaw = (float)Math.Cos(yaw);

        m_Velocity.X = (sinRoll * sinPitch - sinRoll * sinYaw * cosPitch - sinYaw * cosPitch);
        m_Velocity.Y = sinPitch * cosRoll;
        m_Velocity.Z = (sinRoll * sinPitch + sinRoll * cosYaw * cosPitch + cosYaw * cosPitch);
        if (m_Velocity.X == 0 && m_Velocity.Y == 0 && m_Velocity.Z == 0)
            m_Velocity = new Vector3(0f,0f,1f);
        m_Rotation = new Vector3((float)pitch, (float)yaw, (float)roll);

        m_Velocity.Normalize();
        //m_QRotation = Quaternion.CreateFromYawPitchRoll((float)yaw,(float)pitch,(float)roll); This line works for the most part but doesn't allow you to pitch up correctly while banking.
        m_QRotation = Quaternion.CreateFromAxisAngle(m_Velocity,(float)roll);
        m_Velocity = Vector3.Multiply(m_Velocity, shipSpeed);

        m_Position += m_Velocity;
    }

person thattolleyguy    schedule 02.08.2011    source источник


Ответы (2)


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

В конце кадра вы отправите в Effect.World матрицу, представляющую мировую ориентацию в пространстве и положение корабля. Прямое свойство этой матрицы оказывается тем же вектором, который вы рассчитали здесь как скорость. Почему бы не сохранить эту матрицу из эффекта. Мир, тогда следующий кадр просто повернет эту матрицу вокруг своего собственного вектора вперед (для вращения) и продвинет ее свойство перевода на основе его собственного (свойство вперед * скорость корабля) и отправит его обратно в эффект для следующего кадра. Это не позволит вам «знать» фактические углы рыскания, тангажа и крена вашего корабля. Но по большей части в 3D-программировании, если вы думаете, что вам нужно знать угол чего-то, вы, вероятно, делаете это неправильно.

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

//class scope field
Matrix orientation = Matrix.Identity;


//in the update
Matrix changesThisFrame = Matrix.Identity;

//for yaw
changesThisFrame *= Matrix.CreatFromAxisAngle(orientation.Up, inputtedYawAmount);//consider tempering the inputted amounts by time since last update.

//for pitch
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Right, inputtedPitchAmount);

//for roll
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Forward, inputtedRollAmount);

orientation *= changesThisFrame;

orientation.Translation += orientation.Forward * shipSpeed;


//then, somewhere in the ship's draw call

effect.World = orientation;
person Steve H    schedule 03.08.2011

Хотите работать с XNA и вращать объекты в 3D? Затем прочитайте это: http://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-from-storing-an-orientation-as-3-angles/

Не могу рекомендовать это достаточно.

person Sebastian Gray    schedule 04.08.2011
comment
Спасибо, Себ, это мой блог! =) Однажды я написал ее и был удивлен, обнаружив, как много людей сочли ее полезной. Мой ответ на вопрос thattolleyguy был мини-версией сути блога. - person Steve H; 04.08.2011