Вращение трехмерного объекта вокруг своей оси в противоположность мировой оси - XNA - PullRequest
1 голос
/ 20 июня 2010

Привет всем, я работал над этим небольшим проектом в XNA, цель довольно проста, у меня есть 3D-модель, которая появляется где-то на экране, объект должен вращаться вокруг своей оси y,

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

"некоторые" больше деталей

Моя архитектура такая, у меня есть 3 модели (они принимают Game,Position, Size @ их ctor)

private void initDradles()
    {
        m_Dradles[0] = new DradlePositionColor(this, new Vector3(15, 0, 0), 8);
        m_Dradles[1] = new DradlePositionColor(this, new Vector3(0, 0, 0), 8);
        m_Dradles[2] = new DradlePositionColor(this, new Vector3(-15, 0, 0), 8);
        this.Components.Add(m_Dradles[0]);
        this.Components.Add(m_Dradles[1]);
        this.Components.Add(m_Dradles[2]);
    }

эти модели сначала появляются на экране, как показано ниже на изображении 1

, все они используют один и тот же шейдер BasicEffect, но с другой мировой матрицей

Создание базового эффекта и присвоение моделям

protected override void Initialize()
    {
        float k_NearPlaneDistance = 0.5f;
        float k_FarPlaneDistance = 1000.0f;
        float k_ViewAngle = MathHelper.PiOver4;

        // we are storing the field-of-view data in a matrix:
        m_ProjectionFieldOfView = Matrix.CreatePerspectiveFieldOfView(
            k_ViewAngle,
            GraphicsDevice.Viewport.AspectRatio,
            k_NearPlaneDistance,
            k_FarPlaneDistance);

        // we want to shoot the center of the world:
        Vector3 targetPosition = new Vector3(0, 0, 0);//Vector3.Zero;
        // we are standing 100 units in front of our target:
        Vector3 pointOfViewPosition = new Vector3(0, 0, 130);
        // we are not standing on our head:
        Vector3 pointOfViewUpDirection = new Vector3(0, 1, 0);

        // we are storing the point-of-view data in a matrix:
        m_PointOfView = Matrix.CreateLookAt(
            pointOfViewPosition, targetPosition, pointOfViewUpDirection);

        base.Initialize();
    }

    protected override void LoadContent()
    {
        // we are working with the out-of-the box shader that comes with XNA:
        m_BasicEffect = new BasicEffect(this.GraphicsDevice, null);
        m_BasicEffect.View = m_PointOfView;
        m_BasicEffect.Projection = m_ProjectionFieldOfView;
        m_BasicEffect.VertexColorEnabled = true;

        // we are working with colored vertices
        GraphicsDevice.VertexDeclaration = new VertexDeclaration(
            GraphicsDevice, VertexPositionColor.VertexElements);

        // we did not use certain clockwise ordering in our vertex buffer
        // and we don't want antthing to be culled away..
        this.GraphicsDevice.RenderState.CullMode = CullMode.None;

        foreach (var dradle in m_Dradles)
        {
            dradle.BasicEffect = m_BasicEffect;
        }

        base.LoadContent();
    }

В каждой модели есть этот код в методе обновления:

private void BuildWorldMatrix()
    {
        m_WorldMatrix = Matrix.Identity;
        m_WorldMatrix *= Matrix.CreateScale(m_Scales);
        m_WorldMatrix *= Matrix.CreateRotationX(m_Rotations.X);
        m_WorldMatrix *= Matrix.CreateRotationY(m_Rotations.Y);
        m_WorldMatrix *= Matrix.CreateRotationZ(m_Rotations.Z);
        m_WorldMatrix *= Matrix.CreateTranslation(m_Position);
            ///*I*/ Matrix.Identity *
            ///*S*/ Matrix.CreateScale(m_Scales) *
            ///*R*/ Matrix.CreateRotationX(m_Rotations.X) *
            //        Matrix.CreateRotationY(m_Rotations.Y) *
            //        Matrix.CreateRotationZ(m_Rotations.Z) *
            ///* No Orbit */
            ///*T*/ Matrix.CreateTranslation(m_Position);
    }

    public override void Update(GameTime gameTime)
    {
        m_Rotations.Y += (float)gameTime.ElapsedGameTime.TotalSeconds;
        BuildWorldMatrix();

        base.Update(gameTime);
    }

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

public override void Draw(GameTime gameTime)
    {
        m_BasicEffect.World = m_WorldMatrix;
        m_BasicEffect.Begin();
        foreach (EffectPass pass in m_BasicEffect.CurrentTechnique.Passes)
        {
            pass.Begin();
            Render();
            pass.End();
        }
        m_BasicEffect.End();

        base.Draw(gameTime);
    }

    public override void Render()
    {
        renderVerticesBox(m_BodyVertices);
        renderVerticesBox(m_HandleVertices);
        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
            PrimitiveType.TriangleFan, m_PyramidVertices, 0, 4);
    }

    private void renderVerticesBox(VertexPositionColor[] m_Vertices)
    {
        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
            PrimitiveType.TriangleStrip, m_Vertices, 0, 8);

        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
            PrimitiveType.TriangleStrip, m_Vertices, 10, 2);

        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
            PrimitiveType.TriangleStrip, m_Vertices, 14, 2);
    }

изображение при повороте альтернативный текст http://www.freeimagehosting.net/uploads/b0aa83d0d6.png

изображение при запуске

альтернативный текст http://www.freeimagehosting.net/uploads/ee9e5c379c.png

1 Ответ

1 голос
/ 20 июня 2010

Я думаю, вам нужно переместить свою линию

m_WorldMatrix *= Matrix.CreateTranslation(m_Position);

до нескольких строк, сделайте это до применения матриц вращения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...