【问题标题】:Rotating 3D object on it's axis as oppose to the world axis - XNA在与世界轴相反的轴上旋转 3D 对象 - XNA
【发布时间】:2010-06-20 19:39:01
【问题描述】:

大家好,我一直在 XNA 中从事这个小项目,目标非常基本 我有一个 3D 模型,它会在屏幕上的某个位置弹出,假设对象在它的 y 轴上旋转,

问题是: 取而代之的是模型围绕自己旋转,并且开始围绕它们自己和屏幕中的 0,0,0 点之间的中点旋转,所以看起来中间模型在正常旋转,而其他 2 个在前面提到的方式(包括下面旋转模型的img)。

“一些”更多细节

我的架构是这样的,我有 3 个模型(他们接受 Game、Position、Size @ their 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);
    }

以及draw方法中的这段代码

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);
    }

旋转时的图像 alt text http://www.freeimagehosting.net/uploads/b0aa83d0d6.png

启动时的图像

alt text http://www.freeimagehosting.net/uploads/ee9e5c379c.png

【问题讨论】:

    标签: c# xna


    【解决方案1】:

    我认为你需要移动你的线路

    m_WorldMatrix *= Matrix.CreateTranslation(m_Position);
    

    向上几行,在应用旋转矩阵之前执行此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-24
      • 2015-07-23
      • 2012-06-22
      • 2013-08-29
      • 1970-01-01
      • 2017-10-26
      • 2016-10-20
      相关资源
      最近更新 更多