Ich habe eine perspektivische Projektion. Wenn der Benutzer auf den Bildschirm klickt, möchte ich den Strahl zwischen der nahen und der fernen Ebene berechnen, der vom Mauspunkt aus projiziert wird, damit ich einen Strahlschnittcode mit meiner Welt erstellen kann.
Ich benutze meine eigenen Matrix-, Vektor- und Strahlenklassen und sie funktionieren alle wie erwartet.
Wenn ich jedoch versuche, den Strahl in Weltkoordinaten umzuwandeln, ergibt sich für meinen Abstand immer ein Wert von 0,0,0, und mein Strahl wandert vom Mausklick zur Mitte des Objektraums und nicht durch diesen. (Die x- und y-Koordinaten von nah und fern sind identisch, sie unterscheiden sich nur in den z-Koordinaten, in denen sie negativ sind.)
GLint vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
matrix_t mv, p;
glGetFloatv(GL_MODELVIEW_MATRIX,mv.f);
glGetFloatv(GL_PROJECTION_MATRIX,p.f);
const matrix_t inv = (mv*p).inverse();
const float
unit_x = (2.0f*((float)(x-vp[0])/(vp[2]-vp[0])))-1.0f,
unit_y = 1.0f-(2.0f*((float)(y-vp[1])/(vp[3]-vp[1])));
const vec_t near(vec_t(unit_x,unit_y,-1)*inv);
const vec_t far(vec_t(unit_x,unit_y,1)*inv);
ray = ray_t(near,far-near);
Was habe ich falsch gemacht? (Wie können Sie den Mauszeiger aus der Projektion entfernen?)
Antworten:
Ich musste das kürzlich selbst für eine WebGL-Anwendung lösen. Ich habe den vollständigen Quellcode angehängt, aber falls er nicht von Anfang an funktioniert, hier einige Tipps zum Debuggen:
Um auf einige der obigen Kommentare zu antworten, möchten Sie fast nie die Auswahl-APIs von OpenGL verwenden. Auf diese Weise können Sie vorhandene Elemente auswählen, z. B. wenn Sie ein Menü erstellt haben. In den meisten realen Szenarien wie der Bearbeitung von 3D-Modellen ist dies jedoch nicht möglich. Wo müssen Sie Geometrie als Ergebnis des Klickens hinzufügen.
Hier ist meine Implementierung. Hier ist nichts Magisches los. Nur JavaScript und Googles Closure-Bibliothek.
gluUnProject
Verwendung
quelle
Ich sehe keine Probleme mit Ihrem Code. Also ich habe nur ein paar Vorschläge:
Und versuchen, Matrixmultiplazierung zu ändern
(p*mv).inverse();
. Nur weil glMatrices normalerweise im Speicher transponiert werden. (Dies ist eine große vielleicht, sorry)Ein weiteres Raycasting Beim
Entprojektieren geht es nicht nur darum, wie Sie einen Strahl aus dem Pixel erhalten. Das ist mein Code für raycaster:
Sie können cameraRight, Up und Direction aus der View-Matrix (was vor allem im Shader nützlich ist) abrufen. View-Matrix in opengl
Kommissionierung Farbe
Farbe Kommissionierung ist eine Technik , wo Sie mit einer anderen (fest) Farbe jedes anklickbare Objekt machen und dann den Wert der Farbe bei klickten Punkt lesen. Es hat als GL_SELECTION in opengl funktioniert. Aber es ist jetzt veraltet. Die Farbauswahl ist jedoch einfach als 1 zusätzlicher Renderdurchgang zu codieren.
Verwenden Sie den Framebuffer und rendern Sie die Textur mit der gleichen Auflösung wie die Bildschirmauflösung. Verwenden Sie einen einfachen Shader, der nur die Farbe im Fragment-Shader zurückgibt. Lesen Sie nach "Color Pass" den Wert aus einer Textur-Adressierung mit clickedPoint x und y. Finden Sie ein Objekt mit der Farbe, die Sie lesen. Einfach und ziemlich schnell.
quelle