Objekte rotieren bei bewegung falsch



  • Hallo,

    Ich habe 2 Objekte in einem 3D Raum, meine Kamera steht über dem Objekt 1 und schaut mit einem Winkel von 35 Grad darauf.
    Meine Objekte drehe ich mit D3DXMatrixRotationAxis, das klappt auch wunderbar.

    Jetzt möchte ich Objekt 1 zu dem X bewegen. Da Objekt 1 aber immer unter der Kamera bleiben soll, bewege ich also Objekt 2 entgegengesetzt.
    http://www.thm-cbm.de/bild1.gif

    und es passiert folgendes
    http://www.thm-cbm.de/bild2.gif

    Wiso dreht sich Objekt 2 ?

    Kann man keine Bilder einfügen, oder bin ich nur zu blöd dazu ?



  • Ich kann dir nicht ganz Folgen...

    Du hast 1 Objekt, über dem sich eine Kamera befindet und diese schaut mit einem Winkel von 35° von der waagerechten Ebene aus gesehen nach unten zu x?

    Du bewegst Objekt 1 zu dem x, die Kamera soll dadrüber bleiben, also dem Objekt 1 auf der Ebene folgen?

    Und jetzt der Teil den ich garnicht verstehen kann:
    Objekt 2 wird entgegengesetz bewegt, was hat Objekt 2 jetzt damit zu tun? Oder ist Objekt 2 die Kamera?

    Bitte beschreib es ein bischen deutlicher...



  • Also meine Kamera steht auf 0,-1000,0 und schaut mit einem Winkel von 35 Grad nach unten auf Objekt 1.

    Objekt 1 steht bei 0,0,-1000 und um 90 Grad nach rechts gedreht.

    Jetzt möchte ich Objekt 1 zu X bewegen, aber anstatt Objekt 1 jetzt die Koordinaten zu verändern, veränder ich von allen anderen die Koordinaten, hier ist das halt nur Objekt 2. Ich verschiebe also Objekt 2 entgegengesetzt als in die Richtung wo ich Objekt 1 hinbewegen möchte. Ich verschiebe also X und Objekt 2 nach links, anstatt Objekt 1 nach rechts.

    Objekt 2 dreht sich aber bei der verschiebung Richtung Objekt 1, normal sollte es aber weiter geradeaus nach oben schauen.



  • Verwendest du irgendwo die D3DXMatrixLookAtRH oder D3DXMatrixLookAtLH? Das könnte die automatische Drehung erklären.

    Zudem würde ich dazu raten
    D3DXMatrixRotationZ, D3DXMatrixRotationX, D3DXMatrixRotationY
    zu verwenden oder äquvalent dazu
    D3DXMatrixRotationYawPitchRoll

    weil diese nacheinaneder rotieren und somit evtl. logische Fehler gefunden werden können.
    Zum bewegen der Objekte verwendest du dann bestimmt D3DXMatrixTranslation.
    So würde des in etwa ausehen müssen, wobei natürlich eine Schleife drum rum muss die all deine Objekte durchgeht.

    D3DXMATRIX mRotX, mRotY, mRotZ, mTrans;
    
    D3DXMatrixRotationX(&mRotX, pitch);
    D3DXMatrixRotationY(&mRotY, yaw);
    D3DXMatrixRotationZ(&mRotZ, roll);
    
    D3DXMatrixTranslation(&mTrans, x_pos, y_pos, z_pos);
    
    D3DXMATRIX mWorld=(mRotZ*mRotX*mRotY)*mTrans; //Reihenfolge beachten!
    device->SetTransform(D3DTS_WORLD, &mWorld);
    

    Zeig mal ein bischen code, dann kann man dir mehr sagen



  • Das Problem ist wenn ich D3DXMatrixRotationX dann dreht sich das Objekt ja nicht um die eigene Achse, darum nehme ich ja D3DXMatrixRotationAxis.

    Hier setze ich Objekt 1 auf die feste Position

    sSpieler.posX = 0.0f;
    	sSpieler.posY = 0.0f;
    	sSpieler.posZ = -1000.0f;
    	D3DXMatrixTranslation(&sSpieler.char_matPos, sSpieler.posX, sSpieler.posY, sSpieler.posZ);
    	D3DXMatrixRotationX(&sSpieler.char_matRotX, D3DXToRadian(schar_spieler->rotX));
    	D3DXMatrixRotationY(&sSpieler.char_matRotY, D3DXToRadian(schar_spieler->rotY));
    	D3DXMatrixRotationZ(&sSpieler.char_matRotZ, D3DXToRadian(schar_spieler->rotZ));
    	D3DXMatrixMultiply(&sSpieler.char_matWorld, &sSpieler.char_matRotX, &sSpieler.char_matRotY);
    	D3DXMatrixMultiply(&sSpieler.char_matWorld, &sSpieler.char_matWorld, &sSpieler.char_matRotZ);
    	D3DXMatrixMultiply(&sSpieler.char_matWorld, &sSpieler.char_matWorld, &sSpieler.char_matPos);
    

    Das geht auch zum rendern.

    Hier berechne ich die Bewegung von Objekt 1

    D3DXMatrixRotationAxis(&matRotY, &D3DXVECTOR3(0,1,0), D3DXToRadian(schar_spieler->rotY));
    	D3DXVec3TransformCoord( &myCamera_vDir, &myCamera_vDir, &matRotY );
    	D3DXVec3TransformCoord( &myCamera_vUP, &myCamera_vUP, &matRotY );
    	D3DXVec3TransformCoord( &myCamera_vRight, &myCamera_vRight, &matRotY );
    	D3DXMatrixRotationAxis(&matRotX, &D3DXVECTOR3(1,0,0), D3DXToRadian(schar_spieler->rotX));
    	D3DXVec3TransformCoord( &myCamera_vDir, &myCamera_vDir, &matRotX );
    	D3DXVec3TransformCoord( &myCamera_vUP, &myCamera_vUP, &matRotX );
    	D3DXVec3TransformCoord( &myCamera_vRight, &myCamera_vRight, &matRotX );
    	D3DXMatrixRotationAxis(&matRotZ, &D3DXVECTOR3(0,0,1), D3DXToRadian(schar_spieler->rotZ));
    	D3DXVec3TransformCoord( &myCamera_vDir, &myCamera_vDir, &matRotZ );
    	D3DXVec3TransformCoord( &myCamera_vUP, &myCamera_vUP, &matRotZ );
    	D3DXVec3TransformCoord( &myCamera_vRight, &myCamera_vRight, &matRotZ );
    	schar_spieler->posX = schar_spieler->posX + myCamera_vDir.x * schar_spieler->speed;
    	schar_spieler->posY = schar_spieler->posY + myCamera_vDir.y * schar_spieler->speed;
    	schar_spieler->posZ = schar_spieler->posZ + myCamera_vDir.z * schar_spieler->speed;
    

    Das ist nur dazu da um den Rest der Welt zu berechnen

    Hier jetzt der Code für den Rest der Welt

    float PosX = (sSpieler.posX + schars[i].posX - schar_spieler->posX);
    		float PosY = (sSpieler.posY + schars[i].posY - schar_spieler->posY);
    		float PosZ = (sSpieler.posZ + schars[i].posZ - schar_spieler->posZ);
    
    		D3DXMatrixTranslation(&cCharaketer[i].matPos, PosX, PosY, PosZ);
    		D3DXMatrixRotationAxis(&cCharaketer[i].matRotX, &D3DXVECTOR3(1,0,0), D3DXToRadian(schars[i].rotX));
    		D3DXMatrixRotationAxis(&cCharaketer[i].matRotY, &D3DXVECTOR3(0,1,0), D3DXToRadian(schars[i].rotY));
    		D3DXMatrixRotationAxis(&cCharaketer[i].matRotZ, &D3DXVECTOR3(0,0,1), D3DXToRadian(schars[i].rotZ));
    //		D3DXMatrixRotationX(&cCharaketer[i].matRotX, D3DXToRadian(schars[i].rotX));
    //		D3DXMatrixRotationY(&cCharaketer[i].matRotY, D3DXToRadian(schars[i].rotY));
    //		D3DXMatrixRotationZ(&cCharaketer[i].matRotZ, D3DXToRadian(schars[i].rotZ));
    		D3DXMatrixMultiply(&cCharaketer[i].matWorld, &cCharaketer[i].matRotX, &cCharaketer[i].matRotY);
    		D3DXMatrixMultiply(&cCharaketer[i].matWorld, &cCharaketer[i].matWorld, &cCharaketer[i].matRotZ);
    		D3DXMatrixMultiply(&cCharaketer[i].matWorld, &cCharaketer[i].matWorld, &cCharaketer[i].matPos);
    

    Dies geht auch wieder zum rendern.

    Wie gesagt, die Positionen werden alle korrekt angezeigt, auch die Bewegungen stimmen, nur werden die halt gedreht.



  • Das Problem ist wenn ich D3DXMatrixRotationX dann dreht sich das Objekt ja nicht um die eigene Achse, darum nehme ich ja D3DXMatrixRotationAxis.

    Das dürfte nicht passieren, dein zu Transformierendes Objekt muss sich am Anfang jeder Berechnung in der Einheitsmatrix befinden, dann werden die Rotationen durchgeführt, welche zu den Axen [1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0] stattfinden, dann erst die Translation welche das Rotierte Objekt an seine Stelle Transformiert.

    Die D3DX-Funktionen überschreiben eigentlich die Werte der Matrix, evtl. aber nur diese welche nötig sind und lassen den Rest unverändert.

    Versuche vor der D3DXMatrixTranslation(...) die Matrizen(bzw. die matWorld) auf die Einheitsmatrix zu setzen. Also bevor du überhaupt anfängst was zu Transformieren.

    Und warum möchtest du den Rest der Welt transformieren und nicht nur die Kamera(Projektionsmatrix) und den Spieler(Eine Worldmatrix)? Das kostet dich doch Performance(ok, in diesem Fall nicht) und ist auch nicht intuitiv.



  • Also wenn ich deinen Code von oben benutze, dann kann ich mein Objekt nicht entlang seiner z-Achse bewegen nach dem drehen.

    Als Beispiel, ich habe meine z-Achse, die geht vom Objekt weg nach vorne und die x-Achse nach rechts. Jetzt dreh ich das Objekt um 90Grad nach rechts. Mit deinem Code und bewege das Objekt nun um 200 nach vorne, dann bewegt es sich entlang der z-Achse, also nach vorne weg obwohl die Nase nach rechts zeigt.

    Habe jetzt jede Matrix durch D3DXMatrixIdentity laufen lassen, bei jedem Frame, aber gebracht hat es nichts, leider.



  • Mein Code beschreibt eine absolute Bewegungen, d.h. es findet eine Eigenrotation statt und dann die Bewegung(absolut, es gibt kein "Vorne").

    Um die Bewegung in Relation mit der vorangegangenen Eigenrotation zu setzen müsstest du folgendes machen:
    -Identität
    -Translation (-> 200 auf z-Achse)
    -Rotation (-> 200 auf x-Achse)
    -x, y, z-Speichern
    -Identität
    -Rotation (-> Nase in x-Richtung)
    -Translation (Mit den neuen x, y, z-Koordinaten)

    Geht bestimmt einfacher, wenn du Front, Left und Up-Vektor des Spielers hast.



  • Die Vectoren habe ich ja und so berechne ich das ganze doch auch, denke ich zumindest.

    D3DXMatrixRotationAxis(&matRotY, &D3DXVECTOR3(0,1,0), D3DXToRadian(schar_spieler->rotY));
    D3DXVec3TransformCoord( &myCamera_vDir, &myCamera_vDir, &matRotY );
    D3DXVec3TransformCoord( &myCamera_vUP, &myCamera_vUP, &matRotY );
    D3DXVec3TransformCoord( &myCamera_vRight, &myCamera_vRight, &matRotY );
    

    Hab mal ein Video gemacht was passiert, ist 8MB groß
    http://www.thm-cbm.de/video.avi


Anmelden zum Antworten