如何在不倾斜物体的情况下倾斜相机?

时间:2019-10-30 16:07:06

标签: c++ directx direct3d

我使一个物体在相机前面移动。我将旋转矩阵乘以对象矩阵,以使对象重复进行摄影机转换。问题在于,倾斜摄像机时,物体也会倾斜。倾斜相机时,物体不应相对于屏幕旋转。怎么办?

此代码段。

void UpdateCamera()
{
    // Rotate target around camera
    camRotationMatrix = XMMatrixRotationRollPitchYaw(camPitch, camYaw, 0);
    camTarget = XMVector3TransformCoord(DefaultForward, camRotationMatrix );
    camTarget = XMVector3Normalize(camTarget);

    XMMATRIX RotateYTempMatrix;
    RotateYTempMatrix = XMMatrixRotationY(camYaw);

    // Walk
    camRight = XMVector3TransformCoord(DefaultRight, RotateYTempMatrix);
    camForward = XMVector3TransformCoord(DefaultForward, RotateYTempMatrix);
    camUp = XMVector3Cross(camForward, camRight);

    // Free Cam
    camRight = XMVector3TransformCoord(DefaultRight, camRotationMatrix);
    camForward = XMVector3TransformCoord(DefaultForward, camRotationMatrix);
    camUp = XMVector3Cross(camForward, camRight);

    camPosition += moveLeftRight*camRight;
    camPosition += moveBackForward*camForward;

    moveLeftRight = 0.0f;
    moveBackForward = 0.0f;

    camTarget = camPosition + camTarget;

    // Third Person Camera
    // Set the cameras target to be looking at the character.
    camTarget = charPosition;
    camTarget = XMVectorSetY(camTarget, XMVectorGetY(camTarget)+5.0f);    


    // Rotate camera around target
    camRotationMatrix = XMMatrixRotationRollPitchYaw(-camPitch, camYaw, 0);
    camPosition = XMVector3TransformNormal(DefaultForward, camRotationMatrix );
    camPosition = XMVector3Normalize(camPosition);

    // Set our cameras position to rotate around the character.
    // to be "standing" on (0,0,0), instead of centered around it ;) Well target her head here though
    camPosition = (camPosition * charCamDist) + camTarget;


    camForward = XMVector3Normalize(camTarget - camPosition);    // Get forward vector based on target
    camForward = XMVectorSetY(camForward, 0.0f);    // set forwards y component to 0 so it lays only on
    // the xz plane
    camForward = XMVector3Normalize(camForward);
    // To get our camera's Right vector, we set it's x component to the negative z component from the
    // camera's forward vector, and the z component to the camera forwards x component
    camRight = XMVectorSet(-XMVectorGetZ(camForward), 0.0f, XMVectorGetX(camForward), 0.0f);

    // Our camera does not "roll", so we can safely assume that the cameras right vector is always
    // in the xz plane, so to get the up vector, we just get the normalized vector from the camera
    // position to the cameras target, and cross it with the camera's Right vector
    camUp =XMVector3Normalize(XMVector3Cross(XMVector3Normalize(camPosition - camTarget), camRight));

    camView = XMMatrixLookAtLH( camPosition, camTarget, camUp );
}


void DetectInput(double time)
{
    DIMOUSESTATE mouseCurrState;

    BYTE keyboardState[256];

    DIKeyboard->Acquire();
    DIMouse->Acquire();

    DIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouseCurrState);

    DIKeyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)&keyboardState);

    if(keyboardState[DIK_ESCAPE] & 0x80)
        PostMessage(hwnd, WM_DESTROY, 0, 0);

    float speed = 10.0f * time;    
    bool moveChar = false;
    XMVECTOR desiredCharDir = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

    if(keyboardState[DIK_A] & 0x80)
    {
        desiredCharDir += (camRight);
        moveChar = true;
    }
    if(keyboardState[DIK_D] & 0x80)
    {
        desiredCharDir += -(camRight);
        moveChar = true;
    }
    if(keyboardState[DIK_W] & 0x80)
    {
        desiredCharDir += (camForward);
        moveChar = true;
    }
    if(keyboardState[DIK_S] & 0x80)
    {
        desiredCharDir += -(camForward);
        moveChar = true;
    }
    if((mouseCurrState.lX != mouseLastState.lX) || (mouseCurrState.lY != mouseLastState.lY))
    {
        camYaw += mouseLastState.lX * 0.002f;
        camPitch += mouseCurrState.lY * 0.002f;


        // Normalize our destinated direction vector
        desiredCharDir = XMVector3Normalize(desiredCharDir);


        if (XMVectorGetX(XMVector3Dot(desiredCharDir, oldCharDirection)) == -1)
            oldCharDirection += XMVectorSet(0.02f, 0.0f, -0.02f, 0.0f);

        // Get our current characters position in the world, from it's world matrix
        charPosition = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
        charPosition = XMVector3TransformCoord(charPosition, playerCharWorld);

        // Rotate our character smoothly when changing direction (from the GPG series)
        float destDirLength = 10.0f * frameTime;        // Change to the speed you want your character to rotate. This uses the game timer from an earlier lesson
                                                        // The larget this value, the faster the character rotates
        currCharDirection = (oldCharDirection)+(desiredCharDir * destDirLength);    // Get the characters direction (based off time, old position, and desired
                                                                                    // direction), by adding together the current direction and the old direction
                                                                                    // to get vector that smoothly turns from oldCharDir to denstinationDirection
        currCharDirection = XMVector3Normalize(currCharDirection);        // Normalize the characters current direction vector
                                                                        // the opposite of what it currently is, giving us the result in -1 PI to 1 PI.
        float charDirAngle = XMVectorGetX(XMVector3AngleBetweenNormals(XMVector3Normalize(currCharDirection), XMVector3Normalize(DefaultForward)));
        if (XMVectorGetY(XMVector3Cross(currCharDirection, DefaultForward)) > 0.0f)
            charDirAngle = -charDirAngle;

        // Now we update our characters position based off the frame time, his old position, and the direction he is facing
        float speed = 15.0f * frameTime;
        charPosition = charPosition + (desiredCharDir * speed);

        // Update characters world matrix
        Scale = XMMatrixScaling(0.25f, 0.25f, 0.25f);
        Translation = XMMatrixTranslation(XMVectorGetX(charPosition), 0.0f, XMVectorGetZ(charPosition));

        playerCharWorld = Scale * XMMatrixRotationRollPitchYaw(-camPitch, camYaw, 0) * Translation;

        // Check that the camera doesn't go over the top or under the player
        if(camPitch > 0.85f)
            camPitch = 0.85f;
        if(camPitch < -0.85f)
            camPitch = -0.85f;

        mouseLastState = mouseCurrState;
    }

我设置了角色世界矩阵

playerCharWorld = Scale * XMMatrixRotationRollPitchYaw(-camPitch, camYaw, 0) * Translation;

为使角色重复相机的旋转,我乘以XMMatrixRotationRollPitchYaw(-camPitch,camYaw,0)倾斜相机时,角色也会倾斜。倾斜相机时如何使角色不倾斜?

0 个答案:

没有答案