kostenloser Webspace werbefrei: lima-city


OpenGL - Zwei Objekte rotieren lassen

lima-cityForumProgrammiersprachenJava

  1. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Hallo zusammen,

    ich übe gerade ein bisschen mit OpenGL und habe eine Frage. Und zwar habe ich zwei Figuren die sich am Anfang angucken. Diese Figuren sollen sich dann um deren gemeinsamen Mittelpunkt drehen, also quasi als würden sie sich an den Händen anfassen und dann im Kreis drehen. Ich habe es bis jetzt so in der animate() Methode gemacht:

    public void animate(ArrayList<Entity> entities) {
        	// Am Anfang werden die Figuren einmal ausgerichtet, sodass sie sich angucken
        	if(!istGedreht){
        		Matrix4f m1 = new Matrix4f();
        		m1.rotate((float)Math.toRadians(90),0,1,0);
        		m1.translate(0,0,1);
        		entities.get(0).setModelMatrix(m1);
        		
        		Matrix4f m2 = new Matrix4f();
        		m2.rotate((float)Math.toRadians(-90),0,1,0);
        		m2.translate(0,0,1);
        		entities.get(1).setModelMatrix(m2);
        		
        		istGedreht = true;
        	}
    
            // Dann sollen sich die Figuren 0,3 mal pro Sekunde drehen
        	long systemzeit = System.currentTimeMillis();
        	while(System.currentTimeMillis() < systemzeit+(1000/(360/(1/0.3)))){
        		// 0,3 Umdrehungen pro Sekunde
        		// 108° pro 1 Sekunde
        		// 108° pro 1000 Millisekunden
        		// 1° pro 9,259 Millisekunden
        		// Also 9,259 Millisekunden schlafen, dann um 1° drehen
        	}
        	entities.get(0).setModelMatrix(entities.get(0).getModelMatrix().rotateY((float)Math.toRadians(1)));
        	entities.get(1).setModelMatrix(entities.get(1).getModelMatrix().rotateY((float)Math.toRadians(1)));
    }


    So jetzt drehen sich die beiden Figuren aber jeweils nur um ihre eigene Achse, und nicht um die Achse die in der Mitte von beiden ist. Wie bekomme ich das jetzt hin? Und das mit den 0,3 Umdrehungen pro Sekunde ist nur eine Notlösung, ich wusste nicht wie man das sonst machen könnte. Also falls ihr da auch noch was zu wisst würde ich mich da auch ü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.

    Das mit der Zeit löst man anders: du wartest nicht, sondern du zeichnest eben nur einen 1/Zeit-Schritt. Dadurch wird das auf schnellerer Hardware flüssiger, während es auf langsamer Hardware zwar weniger FPS rendert, aber dennoch zur selben Zeit das selbe zeigt (nur halt abgehackter).

    Die Rotation selbst: das hängt mit der Matrizenmultiplikation zusammen, und speziell damit, dass A × B ≠ B × A. Also: zuerst mit der globalen Rotationsmatrix multiplizieren (= die gesamte Szene dreht sich um den Mittelpunkt), und dann jeweils die einzelnen Translationsmatrizen der Objekte anwenden.

    Bemerkung am Rande: du entwickelst offenbar in Java. Das ist zwar durchaus möglich, erzielt aber in Verbindung mit OpenGL sicher nicht die beste Performance. Ich an deiner Stelle würde zu C (oder falls nötig C++) greifen ;-)
  4. Autor dieses Themas

    ultimate-bravery

    ultimate-bravery hat kostenlosen Webspace.

    Ok danke schonmal!

    Also zur Zeit:

    Ich hab jetzt am Anfang eine globale Variable für die zuletzt gespeicherte Systemzeit erstellt die am Anfang 0 ist, also:

    private long letzteSystemzeit = 0;

    Dann am Anfang der animate() Methode hab ich folgendes:

    if(letzteSystemzeit == 0){
        	letzteSystemzeit = System.currentTimeMillis();
    }
    long vergangeneZeit = System.currentTimeMillis() - letzteSystemzeit;

    Also beim ersten mal wird es dann auf die aktuelle Systemzeit gesetzt. In der Variable vergangeneZeit wird dann halt die Differenz gespeichert. Und der der rotate Aufruf sieht dann so aus:

    entities.get(0).setModelMatrix(entities.get(0).getModelMatrix().rotateY((float)Math.toRadians((0.3/1000)*vergangeneZeit)));

    Also er soll sich 0,0003 mal pro Millisekunde drehen und das wird dann halt mit der vergangenen Zeit multipliziert. Am Ende der Methode wird die letzteSystemzeit dann wieder auf System.currentTimeMillis() gesetzt. Das ganze klappt aber irgendwie nicht. Die drehen sich jetzt nicht mehr.


    Dann zur Drehung:

    Muss ich dann also nachdem der Matrix erstellt wurde diese mit der Globalen Rotationsmatrix multiplizieren, also so:

    Matrix4f m1 = new Matrix4f();
    m1.mul(...);
    m1.rotate((float)Math.toRadians(90),0,1,0);
    m1.translate(0,0,1);
    entities.get(0).setModelMatrix(m1);


    Und wie komme ich an die Globale Rotationsmatrix? :)

    EDIT zur Drehung:

    Das was ich da gepostet hab war ja die einmalige Ausrichtung am Anfang. Also da hat das multiplizieren dann ja nichts zu suchen. Also nehme ich an soll vor dem rotateY Aufruf die globale Rotationsmatrix multipliziert werden. Aber wie schon gesagt, ich weiß leider nicht wie ich das machen könnte. Hab auch noch nichts dazu gefunden. Wäre also nett wenn du nochmal genauer helfen könntest :)

    Beitrag zuletzt geändert: 1.11.2015 23:52:53 von ultimate-bravery
  5. hackyourlife

    Moderator Kostenloser Webspace von hackyourlife

    hackyourlife hat kostenlosen Webspace.

    Du berechnest ja Δt korrekt, aber du nutzt es nicht sinnvoll. Δt ist bei dir in der Einheit Millisekunde, also müssen 1000 solche Zeitschritte vergehen, bis 1s vergangen ist. Und was du jetzt machst: damit sich deine Umdrehung in einer Sekunde ereignet, teilst du die Drehung in 1000 Schritte, von denen du so viele ausführst, wie in Δt steht. Also in Pseudocode:
    // Initialisierung
    Rotation = 0° // Rotation der Szene
    ObjektTransformation = Rotate(29°, IrgendEineAchse) × Move(7, 5, 3)
    
    Render() {
    	// Ermitteln der Rotation
    	ermittle Δt
    	Rotation = Rotation + (Δt × 360° / 0.5s) // 1 Umdrehung pro halbe Sekunde
    	Rotation = Begrenze(Rotation, 0°, 360°) // = Rotation modulo 360°
    
    	// Anwenden der Matrix
    	Transformation = RotateYMatrix(Rotation) × ObjektTransformation
    	SetMatrix(Transformation)
    	Render(Objekt)
    }
    Deine Rotationsmatrix ist also das »rotateY«, du speicherst das nicht explizit. Du musst das aber mit deiner Objekt-Transformationsmatrix in der richtigen Reihenfolge multiplizieren … hoffentlich hilft dir der Pseudocode weiter.
  6. 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!