XNA Quaternion.createFromAxisAngle - PullRequest
       9

XNA Quaternion.createFromAxisAngle

1 голос
/ 02 августа 2011

Я пишу программу симулятора полета (похожую на 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;
    }

Ответы [ 2 ]

2 голосов
/ 04 августа 2011

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

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

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

//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;
1 голос
/ 04 августа 2011

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

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

...