【问题标题】:2D Camera panning in SharpDXSharpDX 中的 2D 相机平移
【发布时间】:2016-11-30 11:13:22
【问题描述】:

我是 DirectX 和 Direct3D/2D 等的新手,目前正在试验是否要为我们拥有的机器制作 cad 查看器。

我正在使用来自这里的控件Direct2dOnWPF 使我能够使用 SharpDX 在 WPF 窗口中显示 Direct2D。

目前我的控件正在工作,它会加载一个文件并显示一个绘图。

我现在已经创建了一个相机,并且我已经实现了缩放(在一定程度上),但我的问题是平移。问题是,在平移时,我希望绘图随鼠标移动,但事实并非如此。它会做一些小动作,但较大的动作会导致绘图移动到鼠标移动之外。几乎就像我一次移动鼠标越远,它移动得越快。

好的,一些代码,Direct2DControl 基于图像控件,所以我可以访问鼠标事件等。这里是一些关于鼠标事件和计时器的控件的代码。我尝试了一个计时器来检测鼠标何时停止,因为我发现当鼠标停止时平移不会停止。

// 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();

【问题讨论】:

    标签: c# wpf direct2d sharpdx


    【解决方案1】:

    我相信你计算的坐标是错误的。首先,您需要在 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 变量。

    让我知道它是否有效。

    【讨论】:

    • 谢谢。平移速度现在看起来是正确的,但现在它的移动方向似乎存在问题。如果我单击并从中心拖动到右下角,对象会向上移动到左上角。如果我然后停止然后单击并拖动并向上移动鼠标,则对象继续沿其原始路径移动到左上角,但随后向下移动。如果我然后停下来,然后单击并拖动以在屏幕上向左移动,则对象将返回到左上角。
    • cam 变量的类型是什么?
    • 哦,cam 类型只是我的 Camera 类。
    • 嗯抱歉不知道还有什么问题
    • 我让它工作了,我改变了这个 'cam.MoveCamera(cam.ScreenToWorld(new Vector2(x, y)));'到这个 'cam.MoveCamera(cam.ScreenToWorld(new Vector2(-x, -y)));'让一切朝着正确的方向发展。在该行下方和之前tmr.Stop' I reset the mouse origin like this. MouseOrigin = e.GetPosition(this);. Finally, I removed your 2 lines in OnMouseLeftButtonDown` 用于设置鼠标原点的 X 和 Y 与相机位置。工作完美。
    猜你喜欢
    • 2019-10-08
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2016-04-09
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多