在XNA 4.0中放置立方体+具有相机的问题

时间:2012-09-30 18:30:07

标签: c# 3d xna-4.0

我正在尝试制作一个简单的演示,我在空间中有一个立方体和第一个移动的人物相机。我过去在c ++&中做过类似的事情。 OpenGL的。

我的问题是:

  • 我可以毫无问题地将我的立方体放置在空间的任何位置
  • 我可以创建相机并移动
  • 但是当我同时创建两者时,立方体总是与相机相对位置

我怀疑问题出在世界矩阵上。相机正在操纵矩阵并影响立方体。在OpenGL中,我使用了glPushMatrix和glPopMatrix,因此存储了Matrix而不受影响。

//Draw Cube in openGL
    glPushMatrix();
        glTranslatef(1000,0,1000);
        glRotatef(90,0,1,0);
        DrawCube();
    glPopMatrix();
  • 如何在XNA中实现类似的Push / Pop Matrix功能?

  • 你知道我能看到的任何类似的演示(第一个摄像头+对象)吗?(我正在使用MSDN微软教程,但大多数链接都坏了:-()

你可以看到我到目前为止所尝试的内容。我贴了相关的方法。

    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        float timeDifference = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
        ProcessInput(timeDifference);

        base.Update(gameTime);
    }
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        //Text
        DrawText();

        //CUBE
        // Set the World matrix which defines the position of the cube
        cubeEffect.World = Matrix.CreateTranslation(modelPosition);
        // Set the View matrix which defines the camera and what it's looking at
        cubeEffect.View = Matrix.CreateLookAt(cameraPositionCube, modelPosition, Vector3.Up);
        // Set the Projection matrix which defines how we see the scene (Field of view)
        cubeEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 1000.0f);
        // Enable textures on the Cube Effect. this is necessary to texture the model
        cubeEffect.TextureEnabled = true;
        cubeEffect.Texture = cubeTexture;
        // Enable some pretty lights
        cubeEffect.EnableDefaultLighting();
        // apply the effect and render the cube
        foreach (EffectPass pass in cubeEffect.CurrentTechnique.Passes)
        {
            pass.Apply();
            cubeToDraw.RenderToDevice(GraphicsDevice);
        }

        base.Draw(gameTime);
    }

    private void UpdateViewMatrix()
    {
        Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);

        Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
        Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
        Vector3 cameraFinalTarget = cameraPosition + cameraRotatedTarget;

        Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
        Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);

        viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraFinalTarget, cameraRotatedUpVector);
    }

    private void ProcessInput(float amount)
    {
        MouseState currentMouseState = Mouse.GetState();
        if (currentMouseState != originalMouseState)
        {
            float xDifference = currentMouseState.X - originalMouseState.X;
            float yDifference = currentMouseState.Y - originalMouseState.Y;
            leftrightRot -= rotationSpeed * xDifference * amount;
            updownRot -= rotationSpeed * yDifference * amount;
            Mouse.SetPosition(device.Viewport.Width / 2, device.Viewport.Height / 2);
            UpdateViewMatrix();
        }

        Vector3 moveVector = new Vector3(0, 0, 0);
        KeyboardState keyState = Keyboard.GetState();
        if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
            moveVector += new Vector3(0, 0, -1);
        if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S))
            moveVector += new Vector3(0, 0, 1);
        if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
            moveVector += new Vector3(1, 0, 0);
        if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
            moveVector += new Vector3(-1, 0, 0);
        if (keyState.IsKeyDown(Keys.Q))
            moveVector += new Vector3(0, 1, 0);
        if (keyState.IsKeyDown(Keys.Z))
            moveVector += new Vector3(0, -1, 0);
        AddToCameraPosition(moveVector * amount);
    }

    private void AddToCameraPosition(Vector3 vectorToAdd)
    {
        Matrix cameraRotation = Matrix.CreateRotationX(updownRot) * Matrix.CreateRotationY(leftrightRot);
        Vector3 rotatedVector = Vector3.Transform(vectorToAdd, cameraRotation);
        cameraPosition += moveSpeed * rotatedVector;
        UpdateViewMatrix();
    }

1 个答案:

答案 0 :(得分:1)

您的UpdateViewMatrix()会创建一个从未使用过的矩阵。使用此矩阵作为效果的视图矩阵,而不是在Draw()中创建新矩阵。