lings- rechtsbewegen in openGL



  • hallo,
    hab mal wieder ne einfache frage. ich glaub die is so simple dass die nirgens richtig erklärt wird (meine fragen werden nie irgentwo richtig geklärt 😉 😃 )

    also ich will ein 4 eck erstellen un dann mit W A S D da rum laufen können.

    ich benutzt Rotate vor Translate.

    also bei D (rechts) nimmt die winkelgrösse von rotate zu damits einen vorkommt die kamera dreht sich nach links...einfach

    aber bei W un S klappts net
    eigentlich soll man dahin laufen wo man auch hinguckt aber meine 4-eck bewegt sich direkt auf die kamera drauf zu sodass das so aussieht als würde der betrachter sidesteps machen^^.
    bei NEHE gibt es auch sowas, da werden aber berechnungen mit piover180 usw geamcht und nicht wirklich erklärt
    also wie gehts 😉

    thx im voraus



  • bisschen mit trigonometrie, hat nichts mit ogl zu tun 🙂

    Mach die einen Vector wo du gerade bist. Und mach dir einen Vektor in welche Richtung du gerade guckst.

    dann so:

    static float rot = 0;
    
    // ich habs jetzt so verstanden, dass du mit a und d drehen willst und mit w und s 
    // nach vorne und hinten laufen willst, oder?
    
    // Pseudocode:
    Vector3 Position(0,0,0); // deine aktuelle Position
    
    void Move(float PassedSecs)
    {
       if(keydown('a'))
          rot -= 1 * PassedSecs;
       else if(keydown('d'))
          rot += PassedSecs;
    
       Vector3 dir;
       dir.y = 0;
       dir.x = sinf(rot);
       dir.z = cosf(rot);
    
       Position += PassedSecs * dir;
    
       // Kamera auf Position und setzen und in richtung dir gucken lassen.
       SetCamera(Position, dir);
    }
    

    also is jetzt ungetestet, aber so in etwa müsste es funiktionieren



  • das sieht ja schonmal gut aus thx. ich probiers gleich ma aus. aber beim ersten draugucken frage ich mich nurnoch warum die position mit "passedsec "und "dir" malgenommmen wird weil bei einer drehung um die eigene achse bewegt man sich ja nicht. Un 2.:
    (ich kritisier dich nicht, ich bin nur noch nicht aufgeklärt^^)

    SetCamera wird nicht erkannt aber ich geh mal davon aus dass das so wie gluLookAt (o.ä) ist
    also müsste das das selbe sein:

    gluLookAt(position.x,position.y,position.z, dir.x, dir.y , dir.z, 0,1,0);

    un die frage ist: wenn ich gluLookAt bzw SetCamera benutze dann dreh ich ja das object doppelt: einmal wegen rotatef..(rot) un wegen gluLookAt. das versteh ich nicht so^^ trotzdem thx



  • also das mit += passedsecs * dir hab ich übersehn, muss natürlich noch eine abfrage drum, ob w gedrückt wurde. wenn s gedrückt wird, dann -= PassedSecs * dir;

    Also ich kenn mich kaum mit ogl aus, aber ich dachte, dir geht es darum eine steuerung für die kamera zu machen. Das hab ich versucht zu zeigen. setcamera geht natürlich ncih, war ja auach nur halber pseudocode, aber ich glaub glulookat hört sich dafür ganz gut an. Und glRotatef gehört eigetnlich gar nicht in den code, denn damit wird ja das objekt gedreht. IUnd das willst du ja nich, du möchstest ja sozusagen um das objekt rumgehen können und es so von allen seiten betrachten und nicht auf einer stelle stehen bleiben und das objekt dreht sich dann von alleine. Sieht zwar ähnlich auf dem Bildschrim aus, sind aber zwei total verschiedene Ansätze. Siehst du spätestens, wenn du zwei Objekte hast 🙂



  • für des dass du kaum ogl kannst, kannstes ganzscön gut^^

    also ich hab deinen code jetz ma wiefolgt umgeschrieben für A un 😨

    GLfloat rot;
    ...
    
    if(keys['A'])
    				{
    					rot += 0.1f;
                                            if (rot>=360.0f)
    						rot=0.0f;
    
    					dir.x = sinf(rot);
    					dir.z = cosf(rot);
    
    					gluLookAt(pos.x,pos.y,pos.z   , 
                                                      dir.x,dir.y,dir.z ,  0,1,0);
    				}
    
    				if(keys['D'])
    				{
    					rot -= 0.1f;
                                            if (rot>=360.0f)
    						rot=0.0f;
    
    					dir.x = sinf(rot);
    					dir.z = cosf(rot);
    
    					gluLookAt(pos.x,pos.y,pos.z   , 
                                                      dir.x,dir.y,dir.z ,  0,1,0);
    				}
    

    das sieht schonmal besser aus als bei mir

    teorätisch (meine teorie...) müsste es auch funsten aber das 3-eck schiebt dann grad zur seite bis zu einen punkt und schiebt dann auf die andre seite bis auf den gespiegelten anderen punkt usw. (bei A)
    bei D gehts unsystematisch durch die gegend
    liegt das vll daran, dass rot einen negativen wert bekommen kann und dadurch das mit sin und cos nicht geht oder kann der winkel nicht höher als ein bestimmter wert sein (<360), was mit so vorkommt?

    ey aber reschpekt an No-Tocket, das geht voll ab 👍



  • sin() und cos() erwarten rad und nicht grad.
    gluLookAt() erwartet position und target - also einen absoluten zielvektor und keine richtung.



  • ? versteh ich net, wenn ich bei ziel "0,1,0" heisst das doch der vector von 0,0,0 zu 0,1,0 ..oder von dem aktuellen punkt zu 0,1,0 also ises doch ne richtung

    also so hat das das NEHE tutorial gemacht aber ich finds mit gluLookAt besser als mit rotate und translate besser, wie maxi

    gldrawscene()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
        glLoadIdentity();
    
    	GLfloat x_m, y_m, z_m, u_m, v_m;
    	GLfloat xtrans = -xpos;
    	GLfloat ztrans = -zpos;
    	GLfloat ytrans = -walkbias-0.25f;
    	GLfloat sceneroty = 360.0f - yrot;
    
    	int numtriangles;
    
    	glRotatef(lookupdown,1.0f,0,0);
    	glRotatef(sceneroty,0,1.0f,0);
    
    	glTranslatef(xtrans, ytrans, ztrans);
    	glBindTexture(GL_TEXTURE_2D, texture[filter]);
            ...
    }
    
    winmain
    {
        ...
        if (keys[VK_UP])
        {
             xpos -= (float)sin(heading*piover180) * 0.05f;
             zpos -= (float)cos(heading*piover180) * 0.05f;
        }
        ...
        if (keys[VK_RIGHT])
        {
    	heading -= 1.0f;
            yrot = heading;
        }
        ...
    }
    

    "heading" wird irgentwie garnicht verwendet 😕
    und bei dem erwartet sin und cos grad 😕
    was soll das da oben überhaupt 😕



  • wenn ich bei ziel "0,1,0" heisst das doch der vector von 0,0,0 zu 0,1,0

    das was bei dir (0,1,0) ist, ist der up-vector...

    grundlagen:
    eine matrix beschreibt einen vektorraum der in bezug zum untransformierten raum (einheitsmatrix) eine bestimmte ausrichtung und position hat.
    um diesen vektorraum zu definieren, benoetigt man 4 vektoren die angeben wo "rechts", "oben", "hinten" und das "zentrum" ist.
    um einen punkt vom untransformierten raum in diesen vektorraum zu uebertragen, wird er einfach mit der matrix multipliziert die aus eben diesen 4 basisvektoren besteht - genau das macht opengl fuer alle koordinaten mit modelview- und projection-matrix.

    alle entsprechenden opengl-funktionen wie glrotate oder glulookat manipulieren darum effektiv nur die transformationsmatrix.
    im falle von glulookat wird die matrix aus 3 vektoren berechnet:

    void gluLookAt(double eyeX, GLdouble eyeY, GLdouble eyeZ,
                   GLdouble centerX, GLdouble centerY, GLdouble centerZ,
                   GLdouble upX, GLdouble upY, GLdouble upZ);
    

    "zentrum" ist der eye-vektor - also die position an der nach der transformation (0,0,0) sein soll.
    "hinten" ist der vektor von eye nach center (ein punkt auf den die kamera schaut und keine richtung; daher von mir "target" genannt) - also der vektor der vom zentrum in die tiefe zeigt
    "rechts" ist der vektor der senkrecht auf "hinten" und "up" steht (ohne "up" waere diese richtung nicht definierbar) - also der vektor der vom zentrum nach rechts zeigt.
    "oben" ist dann wiederum der vektor der senkrecht auf "hinten" und "rechts" steht, also nach oben zeigt.

    es ist essentiell dass alle 3 basis-vektoren senkrecht aufeinander stehen, da sonst bei einer verschiebung auch eine skalierung passieren wuerde (deswegen ist "oben" auch ungleich "up")

    wenn du dich nach einer transformation entlang der koordinatenachsen bewegen willst, sind diese richtungen relativ zu der transformation.
    du kannst dazu einfach die aktuelle transformationsmatrix auslesen und die entsprechenden richtungsvektoren entnehmen.



  • ok thx ersma

    aber ein punkt ist also doch nicht ein punkt sondern eine richtung von zentrum und dem punkt
    un der up punkt ist also ein up vector vom zentrum zu den up punkt^^

    also wie ist es eigentlich am sinnvollsten in einer 3D welt rumzulaufen?
    1. modelview matrix rumverschieben
    2. projections matrix rumverschieben
    oder 3. mit gluLookAt arbeiten

    wenn ich jetzt 3. nehm:

    gluLookAt(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, 0,1,0);
    

    wie muss ich dann die pos und dir elemtente manipulieren, wenn man W A S D drückt, sodass man realistisch rumlaufen kann

    meine idee:

    W:
    pos.z += 1;
    dir.z += 1;

    S:
    pos.z -= 1;
    dir.z -=1;

    😨
    dir.z = cos(90-drehwinkel);
    dir.x = sin(90-drehwinkel);

    A:
    ????



  • aber ein punkt ist also doch nicht ein punkt sondern eine richtung von zentrum und dem punkt

    vom zentrum aus gesehen ist jeder punkt auch eine richtung 😉

    wie ist es eigentlich am sinnvollsten in einer 3D welt rumzulaufen?
    1. modelview matrix rumverschieben
    2. projections matrix rumverschieben
    3. mit gluLookAt arbeiten

    fuehrt am ende alles zum gleichen ergebnis.

    gluLookAt(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, 0,1,0);
    

    wie muss ich dann die pos und dir elemtente manipulieren, wenn man W A S D drückt, sodass man realistisch rumlaufen kann

    da du dich so nur um die y-achse drehst, kannst du maxis vorschlag folgen:

    'a': winkel+=irgendwas
    'd': winkel-=irgendwas
    
    // vektor nach vorne: (fuer winkel=0: 0,0,-1)
    vorne.x= sin(winkel);
    vorne.y= 0;
    vorne.z= -cos(winkel);
    
    // verschiebung vorne/hinten
    'w': pos+=vorne // jeweils x,y,z
    's': pos-=vorne
    
    // absolutes "target"
    dir= pos+vorne
    


  • ok wir kommen der sache schon näher.
    ich hab jetz mal dein code passend umgeschrieben (so wie ichs verstanden hab) un im programm steht dann:

    gldrawScene():

    ...
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        glLoadIdentity();
    	glMatrixMode(GL_MODELVIEW_MATRIX);
    
    	gluLookAt(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, 0,1,0);
    
    	glBegin(GL_TRIANGLES); 
         glColor3f(0.0f,0.0f,1.0f);
         glVertex3f( 0.0f, 1.0f, 0.0f);
         glVertex3f(-1.0f,-1.0f, 0.0f);
         glVertex3f( 1.0f,-1.0f, 0.0f);
    	glEnd();
    ...
    

    ...einfach ein 3-eck und gluLookAt

    und dann in WinMain:

    ...
                                            if (keys['W'])
    					{
    						pos.x += dir.x;
    						pos.y += dir.y;
    						pos.z += dir.z;
    
    					}
    					if (keys['S'])
    					{
    						pos.x -= dir.x;
    						pos.y -= dir.y;
    						pos.z -= dir.z;
    					}
    					if (keys['A'])
    					{
    						rot += 1.0f;
    						dir.x= sin(rot);
    						dir.y= 0;
    						dir.z= -cos(rot);
    					}
    					if(keys['D'])
    					{
    						rot -= 1.0f;
    						dir.x= sin(rot);
    						dir.y= 0;
    						dir.z= -cos(rot);
    					}
    ...
    

    ok wenn ich starte seh ich ein 3eck.
    drücke ich W dann komm ich immer näher ans 3-eck. wenn das 3-eck genau vor meiner nase ist "prallt" es ab und geht nach hinten bis es weg ist.
    dann lass ich W los un starte neu. das 3-eck is wieder in der mitte
    wenn ich A gedrückt halt geht es nach rechts, so umgefähr um 20grad dann geht es nach links, so umgefähr 20grad. also bewegt es sich im winkel von 40grad immer wieder hin und her.
    das heisst ich hab dein code misverstanden und bitte um aufklärung 😃
    wäre nett



  • du scheinst ja wohl nichts von dem gelesen oder verstanden zu haben, was ich geschrieben habe...

    wenn ich A gedrückt halt geht es nach rechts, so umgefähr um 20grad dann geht es nach links, so umgefähr 20grad

    rot += 1.0f;
    dir.x= sin(rot);
    

    1.0 sind ~57.3 grad, denn:

    sin() und cos() erwarten rad und nicht grad.

    drücke ich W dann komm ich immer näher ans 3-eck. wenn das 3-eck genau vor meiner nase ist "prallt" es ab und geht nach hinten bis es weg ist.

    dir.x= sin(rot);
    dir.y= 0;
    dir.z= -cos(rot); 
    gluLookAt(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, 0,1,0);
    

    nochmal: der parameter "dir" von gluLookAt ist eine absolute position auf die du schaust. du uebergibst aber eine richtung und darum schaust du immer auf einen punkt nahe (0,0,0) - nur rein zufaellig steht an dieser stelle dein dreieck. uebergib' statt "dir" einfach "pos+dir".



  • ok jetz hab ichs, ich sag mal danke für die ganze aufregung 👍

    wenn dir langweilig ist kannste mir auch noch sagen wie man seitlich läuft 😃

    eig ja dir.x += 1;
    pos.x += 1;

    dann schiebt man grad die position un den sichtpunkt zur seite. das geht aber logischerweise nur in der ausgangsposition. man muss den sichtvector um 90grad am zentrum drehen un dann auf diesem neuen vector das zentrum verschieben +/-.
    wie gesagt, diese frage ist optimal^^



  • kannste mir auch noch sagen wie man seitlich läuft

    mathematisch korrekt waere "seitlich" entlang des vektors der senkrecht auf "vorne" und "up" steht.
    da in diesem fall "vorne" aber effektiv zweidimensional ist, brauchst du nur die beiden komponenten tauschen und eine negieren:

    seite.x= -vorne.z;
    seite.y= 0;
    seite.z= vorne.x;
    

    kann man sich auch leicht am einheitskreis (sin, cos) verdeutlichen.

    wie gesagt, diese frage ist optimal^^

    bitte was?



  • top! thx, funktioniert zwar noch nicht so gaaanz aber im prinzip stimmts thx

    also "optimal" ...naja ist nicht notwendig (zu beantworten)



  • also teoräätisch geht es ja wenn mans aufn blatt papier malt. aber bei openGL net weil immer wenn ich mich dann seitlich beweg geht die kamera wieder in die ausgangsposition

    pos.x = -dir.z
    pos.z = dor.x
    

    ich weiss nur net warum das minus zeichen da ist, es geht iwie auch ohne.

    dann noch ne frage die vll damit zusammenhängt, weil das hier oben nicht geht:
    mein mensch steht pos 0.0/0.0 un guckt auf 0.0/1.0 guckt. wenn ich W drück wird der pos vector mit dem direction vector addiert dh: neue vectoren:
    pos = 0.0/1.0
    direction = 0.0/1.0

    wenn ich nochmal W drück dann:
    pos = 0.0/2.0
    direction = 0.0/1.0

    dh mein mensch guckt nach hinten, macht er aber nicht. warum?



  • wenn ich mich dann seitlich beweg geht die kamera wieder in die ausgangsposition

    pos.x = -dir.z
    pos.z = dir.x
    

    du setzt hier den richtungsvektor als position.
    der richtungsvektor wird irgendwas nahe 0 sein.
    darum befindest du dich am ursprung.

    ich weiss nur net warum das minus zeichen da ist, es geht iwie auch ohne.

    wenn du einen 2d-vektor (x,y) hast der beispielsweise nach vorne zeigt, zeigt der vektor (y,-x) zur seite - siehe einheitskreis.

    wenn du solche zusammenhaenge nicht verstehen kannst, solltest du dich nicht mit 3d-programmierung beschaeftigen.



  • ja sry meine lehrnmethode ist "learning by doing". aber <3lichen dank jetz klappst.

    ich hatte einen logischen denkfehler in meim brain



  • so ich hab jetz schon ganzviel dazugelernt in dem thema aber darf ich bitte bitte bitte noch eine frage stellen |=


  • Mod

    Fachmann schrieb:

    so ich hab jetz schon ganzviel dazugelernt in dem thema aber darf ich bitte bitte bitte noch eine frage stellen |=

    ja, durftest du und das war jetzt eine sehr nutzlose frage aber du hast sie gestellt, dann darf ich nu den thread schliessen :p


Anmelden zum Antworten