2010-12-13 3 views
5

Ho un'applicazione con oggetti 3D che risiedono in Viewport3D e voglio che l'utente sia in grado di selezionarli trascinando un rettangolo sullo schermo.hit test rettangolo wpf3d

Ho provato ad applicare GeometryHitTestParameters (con geometria del rettangolo) su Viewport3D per ottenere i risultati, ma ottengo un'eccezione che mi dice che non è supportato con Viewport3D. Sono supportati solo PointHitTestParameters.

Qualcuno conosce un modo elegante per farlo, ad eccezione di calcolarlo da solo (ad esempio, proiettando tutti gli oggetti 3D in 2D e facendo intersezioni geometriche manuali con un rettangolo)?

+0

Hai provato l'approccio da questo link? http://blogs.msdn.com/b/wpf3d/archive/2009/05/18/3d-hit-testing.aspx –

+0

Naturalmente. Questo è l'approccio noto per hit-test point/ray. Sto cercando test per colpire il rettangolo. Non è una parte integrata del framework, ma forse qualcuno sa come posso usare il framework per raggiungere in modo elegante il mio compito. Ad ogni modo, GeometryHitTestParameters non funziona su Viewport3D. Quindi non posso usarlo per il mio hit-test del rettangolo. – Alex

risposta

0

Dubito che ci sia modo migliore di iterazione attraverso punti rettangolo selezionato:

private void view_PreviewMouseDown(object sender, MouseButtonEventArgs e) { 
     const double offset = 3.0; // I will test in a square 7x7 
     var mouse = e.GetPosition(this); 
     var items = new HashSet<Model3D>(); 
     for (double x = mouse.X - offset; x <= mouse.X + offset; x++) 
      for (double y = mouse.Y - offset; y <= mouse.Y + offset; y++) { 
       PointHitTestParameters pointparams = new PointHitTestParameters(new Point(x, y)); 
       Model3D result = null; 
       VisualTreeHelper.HitTest(view, null, rawresult => { 
        var rayResult = rawresult as RayMeshGeometry3DHitTestResult; 
        if (rayResult != null) 
         items.Add(rayResult.ModelHit); 
        return HitTestResultBehavior.Continue; 
       }, pointparams); 
      } 
     // temporary ListBox to show items 
     list.ItemsSource = items.Select(item => item as GeometryModel3D == null ? null : (item as GeometryModel3D).Material as object); 
    } 

Vedi MSDN How to: Hit Test in a Viewport3D

+1

Ovviamente c'è. Ad esempio, calcola manualmente il frustum di visualizzazione utilizzando i parametri della videocamera, quindi attraversa manualmente l'albero visivo ed esegui il test di contenimento modello-contro-tronco. L'alta velocità può essere raggiunta usando i bounding box. Ma questo sta reinventando la ruota. Lo stanno già facendo con i test di successo basati su ray all'interno di WPF. L'unica differenza è che il test di intersezione è il modello di raggio e non il modello di tronco. Non sono stato in grado di trovare un codice funzionante per questo scenario sul Web e ho pensato che qualcuno qui sappia dove posso trovare il codice efficiente che fa il lavoro. – Alex