Wie implementiere ich Translations-, Skalierungs- und Rotations-Gizmos zum Manipulieren der Transformationen von 3D-Objekten?


11

Ich bin gerade dabei, einen grundlegenden 3D-Editor zu entwickeln. Es verwendet OpenGL zum Rendern einer 3D-Welt. Im Moment besteht meine Szene nur aus ein paar Kästchen unterschiedlicher Größe und ich bin in der Phase, in der ich jedes Kästchen auswählen und dann verschieben / skalieren / drehen möchte, um eine beliebige Transformation zu erzielen.

Wie kann ich das Problem lösen, sowohl das Rendern der Gizmos (oder Handles) dieses Tools (oder wie die Leute sie normalerweise nennen) zu implementieren als auch sie auf jeder Achse auszuwählen, um die Änderung in der Transformation mit meiner Maus durchzuführen? Zur Klarheit: Geben Sie hier die Bildbeschreibung ein

Meine bisherigen Untersuchungen haben ergeben, dass der sauberste Ansatz darin besteht, einen achsenausgerichteten Begrenzungsrahmen pro Pfeil im Gizmo und einen weiteren pro Quadrat (diejenigen, die das Objekt in einer Ebene anstatt in einer einzelnen Achse bewegen) zu haben und dann einen Strahl von der Maus zu werfen positionieren und sehen, womit es kollidiert. Aber das ist mir immer noch etwas zu abstrakt. Ich würde mich über weitere Anleitungen zur Funktionsweise dieses Algorithmus freuen (Pseudocode ist mehr als genug).


1
Normalerweise werden Sie mit der Mausposition in die Welt strahlen und sehen, ob Sie ein Gizmo treffen. Sie können das Gizmo auch in einen Bildschirmbereich verwandeln, um dort eine Kollisionserkennung durchzuführen. Normalerweise machen Sie jedoch nur eine Entfernung vom Strahl zum Liniensegment. Die Drehung erfolgt normalerweise als virtueller Trackball. Siehe Melax in Game Programming Gems 1. Die Übersetzung ist so ziemlich ein Punktprodukt, ebenso wie die Skalierung.
RandyGaul

Antworten:


9

Irgendwann in meiner Zeit bei e-on habe ich die Gizmos der Vue- Produktlinie beibehalten .
Ich kann Ihnen sagen, es wird mehrere Tage dauern, Vollzeit.
Wenn Sie keine Bibliothek oder einen super cleveren Weg finden, besteht der klassische Weg darin, die Koordinate der Maus im Fenster abzurufen, wenn Sie darauf klicken. Wenn es sich um eine relative Koordinate zum Ansichtsfenster handelt, können Sie x und y einfach durch Breite und Höhe teilen Holen Sie sich einen Vektor (float 2d) im Bereich [0,1]. subtrahieren (0,5,0,5) davon, um sowohl für x als auch für y in den Bereich [-0,5, 0,5] zu gelangen.
Dann machen Sie einen Strahl aus dieser Koordinate, indem Sie x und y einfach als Strahl x und y verwenden, und Sie setzen z auf die Brennweite. Manchmal ist das Seitenverhältnis bei dieser Operation ein Schmerz im Arsch. Ein bisschen Fummeln und Versuchsfehler werden Sie reparieren.
Dann müssen Sie den Schnittpunkt mit Ihren Gizmos-Elementen überprüfen. Entweder haben Sie ein Netz, das Sie generiert oder in einem Mixer oder einem anderen DCC modelliert haben, oder Netzteile, die sich gegenseitig artikulieren können. Verwenden Sie diese Netzteile einfach als Strahl / Dreieckskreuzungsabfrage.
Oder wenn Sie es haben, Strahl / Zylinder, Strahl / Kugel entsprechend Ihrem Gizmo Aussehen und Teilen.
Sie benötigen Schnittroutinen, die in der Lage sind, eine Transformationsmatrix auf das Primitiv anzuwenden, mit dem sie kollidieren . Sehr wichtig, da Ihr Gizmo mit dem Objekt, das es bewegt, übersetzt wird, sich dreht und mit der Umkehrung des Abstands zur Kamera skaliert, sodass eine feste projizierte Größe auf dem Bildschirm erhalten bleibt.
Dann haben Sie den Interaktionsteil. Am einfachsten ist es, das Delta des Punktes zu nehmen, an dem die Maus zum ersten Mal "Maus nach unten" war, und die aktuelle Position "Mausbewegung" in reinem 2D, und dieses Delta als aktuelle Achsenbewegung zu verwenden im Weltraum, multipliziert mit einigen k, die Sie empirisch entscheiden. Entsprechend Ihren internen Einheiten im Vergleich zum Pixel im Vergleich zum aktuellen
Zoommaßstab usw. Der letzte Schritt besteht einfach darin, die Matrix des Gizmos auf das manipulierte Objekt anzuwenden, damit es diesem folgt.

Ich sage Ihnen, es ist eine ziemliche Reise in die Hölle, um sie umzusetzen, und wenn Sie dies in Ihrer Freizeit tun, rechnen Sie mit mehr als einer Woche. Mehrere Wochen, wenn Sie das Feld vollständig entdecken. Mehr als einen Monat, wenn Ihre Wochenenden mit anderen Aktivitäten beschäftigt sind :)

Ich schlage vor, dass Sie Embree 2.0 von Intel herunterladen, um die Abfrage für die Kreuzung von Strahlen und Dreiecken für Sie durchzuführen, damit Sie sich nicht darum kümmern müssen, dies zu codieren. Oder Sie könnten Code aus dem Mixer gnadenlos kopieren / einfügen und anpassen ... Ich denke, sie sind auf die Apache-Lizenz umgezogen? Sollte legal möglich sein.


1
Vielen Dank für Ihre Antwort. Es ist in der Tat hilfreich. Ich wusste, dass ich nicht verrückt war, als ich mich von einer scheinbar einfachen Aufgabe überwältigt fühlte. Ich unterschätze die Schwierigkeit und stecke tagelang am selben Problem fest. Wenn ich das nächste Mal damit anfange, werde ich sicher einen guten Plan gemacht haben. Danke
Grimshaw

0

Für Manipulator-Übersetzer verwende ich folgenden Algorithmus:

1) Wenn Sie mit der Maus nach unten gehen, müssen Sie überprüfen, ob der Strahl den Pfeil schneidet. Zum Beispiel betrachten wir den X-Pfeil. Wir konstruieren Ray im Weltraum (basierend auf Kamerastumpf und Mausposition). Wir bauen eine Ebene, in der die x-Achse liegt: Ihre Normale ist gleich V cross X cross V, wobei V - Vektor von der Mitte zur Kamera, X - die x-Achse darstellt. Dann schneiden wir den Strahl mit der Ebene und finden daher den Schnittpunkt in Weltkoordinaten. Dann projizieren wir das x-Achsen-Segment und den resultierenden Punkt zurück auf den Bildschirm und ermitteln den Abstand zwischen dem projizierten Segment und dem projizierten Punkt auf dem Bildschirm. Wenn es weniger als ein paar Pixel sind, schneidet die Maus die Achse. Außerdem berechnen wir den Weltraum-Delta-Vektor zwischen dem Zentrum der Auswahl und unserem Schnittpunkt.

Diese Prozedur machen wir für 3 Achsen, also finden wir Abstände zu allen Achsen. Finden Sie den Mindestabstand. Wir haben also herausgefunden, mit welcher Achse sich die Maus schneidet.

2) Wenn Sie die Maus bewegen. Wir wissen, um welche Achse sich das Objekt bewegt (von 1). Wir finden den Weltraumschnittpunkt des Strahls mit der Ebene (wie in 1). Zusätzlich projizieren wir den Schnittpunkt auf die Linie, entlang der sich das Objekt bewegt. endgültige Manipulatorposition = Schnittpunkt + Delta.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.