Rotation um den Urpsrung



  • Für jeden Vertex wird folgende Matrix angewendet:

    void NLBatchedSprite::rotate( f32 angle )
    {
    	double rad = std::asin(angle);
    
    	for (int i=0; i<6; i++)
    	{
    		f32 center_x = m_vertices[i].x - m_size.x / 2;
    		f32 center_y = m_vertices[i].y - m_size.y / 2;
    
    		f32 x = ((m_vertices[i].x - center_x) * std::cos(angle)) -  ((m_vertices[i].y - center_y) * std::sin(angle) );
    		f32 y = ((m_vertices[i].x - center_x) * std::sin(angle)) +  ((m_vertices[i].y - center_y) * std::cos(angle) );
    
    		m_vertices[i].x = x - center_x;
    		m_vertices[i].y = y - center_y;
    	}
    }
    

    Leider rotiert das um die Mitte herum, aber dreht sich nicht um sich selbst.
    Kleines Bild zur Veranschaulichung:
    http://www.abload.de/img/rotlgos.jpg

    Die Rote Linie ist das Zentrum.
    Momentan rotiert es wie links, soll aber wie rechts dargestellt rotieren.



  • Eine Standardrotationsmatrix rotiert immer um den Ursprung. Wenn du um einen Anderen Punkt rotieren willst musst du zuerst alles so verschieben dass dieser Punkt im Ursprung liegt, dann rotieren und anschließend wieder zurückverschieben. Diese Operationen kannst du natürlich alle in der Reihenfolge zu einer gemeinsamen Matrix zusammenmultiplizieren.

    In dem Code da oben seh ich jetzt nicht direkt eine Matrix. Aber du könntest auch gleich einfach das Rotationszentrum zuerst subtrahieren, den Punkt rotieren und dann das Rotationszentrum auf den rotierten Punkt wieder draufaddieren...

    EDIT: Ok das tust du irgendwie eh schon, sollten das zum Schluss nur nicht eher + statt - sein?



  • Hmm, also so funktioniert eine Rotation um einen Punkt laut diversen Tutorials ( wie http://olli.informatik.uni-oldenburg.de/Grafiti3/grafiti/flow5/page13.html). Wie ich es gemacht habe. Aber ich will ja dass das Bild selbst rotiert. Weiss nicht wie ich es sonst noch beschreiben soll. Ich hab sämtliche Tutorials gewälzt und Matheseiten aber immer wieder wieder komm ich auf diese Formel zurück. OpenGL Tutorials zu dem Thema nutzen leider nur glRotatef, das hilft mir aber nicht weiter..

    Und ja, es sollte am Ende + heissen, aber dann funktioniert es gar nicht mehr.
    Deswegen frage ich ja hier nach, in der Hoffnung dass jemand so nett ist und Licht in meine Bemühungen wirft >_>.



  • Scorcher24 schrieb:

    [...] aber dann funktioniert es gar nicht mehr.

    heißt genau was?



  • dot schrieb:

    Scorcher24 schrieb:

    [...] aber dann funktioniert es gar nicht mehr.

    heißt genau was?

    Das Sprite läuft aus dem sichtbaren Bereich Richtung links.

    Als Zusatzinformation:
    Die Rotation wird vor der ViewMatrix ausgeführt, vielleicht ist das das Problem.
    Aber wenn ich sämtliche MatrixOperationen auf der CPU ausführe ist das glaube ich nicht so toll.

    Ich transformiere die Vertices nach Position und Rotation, danach schicke ich sie an die GraKa und der Shader multipliziert den Vertex mit der Orthographischen Matrix: glOrto(0,w,h,0,-1,1);
    O,0 ist links oben; w,h ist unten rechts.



  • Also arbeitest du nun doch mit Matritzen!? Dann kannst dus ja genau so machen wie ichs im letzten Post beschrieben hab (Translation * Rotation * Translation)!? Inwiefern "vor der ViewMatrix", in OpenGL gibts in der Fixed Pipeline nur eine ModelView Matrix!? Stimmt die Multiplikationsreihenfolge von Model und View?



  • Ich benutze nicht die Fixed Pipeline sondern die Programmable.
    Sprich, OpenGL3 core.
    Ich denke ich muss dann alles auf der CPU machen an Tranformationen bevor ich die Vertices an die GPU sende.
    Ich verwende für Matrizen und Vevtoren glm, das wurde gegen den Spec von GLSL geschrieben.
    Nur leider ist die Doku nicht sehr gut, es steht kaum was dabei was die Funktionen machen. Bzw keine Details.
    Hier gibts einige Beispiele: http://glm.g-truc.net/code.html

    Wenn ich anfange für jedes Objekt eigene Matrizen zu haben, kann ich nix mehr batchen, weil ich vor jedem DrawCall die Matrix für das Objekt senden müsste. Oder ich schick sie mit an die GraKa in den VRAM per VBO. Das wäre aber auch overkill oder nicht?



  • Scorcher24 schrieb:

    Wenn ich anfange für jedes Objekt eigene Matrizen zu haben, kann ich nix mehr batchen, weil ich vor jedem DrawCall die Matrix für das Objekt senden müsste. Oder ich schick sie mit an die GraKa in den VRAM per VBO. Das wäre aber auch overkill oder nicht?

    Ok wenn du batchen willst dann musst du natürlich auf der CPU Transformieren, außer du verwendest Hardware Instancing...



  • Also in der Doku zu glRotatef steht:

    The current matrix (see glMatrixMode) is multiplied by a rotation
    matrix with the product
    replacing the current matrix, as if glMultMatrix were called
    with the following matrix as its argument:

    Nur, es gibt ja keine "current matrix" mehr, bzw die einzige die angewendet wird ist die Projektions-Matrix, aber die wird im Shader angewendet.
    Ich bin am Ende mit meinem Latein. Ich hab mehrere Versuche angewendet mit glm und deren Rotationsfunktionen aber ich komm nicht dahinter. Und überall wo man fragt herrscht betretenes Schweigen zu dem Thema.
    Kann man nicht mehr batchen wenn man rotiert? Muss man das dann alles einzeln zeichnen? Soll ich die Matrizen als VBO Attribut senden?
    Ich bitte euch um weitere Tipps wie ich vorgehen soll... man fühlt sich ja geradezu als hätte man nach Staatsgeheimnissen gefragt so wie sich zu dem Thema ausgeschwiegen wird.Und damit meine ich nicht hier^^.

    http://glm.g-truc.net/api-0.9.1/a00158.html

    Das hier sind die Matrizen die man nutzen kann von GLM.
    Nur, wenn ich die Rotationsmatrix habe, wie wird die korrekt auf meine Vertices angewendet, damit die Berechnung stimmt?

    http://glm.g-truc.net/html/a00192.html

    Die hier hab ich ausprobiert, die rotieren so wie im Bild in Figur A. Also das Objekt um einen Punkt. Aber ich will ja das Objekt rotieren.



  • Scorcher24 schrieb:

    Nur, es gibt ja keine "current matrix" mehr, bzw die einzige die angewendet wird ist die Projektions-Matrix, aber die wird im Shader angewendet

    Ja klar, den Matrix Stack kannst du vergessen. Aber du hast ja offenbar eh schon eine Mathelibrary, was genau ist denn jetzt das Problem? Zeig vielleicht mal wie genau dus versucht hast...



  • f32 center_x = m_vertices[i].x - m_size.x / 2;
    f32 x = ((m_vertices[i].x - center_x) * std::cos(angle)) -  ...
    

    Ist da nicht ein Logikfehler? Wenn du center_x mal einsetzt, hebt sich m_vertices[i].x doch komplett auf und übrig bleibt nur m_size.x / 2 , oder übersehe ich da etwas?



  • void NLSprite::rotate( f32 angle )
    {
    	glm::vec3 half = glm::vec3(m_position.x + m_size.x / 2, m_position.y + m_size.y / 2, m_position.z);
    	glm::mat4 rotation = glm::rotate(translation, angle, glm::vec3(0,0,1)); // rotate about z axis	
    
    	for ( int i=0; i<6; i++ )
    	{
    		glm::vec4 transformed = rotation * glm::vec4(m_vbo.m_vertices[i].x - half.x, m_vbo.m_vertices[i].y - half.y, 0, 1.0f);
    		m_vbo.m_vertices[i].x = transformed.x;
    		m_vbo.m_vertices[i].y = transformed.y;
    	}
    	m_vbo.updateVBO();
    }
    

    Funktioniert endlich 😃 🕶


Log in to reply