OpenGL und Camera
-
Hallo,
es gibt sehr viele Beispiele wie man in OpenGL eine Kamerasteuerung
herstellt. Ich brauche da eigentlich dringend eine Hilfe.Scenario:
Kamera beobachtet eine Platte aus 45% über Ecke, diese ist drehbar
mit der Tastatur left und reight, sowie beweglich rechts links Key.Drehe ich aber meine Platte wirken danach die Tasten rechts und links nur
noch zu einem kleinen Teil,die meiste Erhöhung von zb. X wandert nun in Y
und umgekehrt.Desswegen wirke ich direkt auf die View und Projektions Matrix ein, indem ich
die Matrixeinträge so manipuliere das bei einer Multiplikation der
korrekte XY-Anteil in die Darstellung integriert wird, das sieht so aus:**LookAt(3, 90, 45, 100);
**void CGLcamera::LookAt(float yaw, float roll, float pitch, float dir) { m_rot.z -= (yaw/10.0f); //Seitenruder m_rot.z m_rot.x -= (roll/10.0f); //Nase = m_rot.x //Querruder = m_rot.y register float fc = -CVertex::Cos((m_rot.x + 90.0f) * PI180); m_cam.x = CVertex::Cos((m_rot.z + 90.0f) * PI180)*fc;//rotate by X+90 with RightLeft m_cam.y = CVertex::Sin((m_rot.z + 90.0f) * PI180)*fc;//rotate by Y+90 with RightLeft m_cam.z = -CVertex::Sin((m_rot.x + 90.0f) * PI180); //rotate by Z+90 with UpDown if(pitch > 0)//xchg xy dir=1,m_cam = CVertex( m_cam.y, -m_cam.x, m_cam.z); else if(pitch < 0)//xchg xy dir=1,m_cam = CVertex( -m_cam.y, m_cam.x, m_cam.z); m_cam *= dir; //direction normal +1 m_pos += m_cam; }
Im Anschluß Integriere ich die berechnete rotation m_cam
in die Matrix:pCam->CGLmatrix::RotXYZ(m_cam);
void CGLmatrix::RotXYZ(CVertex rot) { float c,s; float x0,y0,z0; float x1,y1,z1; float x2,y2,z2; register float *mod=&m_m0[0][0]; //x c=Cos(rot.x*PI180); s=Sin(rot.x*PI180); x0 = mod[0]; y0 = mod[1]; z0 = mod[2]; x1 = mod[4]*c+mod[8]*s; y1 = mod[5]*c+mod[9]*s; z1 = mod[6]*c+mod[10]*s; x2 = mod[4]*-s+mod[8]*c; y2 = mod[5]*-s+mod[9]*c; z2 = mod[6]*-s+mod[10]*c; mod[0] = x0, mod[1] = y0, mod[2] = z0; mod[4] = x1, mod[5] = y1, mod[6] = z1; mod[8] = x2, mod[9] = y2, mod[10] = z2; //y c=Cos(rot.y*PI180); s=Sin(rot.y*PI180); x0 = mod[0]*c+mod[8]*-s; y0 = mod[1]*c+mod[9]*-s; z0 = mod[2]*c+mod[10]*-s; x1 = mod[4]; y1 = mod[5]; z1 = mod[6]; x2 = mod[0]*s+mod[8]*c; y2 = mod[1]*s+mod[9]*c; z2 = mod[2]*s+mod[10]*c; mod[0] = x0, mod[1] = y0, mod[2] = z0; mod[4] = x1, mod[5] = y1, mod[6] = z1; mod[8] = x2, mod[9] = y2, mod[10] = z2; //z c=Cos(rot.z*PI180); s=Sin(rot.z*PI180); x0 = mod[0]*c+mod[4]*s; y0 = mod[1]*c+mod[5]*s; z0 = mod[2]*c+mod[6]*s; x1 = mod[0]*-s+mod[4]*c; y1 = mod[1]*-s+mod[5]*c; z1 = mod[2]*-s+mod[6]*c; x2 = mod[8]; y2 = mod[9]; z2 = mod[10]; mod[0] = x0, mod[1] = y0, mod[2] = z0; mod[4] = x1, mod[5] = y1, mod[6] = z1; mod[8] = x2, mod[9] = y2, mod[10] = z2; }
Dann translatiere ich die neue Position der Kamera m_pos separat:
pCam->CGLmatrix::Translate(m_pos);
//Move matrix by Vector-direction multiply a point with a matrix void CGLmatrix::Translate(const CVertex pos) { register float *mod=&m_m0[0][0]; mod[12] = mod[0]*pos.x+mod[4]*pos.y+mod[8]*pos.z+mod[12]; mod[13] = mod[1]*pos.x+mod[5]*pos.y+mod[9]*pos.z+mod[13]; mod[14] = mod[2]*pos.x+mod[6]*pos.y+mod[10]*pos.z+mod[14]; mod[15] = mod[3]*pos.x+mod[7]*pos.y+mod[11]*pos.z+mod[15]; }
Und aktiviere die neue Matrix in OpenGL mit:
**glLoadMatrixf(&CGLmatrix::m_m0[0][0]);
**Das Problem ist bei meiner Ansteuerung,die einer 3D Egoperspektive entspricht,
das dort nur noch wirkt : "gehe n vorwärts mit Winkel a°"Also: yaw roll pitch force und einen (rl-offset).
Das eigens hergestellte LookAt funktiniert in einem Egoshooter besser.
Wie das glLookAt von OpenGL wirkt bleibt für mich ein Mysterium da ich
in OpenGL Y gegen Z vertauschte. Ich benötige geistig das rechthand Koordinatensystem.Frage a)
Wie kann ich am besten eine Tastaturansteuerung herstellen, die aus
rechts und links up und down eine yaw roll pitch -Ansteuerung für eine Egoperspektiven generiert?*Irgendwie gefällt mir nicht die Tastatur eingaben in in eine Flugzeugsteuerung umzurechnen nur um meine Scene immer gleichnamig
bewegen zu können.
*Ich möchte gerne direkt meine Tastatur so in die Matrix integrieren das rechts "immer" rechts bleibt,egal wie die Rotation der Scene ist.
Frage b)
Hat jemand einen anderen Matrixintegrations -Vorschlag der für die einfache
Aufgabe besser geeignet ist ?**Video zum bisherigen: http://youtu.be/qfuSzISu0ig
**
Gruß
Karsten
-
oben links auf "OpenGL" klicken und "camera2" auswählen.
Tutorial "Advanced camera" ansehen.
-
Hallo,
danke für deine Antwort, das ist eine nette sammlung examples dort
ich glaube diese seite habe ich so vor 10 Jahren schon mal besucht
sie scheint unverändert, was mich freut.Die Examples lösen mein Problem nicht, inzwischen sehe ich das Problem so:
Stellt man das globale Koordinatensystem auf eine Betrachtungsrichtung ein
(es gibt ja keine kamera in dem Sinne) betrachtet man zb ein ein Objekt von
oben.Es ist einfach dieses durch verschieben des globalen Koordinaten systems zu bewegen.
Dreht man aber das Objekt zB 45° kann man nicht mehr mit der taste rechts links erwarten,das sich das Objekt weiterhin auf diesem Vektor verscheibt sondern das passiert entlang seines gedrehten koordinaten systems also ein ein bischen X und ein bissel Y, es gild also jetzt mit Sin und Cos genau die fehlenden bestandteile zur Bewegung wieder hinzuzu rechnen.
Ich habe für das Objekt eine zweite transaltionsmatrix integriert, nun fährt das Objekt wie in einem Spiel unter der eingestellten "Kamera" hindurch.
Man braucht also mehrere translationen.
Dennoch muss eine translation in einer Achse erneut mit sin/cos korrigiert werden, also bewege ich das globale achsensystem, rotiere aber nur das
lokale, möglich durch die multiplikation beider matritzen.glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); CGLcamera *pCam(GetCam()); CVertex pos3d,pos(pCam->GetPos()),dir(pCam->GetRot()); //global translation pCam->LoadIdentity(); pCam->CGLmatrix::RotXYZ(-dir); pCam->CGLmatrix::Translate(-pos); pCam->SetActiv(); //local translation m_terrain.LoadIdentity(); m_terrain.RotXYZ(-m_terrain.m_rot); m_terrain.Translate(-m_terrain.m_pos); pCam->Mult(m_terrain.GetPtr()); pCam->SetActiv(); m_terrain.RenderGrid(&m_font); glEnable(GL_LIGHTING); m_light.Update((CGLfrustum *)pCam); m_terrain.Render(&m_font); glDisable(GL_LIGHTING);
Ich würde nun gerne eine logische Steuerung abbilden, im Moment
ist aber die globale Ansicht und die lokale Ansicht vermischt,
wie stellt man das am besten sterungsseitig dar ? Schließlich gibt es
ja nun quasi zwei mögliche Manipolatoren oder zwei Kameras Lokal und GlobalGrüße und Erfolg
K.