2017-11-04 10 views
1

Ich möchte einen Würfel mit Schlüsseln drehen. Dies ist ein Teil des Codes. Wenn ich die LINKE Taste drücke, dreht sich der Würfel nach links usw. Mein Ziel ist es, den Würfel rundum zu drehen, also muss ich ihn um x und y drehen, was ein Problem verursacht.Objekt-Rotation mit Tasten

Ich habe mat4 rotation; definiert und verwendet, um eine Drehung zuzuweisen, wenn ich eine Taste gedrückt halte. Wenn ich den Schlüssel halte, dreht er sich, zum Beispiel nach links. Dann lasse ich den Schlüssel los, und das Objekt kehrt in die Ausgangsposition zurück (die Kamera kehrt in die Ausgangsposition zurück, da sich das Objekt nicht bewegt). Ich denke, dass dieses Problem die Linie auto rotateMat = rotation; verursacht, die unterhalb der Schlüsselfunktionen definiert wird. Was mache ich falsch?

mat4 rotation; //global 

    if(keysPressed[GLFW_KEY_LEFT]){ 
       timer -= delta; 
       rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0}); 
    } 

    if(keysPressed[GLFW_KEY_RIGHT]){ 
       timer += delta; 
       rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0}); 
    } 

    if(keysPressed[GLFW_KEY_UP]){ 
       timer += delta; 
       rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0}); 
    } 

    if(keysPressed[GLFW_KEY_DOWN]){ 
       timer -= delta; 
       rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0}); 
    } 

    ... 
    program.setUniform("ModelMatrix", rotation* cubeMat); 
    cube.render(); 

UPDATE:

Also das Problem dieses Problem gelöst wurde, als ich Matrix Variable als globale Variable verwendet, nicht lokal.

+0

Wenn keine Taste gedrückt wird, ist die Drehung eine Einheitsmatrix. Ja, das Überschreiben von rotateMat mit einer Unity-Matrix führt dazu, dass Ihr Cube in seine ursprüngliche Position zurückkehrt. – BDL

+0

@BDL also wie konnte ich 'rotateMat' nicht übersteuern? Ich dachte, wenn ich 'rotation' zu' rotateMat' zuweise, wird es sich an die letzte Position erinnern. – Ady96

+0

Sie können zum Beispiel eine relative Drehung in den ifs berechnen und sie mit Ihrer aktuellen Matrix multiplizieren. – BDL

Antwort

0

Es gibt mehrere Möglichkeiten, wie eine solche Interaktion implementiert werden kann. Eine der leichteren, ist eine relative Verschiebung in jedem Frame statt einem globalen, eines zu erstellen und an die aktuellen Dreh hinzufügen:

Dazu hat man die Summe aller Drehungen in einem globalen varialbe speichern

//Global variable 
mat4 total_rotate; 

und die relative Übersetzung in jedem Frame berechnen:

//In the function 
mat4 rotation; 

if(keysPressed[GLFW_KEY_LEFT]){ 
      rotation = rotate(mat4{}, delta, {0, 1, 0}); 
} 

if(keysPressed[GLFW_KEY_RIGHT]){ 
      rotation = rotate(mat4{}, -delta, {0, 1, 0}); 
} 

if(keysPressed[GLFW_KEY_UP]){ 
      rotation = rotate(mat4{}, delta, {1, 0, 0}); 
} 

if(keysPressed[GLFW_KEY_DOWN]){ 
      rotation = rotate(mat4{}, -delta, {1, 0, 0}); 
} 

total_rotate = total_rotate * rotation; 
... 
program.setUniform("ModelMatrix", total_rotate * cubeMat); 
cube.render(); 

Als Alternative könnten Sie speichern die beiden Drehwinkel statt und berechnen die Matrix in jedem Rahmen:

//Global variables 
float rot_x = 0.0f, rot_y = 0.0f; 

//In every frame  
if(keysPressed[GLFW_KEY_LEFT]){ 
      rot_x += delta; 
} 

if(keysPressed[GLFW_KEY_RIGHT]){ 
      rot_x -= delta; 
} 

//Same for y 

auto rotation = rotate(rotate(mat4{}, rot_y, {0, 1, 0}), rot_x, {1, 0, 0} 
... 
program.setUniform("ModelMatrix", rotation * cubeMat); 
cube.render(); 
+0

Die erste Lösung funktioniert nicht für mich. Es kommt zurück zur Ausgangsposition. – Ady96

+0

Haben Sie 'total_rotate' als globale Variable deklariert? Sofern Sie total_rotate nicht überschreiben oder zurücksetzen, sollte es nicht zurückgehen. – BDL

+0

Es ist in der Funktion onIdle() überschreiben, aber es sollte nicht in es zurückgesetzt werden. Und für die zweite Lösung möchte es sich drehen, aber es blockiert nicht etwas. Es ist also nur ein "Schütteln" in der Ausgangsposition, wenn ich die Taste zum Bewegen drücke. – Ady96