SharpDX中的2D相机平移

时间:2016-11-30 11:13:22

标签: c# wpf direct2d sharpdx

我是DirectX和Direct3D / 2D等的新手,目前正在进行一项关于是否为我们拥有的机器制作cad查看器的实验。

我正在使用此处Direct2dOnWPF的控件使我能够使用SharpDX将Direct2D显示在WPF窗口上。

目前我让控件正常工作并加载文件并显示图纸。

我现在已经创建了一个摄像头,我已经实现了缩放(在某种程度上),但我的问题是平移。问题是,当平移时,我希望绘图随鼠标移动,但事实并非如此。它有点小动作,但更大的动作会使绘图移动到鼠标移动之外。几乎就像我在一次移动中移动鼠标一样,它移动得越快。

确定一些代码,Direct2DControl基于Image控件,因此我可以访问鼠标事件等。以下是控件上的一些代码,包括鼠标事件和计时器。我尝试了一个计时器来检测鼠标何时停止,因为我发现当鼠标移动时平移不会停止。

// Timer to detect mouse stop
private Timer tmr;

public Direct2dControl()
   {
        //
        // .... Init stuff
        //

        // Mouse panning

        // get mouse position
        MouseOrigin = CurrentMousePosition = new Point(0, 0);

        tmr = new Timer { Interval = 50 };
        tmr.Elapsed += Tmr_Elapsed;
   }

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
   {
        base.OnMouseLeftButtonDown(e);

        if (!DragIsOn)
        {
            DragIsOn = true;
        }
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonUp(e);

        if (DragIsOn)
        {
            DragIsOn = false;
            DragStarted = false;
            MouseOrigin = CurrentMousePosition = e.GetPosition(this);
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        if (!DragIsOn) return;

        MouseMoved = true;

        if (!DragStarted)
        {
            DragStarted = true;
            MouseOrigin = CurrentMousePosition = e.GetPosition(this);

            tmr.Start();
        }
        else
        {
            CurrentMousePosition = e.GetPosition(this);

            var x = (float)(MouseOrigin.X - CurrentMousePosition.X);
            var y = (float) (MouseOrigin.Y - CurrentMousePosition.Y);

            cam.MoveCamera(cam.ScreenToWorld(new Vector2(x, y)));

            tmr.Stop();
            tmr.Start();
        }
    }

private void Tmr_Elapsed(object sender, ElapsedEventArgs e)
    {
        MouseOrigin = CurrentMousePosition;

        tmr.Stop();
        MouseMoved = false;
    }

通过移动位置在相机类中平移。

public void MoveCamera(Vector2 cameraMovement)
    {
        Vector2 newPosition = Position + cameraMovement;

        Position = newPosition;
    }

    public Matrix3x2 GetTransform3x2()
    {
        return TransformMatrix3x2;
    }

    private Matrix3x2 TransformMatrix3x2
    {
        get
        {
            return
                Matrix3x2.Translation(new Vector2(-Position.X, -Position.Y)) *
                Matrix3x2.Rotation(Rotation) *
                Matrix3x2.Scaling(Zoom) *
                Matrix3x2.Translation(new Vector2(Bounds.Width * 0.5f, Bounds.Height * 0.5f));
        }
    }

最后在开始渲染的开始我更新RenderTarget变换

target.Transform = cam.GetTransform3x2();

1 个答案:

答案 0 :(得分:0)

我相信你正在计算错误的坐标。首先,您需要在OnLeftMouseButtonDown中设置MouseOrigin变量,而不是在任何其他方法中修改它:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);

    if (!DragIsOn)
    {
        DragIsOn = true;
        MouseOrigin = e.GetPosition(this);

        // I don't know the type of your cam variable so the following is pseudo code
        MouseOrigin.x -= cam.CurrentPosition.x;
        MouseOrigin.y -= cam.CurrentPosition.y;
    }
}

并像这样修改OnMouseMove:

protected override void OnMouseMove(MouseEventArgs e)
{
    base.OnMouseMove(e);

    if (!DragIsOn) return;

    MouseMoved = true;

    var x = (float)(e.GetPosition(this).x - MouseOrigin.X);
    var y = (float) (e.GetPosition(this).y - MouseOrigin.Y);

    cam.MoveCamera(cam.ScreenToWorld(new Vector2(x, y)));

    tmr.Stop();
    tmr.Start();

}

不需要DragStarted和CurrentMousePosition变量。

让我知道它是否有效。