2016-11-30 1 views
0

Je suis nouveau sur DirectX et Direct3D/2D etc. et je suis actuellement en train de faire une expérience sur la poursuite de la création d'un visualisateur cad pour une machine que nous avons.Caméra 2D panoramique dans SharpDX

J'utilise le contrôle d'ici Direct2dOnWPF pour me permettre d'afficher Direct2D sur la fenêtre WPF en utilisant SharpDX.

Au moment où j'ai le contrôle de travail et son charge un fichier et affiche un dessin.

J'ai maintenant créé une caméra et j'ai implémenté le zoom (dans une certaine mesure) mais mon problème est avec le panoramique. Le problème est que lorsque je fais un panoramique je m'attends à ce que le dessin bouge avec la souris mais ce n'est pas le cas. De petits mouvements, mais de plus grands mouvements font bouger le dessin au-delà du mouvement de la souris. Presque comme plus je déplace la souris en un seul mouvement, plus vite il bouge. Ok un peu de code, le Direct2DControl est basé sur un contrôle Image afin que j'ai accès aux événements de la souris, etc. Voici la partie du code sur le contrôle avec les événements de la souris et une minuterie. J'ai essayé une minuterie pour détecter quand la souris s'est arrêtée car j'ai trouvé que le panoramique ne s'arrêtait pas quand la souris le faisait.

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

et le panoramique dans la classe de caméra en déplaçant la position.

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

et enfin au début du rendu commence mettre à jour le RenderTarget Transformer

target.Transform = cam.GetTransform3x2(); 

Répondre

0

Je crois que vous calculez les coordonnées mal. Tout d'abord, vous devez définir la variable MouseOrigin dans OnLeftMouseButtonDown et ne modifiez pas dans une autre méthode:

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

Et modifier OnMouseMove comme ceci:

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

} 

Les variables DragStarted et CurrentMousePosition ne sont pas nécessaires .

Faites-moi savoir si cela fonctionne.

+0

Merci pour votre inscription. La vitesse de panoramique semble maintenant correcte, mais il semble maintenant y avoir un problème avec la direction dans laquelle elle se déplace. Si je clique et glisse du centre vers le bas à droite, les objets se déplacent vers le haut à gauche. Si je m'arrête puis que je clique et déplace la souris vers le haut, les objets continuent à se déplacer dans leur chemin d'origine en haut à gauche, mais ensuite ils descendent. Si je m'arrête puis clique et fais glisser pour aller à gauche sur l'écran, l'objet retourne en haut à gauche. – Gaz83

+0

Quel est le type de votre variable 'cam'? – user1610015

+0

oh le type cam est juste ma classe Camera. – Gaz83