[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.


Log in to reply