2 Stimmen

WPF3D Manipulation von Objekten in einer Ebene parallel zur Kamera

Ich mache eine Anwendung in WPF. Ich benutze eine Menge die 3DTools . Ich habe ein Tetraeder und darin einen Würfel. Ich möchte den Würfel in 3D-Richtungen bewegen.

Mein Tetraeder, zentriert in (0,0,0), dreht sich mit einem Trackball (programmatisch habe ich einen transparenten Rahmen über meinem Ansichtsfenster, um die Ereignisse zu erfassen).

Die Benutzer der Anwendung sind der Meinung, dass es natürlicher ist, den Würfel immer in einer 2D-Ebene (parallel zum Bildschirm) zu bewegen. Wenn ich ihn also tiefer in den Bildschirm hineinbewegen möchte, drehe ich den Tetraeder einfach und bewege ihn z. B. in der Y-Achse. Ich denke, das kann eine gute Lösung sein.

Ich habe zwei Probleme, und ich möchte Hilfe, um dann zu lösen: erstens, wenn ich meine Tetraeder (innerhalb der Trackball) der Trackball sieht aus wie bewegen alle Systemkoordinaten. Ich sage das, weil ich Achsen für Debug-Zwecke zeichne, und diese Achsen werden auch gedreht. Aber das ist nicht wahr - sie bewegen sich nur, weil sie Objekte innerhalb des Trackballs sind (richtig?). EDIT Ich glaube, das Koordinatensystem im Trackball ändert sich wirklich. Wenn ich den Würfel in der Y-X-Achse bewege, verhält er sich gut. Aber wenn ich ein wenig drehen, und versuchen, in der Z-Achse zu bewegen, sehe ich es immer größer (näher an der Kamera) und kleiner (weit von der Kamera). =(

Meine Fragen lauten also Wie kann man eine Ebene definieren, die nicht durch den Trackball gedreht werden kann? Für mich sieht die Antwort in etwa so aus: "Ok, definiere es einfach außerhalb des Trackballs", aber wie ich schon sagte (und die 3DTools-Dokumentation sagt), habe ich einen Rand über meinem Viewport... Ich weiß also nicht, wie ich das handhaben soll.

Mein Tetraedron in einer Reihe von ScreenSpaceLines3D. Ich werde den Würfel darin behalten müssen. Meine zweite Frage ist Wie kann ich die Positionen der Scheitelpunkte des Tetraeders verfolgen, wenn er gedreht wird? ? Ich war sehr enttäuscht, als die Eigenschaft Position mir die ursprünglichen Positionen anzeigte und sonst nichts. Sollte ich die Matrixtransformationen beibehalten und dann auf meine Punkte anwenden, wenn ich sie brauche?

Entschuldigung für den langen Text, aber ich steckte wirklich in diesem nicht so sehr Programmierung Fragen. Ich bin in WPF bekannt, ich habe noch einige Mängel der Konzepte.

Vielen Dank im Voraus,

Pedro

5voto

Ich würde dann versuchen, eigene Manipulatoren zu entwickeln (neue Klassen erstellen, die TrackBall Manipulator aus 3DTools ersetzen), um diese Aufgaben zu erfüllen. Zum Beispiel habe ich in der Vergangenheit Zoom/Schwenk, Drehen um ein Ziel, frei drehen, frei verschieben, Objekt drehen, Objekt verschieben usw... alle durch einfache Matrix / Vektor-Manipulationen zu tun.

Für Ihr Beispiel müssen Sie die Normale berechnen, die orthogonal zur Ebene zwischen Kamera->Ziel und dem Weltaufwärtsvektor ist. Dies gibt Ihnen einen Vektor, der "parallel" zur Kamera ist, wie eine lokale X-Achse, wenn Sie in den Bildschirm schauen. Mit Hilfe dieses Vektors können Sie die Bewegung des Würfels in diese Richtung einschränken.

Berechnen Sie dazu den Vektor V von der Kamera zum Ziel. Dies geschieht durch Subtraktion der Objektposition von der Kameraposition. Berechnen Sie dann wie folgt einen Vektor für die seitliche Verschiebung:

Gegeben ist ein Vektor der Kamera zum Ziel, v = xi, yj, zk
Normalisierung des Vektors, v' = xi, yj, zk / sqrt(xi^2 + yj^2 + zk^2)
U = globaler Weltaufwärtsvektor u = 0, 0, 1

Dann können wir R = Horizontalvektor berechnen, der parallel zur Blickrichtung der Kamera liegt

R = v' ^ U, where ^ is the cross product, given by   
 a ^ b = (a2b3 - a3b2)i + (a3b1 - a1b3)j + (a1b2 - a2b1)k 

So erhalten Sie einen Vektor, der wie folgt aussieht.

Cross Product to find vector parallel to camera direction

Jetzt kennen Sie diesen Vektor R. Wenn Sie die Maus nach links/rechts bewegen, können Sie ihn zum Verschieben des Objekts verwenden. Zum Beispiel, in Pseudocode:

// Pseudocode
onMouseMove()
{
    // Using calculation for R vector above
    Vector r = calulateVector();

    // Assuming passed in the number of points to translate 
    // (or some derivative of mousemove)
    let int pts = mousePointsMovedLeftOrRight;

    // Perform a translate in direction of R
    Vector targetPosition = TargetObject.PositionVector;
    targetPosition.X += r.X * pts;
    targetPosition.Y += r.Y * pts;
    targetPosition.Z += r.Z * pts;
}

Ich habe einen Code auf meinem Laptop zu Hause, der das kann (es ist OpenGL, aber das gleiche Prinzip - bietet verschiedene Manipulationen von Objekten und Kamera im 3D-Raum). Bitte zögern Sie nicht, mich zu kontaktieren/kommentieren, wenn Sie mehr wissen wollen.

Mit freundlichen Grüßen,

1voto

Kendall Frey Punkte 41152

Ich habe etwas Ähnliches ohne einen Trackball gemacht. Ich habe nur das MouseMove-Ereignis verwendet, um die Kamera zu bewegen und auszurichten, aber es wäre genauso gut möglich, ein Objekt zu bewegen. Ich habe noch den Code, wenn Sie es wollen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X