Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

01.11.2007, 14:08

Problem mit Rotation bei OpenGL

Hallo,

ich habe ein Problem mit Rotationen bei OpenGL.

Ich habe einen Kopf mit 2 Augen und eine bestimmte Anzahl von Objekten.
Der Kopf ist rotierbar um die x-, y- und z-Achse, die Objekte bleiben dabei fest. Die Augen sollen dabei ein aktives Objekt fixieren.
Mir ist es zwar gelungen, das Objekt im Auge zu behalten (Sehstrahlen kreuzen sich im Objektmittelpunkt), allerdings nur, wenn auch nur ein Winkel für die Kopfrotation gesetzt wird. Sobald mehr als ein Winkel gesetzt wird, sind die Sehstrahlen windschief.

Ich hoffe, Ihr könnt mir helfen - Danke im voraus

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//Initialisierung


double x_rot_head = 5.0;    // Rotationswinkel des Kopfes um x-,y- und z-Achse

double y_rot_head = 10.0;
double z_rot_head = 25.0;

vector<double> active_obj(3);   // Vektor für die Position des aktiven Objektes 


vector <double> center_le(3), center_re(3);     // Zentrum des linken / rechten Auges

vector <double> gaze(3);        // Blickrichtungsvektor 

    gaze [0] = 0;
    gaze [1] = 0;
    gaze [2] = 1;
vector<double> diffvect_l(3), diffvect_r(3);     // Differenzvektor zwischen Zentrum des linken/rechten Auges und aktivem Objekt


vector<double> rot_vec_l(3), rot_vec_r(3);     // Rotationsachsen für linkes und rechtes Auge

double angle_l = 0, angle_r = 0;     // Winkel für die Rotation des linken / rechten Auges um Rotationsachse



//Berechnungen


gaze_upd = math.RotUpdate(gaze, x_rot_head, y_rot_head, z_rot_head);    // Position von gaze/center_le/center_re nach Kopfrotation

center_le_upd = math.RotUpdate(center_le, x_rot_head, y_rot_head, z_rot_head);
center_re_upd = math.RotUpdate(center_re, x_rot_head, y_rot_head, z_rot_head);


diffvect_l = math.DiffVect(center_le_upd, active_obj);  // Differenzvektor zws Zentrum linkes/rechtes Auge und aktivem Objekt

diffvect_r = math.DiffVect(center_re_upd, active_obj);  

angle_l = math.SkalProd(gaze_upd, diffvect_l);     // Rotationswinkel für linkes und rechtes Auge über Skalarprodukt

angle_r = math.SkalProd(gaze_upd, diffvect_r);

rot_vec_l = math.CrossProd(gaze_upd, diffvect_l);    // Rotationsachse für linkes / rechtes Auge über Kreuzprodukt

rot_vec_r = math.CrossProd(gaze_upd, diffvect_r);

rot_vec_l = math.RotUpdate(rot_vec_l, -1 * x_rot_head, -1 * y_rot_head, -1 * z_rot_head);     // Rotationsachsen nach Rotationsupdate

rot_vec_r = math.RotUpdate(rot_vec_r, -1 * x_rot_head, -1 * y_rot_head, -1 * z_rot_head);     // Allerdings: -1* Winkel???



//DrawGLScene(GLvoid)   


glPushMatrix();     // *Zeichnen des Kopfes*

        glRotated(x_rot_head, 1.0, 0.0, 0.0);
        glRotated(y_rot_head, 0.0, 1.0, 0.0);
        glRotated(z_rot_head, 0.0, 0.0, 1.0);
        ...
        glCallList(1);     // Displayliste: Kopf

glPopMatrix();


glPushMatrix();     // *Zeichnen des rechten Auges*

        glRotated(x_rot_head, 1.0, 0.0, 0.0);
        glRotated(y_rot_head, 0.0, 1.0, 0.0);
        glRotated(z_rot_head, 0.0, 0.0, 1.0);

        glTranslated(center_re.at(0), center_re.at(1), center_re.at(2));     // Transl. des Sehstrahls vom Ursprung in Augzentrum 

        glRotated(angle_r, rot_vec_r.at(0), rot_vec_r.at(1), rot_vec_r.at(2));  // Ausrichten auf aktives Objekt

        
        glCallList(4);     // Displayliste: Sehstrahl

        
        glTranslated(-center_re.at(0), -center_re.at(1), -center_re.at(2));     // Rücktranslation

        
        glCallList(2);     // Displayliste: rechtes Auge                                                                

glPopMatrix();

glPushMatrix();      // Zeichnen des linken Auges

        ...
        // analog zu rechtem Auge

        ...
glPopMatrix();
glFlush();

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

01.11.2007, 14:41

Du musst die Sehstrahlen natürlich relativ zur Kopfrotation berechnen.
@D13_Dreinig

3

01.11.2007, 16:02

Erst mal herzlichen Dank,


aber wie kann ich von meinen Augenrotationswinkeln denn die Kopfrotationswinkel "subtrahieren"?
Die Augenrotationsachsen sollten mit

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
rot_vec_l = math.RotUpdate(rot_vec_l, -1 * x_rot_head, -1 * y_rot_head, -1 * z_rot_head);     // Rotationsachsen nach Rotationsupdate 
rot_vec_r = math.RotUpdate(rot_vec_r, -1 * x_rot_head, -1 * y_rot_head, -1 * z_rot_head); 

// Funktion RotUpdate - "glRotate von Hand"
vector <double> Math::RotUpdate (vector <double> v, double rot_x, double rot_y, double rot_z)

{   
    rot_x = rot_x*PI/180;           //Deg2Rad
    rot_y = rot_y*PI/180;
    rot_z = rot_z*PI/180;

    vector <double> rotupdate (3);
    double vector [3][1] = {{v.at(0)},{v.at(1)},{v.at(2)}};
    
    double rotmatrix [3][3] ={ {cos(rot_y)*cosf(rot_z), -cos(rot_x)*sin(rot_z)+sin(rot_x)*sin(rot_y)*cos(rot_z),  sin(rot_x)*sin(rot_z)+cos(rot_x)*sin(rot_y)*cos(rot_z)},
                               {cos(rot_y)*sin(rot_z),   cos(rot_x)*cos(rot_z)+sin(rot_x)*sin(rot_y)*sin(rot_z), -sin(rot_x)*cos(rot_z)+cos(rot_x)*sin(rot_y)*sin(rot_z)},
                               {-sin(rot_y),             sin(rot_x)*cos(rot_y),                                   cos(rot_x)*cos(rot_y)}};
    
    double upd_vec [1][3];
    
    
     for (int i=0; i<3; ++i)
     {
        double s = 0;
        for (int j=0; j<3; ++j)
        {
            s += rotmatrix[i][j] * vector[j][0];
            upd_vec[0][i] = s;
        }
      }
    
      rotupdate[0] = upd_vec [0][0];
      rotupdate[1] = upd_vec [0][1];
      rotupdate[2] = upd_vec [0][2];

    return rotupdate;

}

doch kompensiert sein.
Oder bin ich ganz auf dem Holzweg?





Grüße

Werbeanzeige