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

23.02.2008, 19:12

Kamera Steuerung

Hallo zusammen,

vielleicht kann mir jemand eine Kleinigkeit erklären?
Ich bin gerade dabei eine Steuerung zu schreiben (Weltraumsteuerung), funktioniert auch teilweise.
Die Kamera soll wenn man die Maus nach rechts bewegt sich nach rechts drehen und genauso in die andere Richtung, ebenso hoch und runter.
So wenn ich jetzt die Kamera nach unten richte und ich will mich nach rechts drehen rotiert sie um Ihre eigene Achse.
Kann mir eventuell jemand sagen woran das liegen könnte?
Gruß
Andy

2

23.02.2008, 19:34

Zeig doch mal den relevanten Code...

3

23.02.2008, 19:41

Ok das ist momentan der Code.
Rollen-Drehen-Hoch und runter schauen

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
    //Rollen um die eigene Achse

    if( dims.rgbButtons[1] & 0x80 )
    {
        if( dims.lX != 0 )
        {
            float g_fPitchAmount = ((float)dims.lX / g_fMouse);
            g_fPitch += g_fPitchAmount;
            D3DXMatrixRotationAxis( &mtxRot, & D3DXVECTOR3(0,0,1), D3DXToRadian(g_fPitchAmount));
            D3DXVec3TransformCoord( &g_vLook, &g_vLook, &mtxRot );
            D3DXVec3TransformCoord( &g_vUp, &g_vUp, &mtxRot );         
        }
    } 
    //Drehen um die eigene Achse

    else if( dims.lX != 0 )
    {
        D3DXMatrixRotationAxis( &mtxRot, &D3DXVECTOR3(0,1,0), D3DXToRadian((float)dims.lX / g_fMouse) );
        D3DXVec3TransformCoord( &g_vUp, &g_vUp, &mtxRot );
        D3DXVec3TransformCoord( &g_vLook, &g_vLook, &mtxRot );
        
    }
    //Look up and down

    if( dims.lY != 0 )
        {
            float g_fPitchAmount = ((float)dims.lY / g_fMouse);
            g_fPitch += g_fPitchAmount;
            D3DXMatrixRotationAxis( &mtxRot, &g_vRight, D3DXToRadian(g_fPitchAmount));
            D3DXVec3TransformCoord( &g_vLook, &g_vLook, &mtxRot );
            D3DXVec3TransformCoord( &g_vUp, &g_vUp, &mtxRot );              
        }

4

24.02.2008, 09:51

Das hört sich an, als würdest du um die absoluten Achsen drehen!
Wenn du das tust, funktioniert eigentlich alles prima - nur das du, wenn du nach unten guckst, die absolute Y-Achse entlang schaust und somit eine Drehung um die absolute Y-Achse in einer Drehung um die Kamera-Z-Achse resultiert.

5

24.02.2008, 09:59

Probier mal Folgendes:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if( dims.rgbButtons[1] & 0x80 )
{   

// Mausbewegung "abdämpfen"

float deltaX = (float)dims.lX * 0.005f;
float deltaY = (float)dims.lY * 0.005f;
        
// Pitch (Rauf/Runter)

D3DXMatrixRotationAxis(&mtxRot, &g_vRight, deltaY);
D3DXVec3TransformCoord(&g_vLook, &g_vLook, &mtxRot);
D3DXVec3TransformCoord(&g_vUp, &g_vUp, &mtxRot);

// Rotation Y-Achse

D3DXMatrixRotationY(&mtxRot, deltaX);
D3DXVec3TransformCoord(&g_vLook, &g_vLook, &mtxRot);
D3DXVec3TransformCoord(&g_vRight, &g_vRight, &mtxRot);

}

6

24.02.2008, 14:56

Hi,
danke für die Antwort, aber leider funktioniert das nicht.
Vielleicht hab ich mich etwas falsch ausgedrückt.
Also die Steuerung soll ja eine Weltraum steuerung sein.
Es gibt ja kein oben oder unten, nur gebe ich ja bei

D3DXMatrixLookAtLH(&m_ViewMatrix,
&D3DXVECTOR3(0.0f, 0.0f,0.0f),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));

an dass die Weltausrichtung oben ist.
So wenn ich mich nun um die eigene ,Achse drehe also Umschaue, funktioniert das wenn ich nach vorne blicke.
Es funktioniert auch das Rollen.
Aber wenn ich die nach unten schaue und nach links oder rechts drehen will beginnt die Kammera zu rollen.
Genauso was ein anderer Effekt ist wenn ich mich auf den Kopf drehe ist die Steuerung spiegelverkehrt.
Also die Steuerung soll immer in jede Richtung funktionieren egal in welche Richtung man schaut, nur wenn die Maustaste gedrückt wird kann man die Kamera rollen.

7

26.02.2008, 22:55

Für komplexere Rotationen im 3D Raum benötigt man Quaternions. Ich habe aber auch gerade erst angefangen, mich damit zu befassen, deshalb bin ich mir nicht ganz sicher, ob das hier erforderlich ist.
Nur mal so als Hinweis.
Lieber dumm fragen, als dumm bleiben!

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

8

27.02.2008, 11:37

Nein ist es für diesen Fall nicht. Im Prinzip muss man ja nur eine Rotationsmatrix aus den Steuereinstellungen erstellen und diese dann mit der Weltmatrix des Objektes multiplizieren. Das Problem ist nur, dass es eine Weile her ist, dass ich das gemacht habe. Daher kann ich auf Anhieb nicht sagen wo hier das Problem liegt.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

9

27.02.2008, 11:39

als erstes fällt mir auf, dass dein zweiter vektor erstmal 0.0f,0.0f,1.0f sein sollte, als grundeinstellung.

für deine kamerasteuerung bietet es sich folgendes an:

man definiere drei zueinander senkrecht stehende vektoren z. b. folgende:

vRight = 1.0f,0.0f,0.0f;
vUp = 0.0f,1.0f,0.0f;
vLook = 0.0f,0.0f,1.0f;

wenn du dich drehst, dann entsprechend entlang der achse (also beispielsweise bei y-drehung um die vUp) mit D3DXRotationAxis. die anderen beiden achsen ebenfalls mit der erhaltenen Matrix durch TransformCoord mitdrehen.

die bwegung machst du dann einfach entlang dieser drei vektoren, also wenn du z. b. dich vorwärts bewgeen willst dan entlang des vLookVektors * Schrittweite, dann hast du deinen eye-vektor (vEye).

wichtig ist natürlich, dass die richtungsvektoren immer normalisiert sind, sonst haut das ganze nicht hin.

zum schluss rufst du einfach die D3DXMatrixLookAtLH wie folgt auf:

D3DXMatrixLookAtLH(&vEye,&vLook,&vUp);

ArthurII

Treue Seele

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

10

22.03.2009, 12:32

also bin momentan an einem kleinen weltraumrennspiel in OpenGl. mein problem ist auch die steuerung.

meine bisherigeren klassen für die bewegung etc: (Python)

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
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
72
73
74
75
class Movedobject:
    def __init__(self):
        self.v=Vektor()
        
        self.front=Vektor(0,0,-1)
        self.up=Vektor(0,1,0)
        self.left=self.front.kreuz(self.up)          #Vektor.kreuz() gibt das Kreuzprodukt zurück
        
        self.pos=Vektor()

    def newpos(self):
        self.pos+=self.v

        self.rx=math.degrees(math.asin(float(self.front * Vektor( 0, 1, 0)  /abs(self.front))))  
        #berchnet den winkel zwischen self.front und xz ebene

        self.ry=math.degrees(math.asin(float(self.front * Vektor(-1, 0, 0)  /abs(self.front))))

        self.rz=math.degrees(math.asin(float(self.front * Vektor(-1, 0, 0) /abs(self.front))))


    def setstatus(self, key, state):                     
        self.status[key]=state

class Player(Movedobject):
    def __init__(self):
        Movedobject.__init__(self)
        self.status={K_UP:False,
                     K_DOWN:False,
                     K_LEFT:False,
                     K_RIGHT:False,

                     K_w:False,
                     K_a:False,
                     K_s:False,
                     K_d:False,
                     
                     K_SPACE:False,

                     K_r:False}
        
    def lenken(self):
        diff=0.005
        if self.status[K_UP]:
            self.front= (self.front+self.up*diff).normal()            
            self.up = -self.front.kreuz(self.left).normal()            

        if self.status[K_DOWN]:
            self.front= (self.front-self.up*diff).normal()            
            self.up = -self.front.kreuz(self.left).normal()

        if self.status[K_LEFT]:
            self.front= (self.front-self.left*diff).normal()            
            self.left = self.front.kreuz(self.up).normal()

        if self.status[K_RIGHT]:
            self.front= (self.front+self.left*diff).normal()            
            self.left = self.front.kreuz(self.up).normal()

        #vorwärtsbeschleunigen:
        a=0.01
        if self.status[K_w]:
            self.v+=self.front.normal()*-a

        #bremsen und rückwärts
        if self.status[K_s]:
            self.v+=self.front.normal()*a        

        #anhalten
        if self.status[K_SPACE]:
            self.v=Vektor()

        #reset
        if self.status[K_r]:
            self.__init__()


in der draw() funktion führe ich dann aus:

Quellcode

1
2
3
4
5
glRotate(self.player.rx, 1.0,0,0)
glRotate(self.player.ry, 0,1.0,0)
glRotate(self.player.rz, 0,0,1.0)

glTranslatef(self.player.pos.x, self.player.pos.y, self.player.pos.z)


self.player ist eine Instanz von Player in der Main-Klasse zu der draw() gehört.

die berechnung der position erfolgt so wie ich mir das vorstelle, nur die kamera-drehung macht mir iwie den gar aus, keine ahnung warum

Werbeanzeige