kostenloser Webspace werbefrei: lima-city


OpenGL - Maus Position im Koordinatensystem

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Hallo zusammen,

    ich habe ein OpenGL Projekt, bei dem ich mir jetzt erstmal die Mausposition anzeigen lassen möchte. Dafür habe ich in der DisplayManager Klasse erstmal folgenden Callback angelegt:

    glfwSetCursorPosCallback(window, cursorPosCallback = new GLFWCursorPosCallback(){
    	@Override
    	public void invoke(long window, double mx, double my) {
    		mouseX = (float)mx;
    		mouseY = (float)my;
    		data.showMousePosition(mouseX, mouseY);
    	}
    });


    Die Mausposition lasse ich mir dann mit dieser Funktion ausgeben:

    public void showMousePosition(float mx, float my){
    	System.out.println(mx + ", " + my);
    }


    Das klappt auch alles. Allerdings gibt mir das ja die Position der Maus im Fenster an. Also links oben in der Ecke ist (0,0) usw. Wie kann ich jetzt die Mausposition in meinem Koordinatensystem ermitteln? Ich habe nämlich eine Kugel die am Anfang eine feste Position im Koordinatensystem hat. Und diese Kugel soll sich dann später bei einem Mausklick in Richtung der angeklickten Stelle bewegen. Also brauche ich ja die Koordinaten der angeklickten Stelle.

    Ich würde mich über Hilfe freuen.
    Viele Grüße :)
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    Dazu erstellt man eine Transformationsmatrix, die Bildschirm-Koordinaten in Welt-Koordinaten transformiert. Grundsätzlich ist diese Transformationsmatrix nichts anderes, als die Inverse zu deiner »normalen« Transformationsmatrix, die Welt-Koordinaten in Bildschirm-Koordinaten transformiert, und die ist nicht mehr als das Produkt der Projection- und View-Matrix (Annahme: du nutzt keine Model-Matrix, sonst müsstest du die eben auch dazumultiplizieren, natürlich unter Berücksichtigung der Reihenfolge). Eine halbwegs brauchbare Anleitung dazu gibt es hier: *klick*.
  4. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    hackyourlife schrieb:
    Eine halbwegs brauchbare Anleitung dazu gibt es hier: *klick*.


    Ok danke für die Antwort, ich versuche mal die Anleitung Schritt für Schritt durchzugehen:

    1. Projection und View Matrix bekommen:

    Matrix4f projectionMatrix = camera.getProjectionMatrix();
    Matrix4f viewMatrix = camera.getViewMatrix();

    2. Diese multiplizieren:

    Matrix4f projMulView = projectionMatrix.mul(viewMatrix);

    3. Diese Matrix umkehren:

    projMulView.invert();

    4.

    Bis hier sollte ja alles stimmen, aber bei dem 4. Punkt weiß ich jetzt nicht mehr weiter. Wie soll ich zum Beispiel den x und y Wert auf einen Wert zwischen -1 und +1 transformieren? Und was genau kommt dann bei z hin?

    5. Vektor mit Matrix multiplizieren:

    vec4.mul(projMulView);

    6. w Komponent:

    Hab das so gemacht wie er in seinem Code:

    vec4.w = 1.0f / vec4.w;
    vec4.x *= vec4.w;
    vec4.y *= vec4.w;
    vec4.z *= vec4.w;

    ----------------

    Könntest du mal bitte über die einzelnen Punkte drüber gucken und sagen was richtig und was falsch ist und dann noch was ich bei Punkt 4 hinschreiben muss? Würde mich freuen :) Danke für die Hilfe!
  5. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    4) Beispiel: Du hast einen Bildschirm mit Koordinaten von (0|0) bis (640|480). Nach der Transformation muss (-1|-1) den Koordinaten (0|0) entsprechen, und (1|1) den Koordinaten (640|480). Also:
    Formel: p_x = \frac{2 \cdot mouse_x}{width} - 1
    Formel: p_y = \frac{2 \cdot mouse_y}{height} - 1

    Wie du Formel: p_z wählen musst, häng davon ab, was du insgesamt tust. Dieser Wert ist jedenfalls jener Wert, der im Z-Puffer zu finden ist. Nötig ist das, da du von 2D-Koordinaten auf 3D-Koordinaten zurückschließen willst, und dazu fehlt dir sonst Information. Wenn du beispielsweise nur eine 2D-Szene darstellst, und alle Z-Werte nach der Transformation den Wert 0 haben (= »gerade auf die Szene schauen«), dann kannst du fix 0 wählen. Ansonsten musst du wohl den Z-Puffer an den Mauskoordinaten lesen, und diesen Wert für Formel: p_z nutzen. Wie? Siehe Link,
    glReadPixels
    macht das möglich. In C würde das ca. so aussehen:
    float z = 0.0f;
    
    glReadBuffer(GL_FRONT);
    glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
    
    // z enthält nun die Tiefeninformation


    Ansonsten sieht das, was du tust, ungefähr richtig aus. Es könnte eventuell könnte sein, dass die Reihenfolge der Operanden bei 2) nicht passt, aber das wirst du eh merken. Und was auch noch sein könnte ist, dass du Formel: p_y invertieren musst (also *(-1)), aber auch das wirst du wohl merken.
  6. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Alles klar, danke! Die Richtung stimmt jetzt schonmal mit meinem Koordinatensystem überein. Also wenn ich die Maus nach links bewege, wird der x Wert höher und nach rechts kleiner. Und wenn ich die Maus nach oben bewege wird der y Wert höher und nach unten kleiner. Allerdings stimmen die Werte jetzt noch nicht überein. Hier erstmal der Code den ich jetzt habe:

    public void showMousePosition(float mx, float my){
    	Matrix4f projectionMatrix = camera.getProjectionMatrix();
    	Matrix4f viewMatrix = camera.getViewMatrix();
    	Matrix4f projMulView = viewMatrix.mul(projectionMatrix);
    	projMulView.invert();
    	float px = ((2*mx)/650)-1;
    	float py = ((2*my)/650)-1;
    	Vector4f vec4 = new Vector4f(px, py*(-1), 0.0f, 1.0f);
    	vec4.mul(projMulView);
    	vec4.w = 1.0f / vec4.w;
    	vec4.x *= vec4.w;
    	vec4.y *= vec4.w;
    	vec4.z *= vec4.w;
    	
    	System.out.println(vec4.x + ", " + vec4.y);
    }


    Ich habe jetzt ein Objekt wie folgt platziert:

    Matrix4f mat = new Matrix4f();
    mat.translate(0.0f, -11.0f, 0.1f);
    mat.scale(player.getBreite(), player.getHoehe(), player.getTiefe());
    player.getObjectModel().setModelMatrix(mat);


    Es befindet sich also bei der Koordinate (0/-11). Wenn ich jetzt mit der Maus auf diese Stelle gehe werden folgende Koordinaten ausgegeben: (0 / 2,17)

    Wenn ich mit der Maus zum linken Rand gehe erhöht sich der x Wert auf maximal 0,13. Also der Ursprung ist schonmal richtig, aber wenn ich die Maus weiter nach links bewege stimmts nicht mehr ganz. Der Wert erhöht sich halt nur minimal. Und bei dem y Wert stimmt der Ursprung nicht, also da wo normalerweise -11 sein müsste steht dann 2,17 und auch da erhöht sich der Wert nur minimal.

    Wenn ich die Reihenfolge der Multiplikation bei Schritt 2 änder erhöhen sich die Werte weiter, aber passen immer noch nicht.

    Hast du ne Idee was noch falsch sein könnte?
  7. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!