在物体周围移动相机

时间:2014-12-17 08:10:16

标签: silverlight 3d xna silverlight-5.0

我正在尝试将相机设置为在渲染对象周围移动,我正在遵循本指南:

MSDN Guide on Rotating and Moving The Camera

这是我得到的代码:

public partial class MainPage : UserControl
{
    float _cameraRotationRadians = 0.0f;
    Vector3 _cameraPosition = new Vector3(5.0f, 5.0f, 5.0f);
    List<TexturedMesh> _meshes;
    BasicEffect _effect;

public MainPage()
{
    InitializeComponent();
}

private void DrawingSurface_Loaded(object sender, RoutedEventArgs e)
{
    GraphicsDevice device = GraphicsDeviceManager.Current.GraphicsDevice;
    RenderModeReason reason = GraphicsDeviceManager.Current.RenderModeReason;

    _meshes = StreamHelper.ToMesh(device, "capsule.obj");

    _effect = new BasicEffect(GraphicsDeviceManager.Current.GraphicsDevice);
    _effect.TextureEnabled = false;
    _effect.World = Matrix.Identity;
    _effect.View = Matrix.CreateLookAt(_cameraPosition, new Vector3(0.0f, 0.0f, 0.0f), Vector3.Up);
    _effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1.667f, 1.0f, 100.0f);
}

private void DrawingSurface_Draw(object sender, DrawEventArgs e)
{
    GraphicsDevice device = GraphicsDeviceManager.Current.GraphicsDevice;

    device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Microsoft.Xna.Framework.Color(0, 0, 0, 0), 10.0f, 0);
    device.RasterizerState = new RasterizerState()
    {
        CullMode = CullMode.None
    };

    foreach (TexturedMesh mesh in _meshes)
    {
        // Load current vertex buffer
        device.SetVertexBuffer(mesh.VertexBuffer);

        // Apply texture
        if (mesh.Texture != null)
        {
            _effect.Texture = mesh.Texture;
            _effect.TextureEnabled = true;
        }
        else
            _effect.TextureEnabled = false;

        // Draw the mesh
        foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
        {
            pass.Apply();
            device.SamplerStates[0] = SamplerState.LinearClamp;
            device.DrawPrimitives(PrimitiveType.TriangleList, 0, mesh.VertexBuffer.VertexCount / 3);
        }

        // updates camera position
        UpdateCameraPosition();
    }

    e.InvalidateSurface();
}

private void UpdateCameraPosition()
{
    float nearClip = 1.0f;
    float farClip = 2000.0f;

    // set object origin
    Vector3 objectPosition = new Vector3(0, 0, 0);

    // set angle to rotate to
    float cameraDegree = _cameraRotationRadians;
    Matrix rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(cameraDegree));

    // set where camera is looking at
    Vector3 transformedReference = Vector3.Transform(objectPosition, rotationMatrix);
    Vector3 cameraLookAt = _cameraPosition + transformedReference;

    // set view matrix and projection matrix
    _effect.View = Matrix.CreateLookAt(_cameraPosition, objectPosition, Vector3.Up);
    _effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1.667f, nearClip, farClip);
}

private void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    // slider.Value;
    _cameraRotationRadians += (float)slider.Value;
}
}

我有一个滑块控件,可以给出弧度值。当滑块值改变时,我然后为摄像机设置一个新的角度。每次在加载对象后刷新DrawingSurface时都会调用UpdateCameraPosition()。

现在,当我尝试移动滑块时,相机的位置永远不会改变。有人可以帮助并告诉我要解决什么问题,让它围绕整组对象进行解决吗?

2 个答案:

答案 0 :(得分:1)

您基本上是在尝试旋转矢量(0,0,0)。旋转origo中的向量将没有结果。 您应该改变相机位置。

答案 1 :(得分:0)

该指南是如何将相机旋转到位,但听起来您正试图让相机绕物体运行。在这种情况下,不需要transformedReferencecameraLookAt

只需删除这两行,然后围绕_cameraPosition旋转objectPosition,让相机绕对象旋转。

//add this line in place of those two lines:
_cameraPosition = Vector3.Transform(_cameraPosition, rotationMatrix);

//now when you plug _cameraPosition into Matrix.CreateLookAt(), it will offer it a new camera position

从技术上讲,我的代码段会导致_cameraPosition绕世界原点0,0,0进行环绕。这是有效的,因为您的objectPosition恰好位于世界原点,因此相机也在绕objectPosition轨道运行。

但是如果objectPosition一直偏离原点,你仍然可以让相机通过将相机/物体系统平移到原点来运行物体,执行旋转,将它们平移回来。它听起来更容易:

_cameraPosition = Vector3.Transform(_cameraPosition - objectPosition, rotationMatrix) + objectPosition;
//now the camera will orbit the object no matter where in the world the object is.