[solved] Problem mit Vektor- und Winkelberechnung beim Strafing
-
Hab eine kleine 3D Engine, in der man sich innerhalb des Raumes bewegen kann. Hierbei kann man frei im Raum schweben, oder laufen. Nun brauch ich einen speziellen Modus, wo die Kamera immer zu einem fixen Punkt schaut. Allerdings spinnt dann bei meiner aktuellen Realisierung das seitwärtsgehen. Hab bereits Wikipedia und diverse Webseiten für die Berechnungen zu rate gezogen, aber irgendwie funzt das alles nicht.
Vielleicht kann mir hier jemand weiterhelfen.
Hier mal die entsprechenden Quelltextteile:strafen nach rechts (strafen nach links ist analog dazu)
if (m_Input.IsKeyPressed(DIK_RIGHT)) { D3DXVECTOR3 vStrafe; // Vektor der Seitwärtsbewegung // Seitwärtsvektor berechnen vStrafe.x = cos(m_fCamPitch) * cos(m_fCamYaw + D3DX_PI / 2.0f); vStrafe.z = cos(m_fCamPitch) * sin(m_fCamYaw + D3DX_PI / 2.0f); vStrafe.y = 0.0f; m_vCameraPos -= 0.01 * m_Input.GetMoveSpeed() * vStrafe; // Position prüfen und neuen Blickpunkt berechnen CheckCamPos(); CalcCamLook(); }
Kamera Position prüfen (u.a. damit man nicht in das anvisierte Objekt laufen kann)
void CEngine::CheckCamPos(void) { // Falls Lock aktiviert ist, prüfen ob die Kamera zu nah am Objekt ist if ((m_Input.GetMicLock() == true) && (m_Input.GetCamMode() == false)) { if (m_fCamDist < 0.5f) // Ist Kamera zu nah am Mikrofon? { float fDifferenz = 0.5f - m_fCamDist; m_vCameraPos = m_vCameraPos + m_vCameraLook * (-fDifferenz); } } } // ~CEngine::CheckCamPos();
Berechnung des Richtungsvektor und Rückwärtsberechnung von Pitch und Yaw
void CEngine::CalcCamLook(void) { // ist der Mikrofon-Lock aus, oder der Mikrofon-Kamera Modus an if ((m_Input.GetMicLock() == false) || (m_Input.GetCamMode())) { ... } else // Wenn Lock Modus aktiv ist { D3DXVECTOR3 vMicDirection; // Stützvektor erstellen vMicDirection.x = m_Sphere.GetMicPosX() - m_vCameraPos.x; vMicDirection.y = m_Sphere.GetMicPosY() - m_vCameraPos.y; vMicDirection.z = m_Sphere.GetMicPosZ() - m_vCameraPos.z; // Betrag des Blickrichtungsvektors ermitteln m_fCamDist = sqrt(vMicDirection.x * vMicDirection.x + vMicDirection.y * vMicDirection.y + vMicDirection.z * vMicDirection.z); // Richtungsvektor Normieren m_vCameraLook = vMicDirection / m_fCamDist; // Berechnung des Radius der Ebene float fR = sqrt(m_vCameraLook.x * m_vCameraLook.x + m_vCameraLook.z * m_vCameraLook.z); // Neuberechnung der Elevation SetCamPitch(acos(fR)); // Neuberechnung des Azimuts SetCamYaw((D3DX_PI / 2.0f - atan(m_vCameraLook.z / fR))); } } // ~CEngine::CalcCamLook();
Der letzte Quelltext ist vermutlich der, der den Fehler beinhaltet. Es soll der Richtungsvektor von Kamera zum Mikrofon ermittelt werden und dieser auf eine Länge von 1 normiert werden. Danach soll anhand von diesem die aktuellen Pitch(Elevation->Neigung) und Yaw(Azimut->Winkel in der xz-Ebene) Werte berechnet werden.
Diese scheinen aber dann nicht zu stimmen. wenn ich den Modus wieder deaktiviere und schaut er mit diesen Pitch/Yaw -Werten jedenfalls komplett woanders hin.
-
Konnte das Problem selber lösen. Anhand der Skalarprodukte zwischen Richtungsvektor und Stützvektor zur xy-Ebene bzw zur xz-Ebene lassen sich die Winkel ermitteln.