Jump to content
  • Advertisement
Sign in to follow this  
Toastmastern

Camera movements around a sphere(planet)

This topic is 662 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello(again ^^)!
 
For a few days now I have been working on my camera movement around my sphere, I've been googling and reading guides all over the internet. The plan right now is to have the user go north/south and east/west with the keyboard, strafing in different directions while keeping the distance from origin. I then want the user to be able to turn the camera by pressing the right mousebutton and moving the camera around. The user will also be able to zoom by using the mouse wheel, but right now I have but that on the keyboard as well. So that is the plan, atleast for now.

 

I will post the camera code here before continueing:

XMFLOAT3 up, position, lookAt;
XMVECTOR upVector, positionVector, lookAtVector;
float yaw, pitch, roll, radians;
XMMATRIX rotationMatrix;
 
up.x = 0.0f;
up.y = 1.0f;
up.z = 0.0f;
 
upVector = XMLoadFloat3(&up);
 
position.x = mPositionX;
position.y = mPositionY;
position.z = mPositionZ;
 
positionVector = XMLoadFloat3(&position);
 
lookAt.x = 0.0f;
lookAt.y = 0.0f;
lookAt.z = 1.0f;
 
lookAtVector = XMLoadFloat3(&lookAt);
 
pitch = mRotationX * 0.0174532925f;
yaw = mRotationY * 0.0174532925f;
roll = mRotationZ * 0.0174532925f;
 
rotationMatrix = XMMatrixRotationRollPitchYaw(pitch, yaw, roll);
 
lookAtVector = XMVector3TransformCoord(lookAtVector, rotationMatrix);
upVector = XMVector3TransformCoord(upVector, rotationMatrix);
 
lookAtVector = XMVectorAdd(positionVector, lookAtVector);
 
mViewMatrix = XMMatrixLookAtLH(positionVector, lookAtVector, upVector);
 
return;

I first started by thinking around the rotationX, Y and Z and got that working as long as I didn't lookAtVector = XMVectorAdd(positionVector, lookAtVector);(is this what is called translating?) but since I wanted to give the user the ability to turn around as if he/she was using a first person camera I dropped that idea. I still believed if I would have gotten this to work it would have been the best solution.

 

I then started working with the positionX, Y and Z and got that working pretty nicely or well closer then the rotation atleast. The issue I have currently having with this one is that I have hard time finding a equation that fits all the cases. I have no issue working with the XZ-plane only(East/West) but since the x also is included in the XY plane(North/South) I'm only able to get it to work in one of the directions by having an angleXZ and angleXY which I increase or decrease depending on which button is pressen. is there a general equation that covers all the directions? Or is the rotation solution I should go for?

 

I find working with the position vector the easiest to understand but I think that the rotation is the way to go but my lack of knowledge in the Matrix area prohibits me to continue down that path.

 

Also as before my code have the framework used in the Rastertek guide's which have one Camera class and one Position class.

 

Best Regards and Thanks in Advance!

//Toastmastern

Share this post


Link to post
Share on other sites
Advertisement

The answer for me was to google  more about math and less about game development and camera movement.

 

For anyone having issues in the future here is where I find my solution for a coordinate system around a sphere:

 

http://mathworld.wolfram.com/SphericalCoordinates.html

 

Still having some issue for my mouse rotation but that will be a question for the future :)

 

Best Regards

Toastmastern

Share this post


Link to post
Share on other sites
I will write here instead of in a new thread since the topic is still the same :) I got it working by commenting a row of the code away but I'm looking for
input on why it helped since I kind of confused.

Here is my camera code:

	XMFLOAT3 up, position, lookAt;
	XMVECTOR upVector, positionVector, lookAtVector;
	float yaw, pitch, roll, radians;
	XMMATRIX rotationMatrix;

	up.x = 0.0f;
	up.y = 1.0f;
	up.z = 0.0f;

	upVector = XMLoadFloat3(&up);

	position.x = mPositionX;
	position.y = mPositionY;
	position.z = mPositionZ;

	positionVector = XMLoadFloat3(&position);

	lookAt.x = 0.0f;
	lookAt.y = 0.0f;
	lookAt.z = 1.0f;

	lookAtVector = XMLoadFloat3(&lookAt);

	pitch = mRotationX * 0.0174532925f;
	yaw = mRotationY * 0.0174532925f;
	roll = mRotationZ * 0.0174532925f;

	rotationMatrix = XMMatrixRotationRollPitchYaw(pitch, yaw, roll);

	lookAtVector = XMVector3TransformCoord(lookAtVector, rotationMatrix);
	upVector = XMVector3TransformCoord(upVector, rotationMatrix);

	lookAtVector = XMVectorAdd(positionVector, lookAtVector);

	mViewMatrix = XMMatrixLookAtLH(positionVector, lookAtVector, upVector);
and I try to move the camera forward with this code:

pitchRadians = mRotationX * (M_PI / 180);
yawRadians = mRotationY * (M_PI / 180);

mPositionX += mForwardSpeed * sinf(yawRadians) * cosf(pitchRadians);
mPositionY += mForwardSpeed * -sinf(pitchRadians);
mPositionZ += mForwardSpeed * cosf(yawRadians) * cosf(pitchRadians);
The camera moves forward without issues. BUt after moving away from the starting position the rotation doesn't work anymore, I roll instead of yaw. Here is the code
for rotation with the mouse:

	if (keyDown && (mouseDiffX > 0))
	{
		mRightTurnSpeed += mFrameTime * 5.0f;

		if (mRightTurnSpeed > (mFrameTime * 0.1f))
		{
			mRightTurnSpeed = mFrameTime * 0.1f;
		}

		mRotationY += mouseDiffX * mRightTurnSpeed * mouseSensitivity;
	}
	else 
	{
		mRightTurnSpeed -= mFrameTime * 3.5f;

		if (mRightTurnSpeed < 0.0f)
		{
			mRightTurnSpeed = 0.0f;
		}
	}

	if (keyDown && (mouseDiffX < 0))
	{
		mLeftTurnSpeed += mFrameTime * 5.0f;

		if (mLeftTurnSpeed >(mFrameTime * 0.1f))
		{
			mLeftTurnSpeed = mFrameTime * 0.1f;
		}

		mRotationY -= (-1 * mouseDiffX) * mLeftTurnSpeed * mouseSensitivity;
	}
	else
	{
		mLeftTurnSpeed -= mFrameTime * 3.5f;

		if (mLeftTurnSpeed < 0.0f)
		{
			mLeftTurnSpeed = 0.0f;
		}
	}

	if (keyDown && (mouseDiffY > 0))
	{
		mLookDownSpeed += mFrameTime * 5.0f;

		if (mLookDownSpeed > (mFrameTime * 0.1f))
		{
			mLookDownSpeed = mFrameTime * 0.1f;
		}

		mRotationX += mouseDiffY * mLookDownSpeed * mouseSensitivity;
	}
	else
	{
		mLookDownSpeed -= mFrameTime * 2.0f;

		if (mLookDownSpeed < 0.0f)
		{
			mLookDownSpeed = 0.0f;
		}
	}

	if (keyDown && (mouseDiffY < 0))
	{
		mLookUpSpeed += mFrameTime * 5.0f;

		if (mLookUpSpeed > (mFrameTime * 0.1f))
		{
			mLookUpSpeed = mFrameTime * 0.1f;
		}

		mRotationX -= ( -1 * mouseDiffY) * mLookUpSpeed * mouseSensitivity;
	}
	else
	{
		mLookUpSpeed -= mFrameTime * 2.0f;

		if (mLookUpSpeed < 0.0f)
		{
			mLookUpSpeed = 0.0f;
		}
	}
What solved it for me was to remove this row in the camera class:

upVector = XMVector3TransformCoord(upVector, rotationMatrix);
After I remove that row of code after moving forward from the start position I can still yaw and pitch.

I would like to find out so that I know what I'm doing and not run into trouble further down the line of development.


Thanks in advance
//Toastmastern

Share this post


Link to post
Share on other sites

Take a look at my DX sample code for some ideas.

http://virtuallyprogramming.com/DirectX11/Tutorials/Tutorials.html

 

Either the Skybox or Blender Models with Serialized Class, either one should have examples of rotating objects and rotating cameras. Skybox might have slightly less complicated code. It's a progression with me adding more code to each one, but it's basically the same code in all those projects. I just start out more simple and build on it.

 

I think matrices are the way to go unless you have a really solid reason to do something else.

 

I'm going to suggest you watch the Vector, Matrix, and Gimbal Lock videos on my YouTube channel in that order. It's 4 hours of video, but it's well worth it if you don't have those subjects pretty much mastered. The Gimbal Lock video gets into the different ways of doing rotations and why the way people most often want to do it when they start out is the worst possible option.

 

One thing that may confuse you is that camera changes are all inverted compared to changes made to a object's world matrix. So, if you do a rotation for example on your view matrix, the rotation matrix probably needs to be inverted before you apply (multiply) it to your view matrix. Just be aware of that because otherwise you could easily get messed up by that.

 

But download my sample projects and look at what I'm doing there. It's setup to control the camera with either the keyboard or an XBox 360 controller. I have a personal vendetta against mice and refuse to use them. :-) So, you'll likely never see mouse control in any of my code. Still, XBox controller probably isn't that different. Whether you tell a controller to yaw the camera or a mouse, it's still yawing.

 

Here's the main movement code from my sample engine:

//=====================================================================================================================
//  Game::Update()
//
//    Purpose:
//        To do everything that needs to be done in one frame except draw stuff to the screen.
//
//    Input:
//        float TimeDelta - Amount of time that has passed since the last frame occured in milliseconds.
//
//    Output:
//        None.
//
//  Notes:
//        This is where most of your game code will be. It gets called every frame to change anything that needs to be changed
//    or done during that frame. It runs in a loop that needs to be called at least 30 times per second but there's nothing
//    to control how often it gets called. Things would move at unpredictable rates if we did not use TimeDelta to take in to
//    account the amount of time that has passed since the last frame.
//
//        We start out by processing the keyboard and game controller input to change the camera's position and direction. You
//    can also toggle full screen on and off.
//
//        The camera movement this frame is stored as a 3D vector that we treat more like a 2D vector. The facing normal should
//    point in the direction we want the camera to face. And as a normal should have a length of 1. Any movement during the
//    frame is cumulative from the various controls. When you move it uses either the CameraFacingNormal or a normal rotated 90
//    degrees away from the camera facing. It's basic vector addition to add the movement to the camera position.
//
//        XMMatrixLookAtRH is used to create a view matrix to simulate the camera every frame. Generally, I would say it is a
//    good idea to not continuously recreate the view matrix but it's easier then maintaining a view matrix between frames and
//    this is really early in this tutorial series.
//
//        Finally some very simple rigid animation is thrown in to show you not only how to do it, but that it can be done and how
//    easy it is to do. Experiment by turning the rotations off and on and changing their directions and speed.
//
//        The scene is lit with a simple Blinn-Phong shader that has "directional" lighting as opposed to point lights or
//    spot lights. Directional lighting is nothing more than a direction that the light shines in. It is a normalized vector
//    describing a direction and it has a color. That's all it is. Look at the shader for more detail. By rotating that direction
//    the light source seems to orbit the scene similar to a day and night cycle except the light shines through solid objects.
//
//=====================================================================================================================
void Game::Update(float TimeDelta)
{
    XMVECTOR LookAtVector;                                        //Position for camera to look at.
    XMVECTOR CameraLocation;                                    //Where the camera is positioned.
    XMVECTOR CameraMovement = XMVectorZero();                    //The change in position this frame as a 3D vector.
    DWORD Controller1StateResult = XInputGetState(0, &Controller1State);    //XBox 360 controller state.
    float ThumbLHorizontal;                                        //Controller Left Thumb Horizontal value;
    float ThumbLVertical;                                        //Controller Left Thumb Vertical value;
    float ThumbRHorizontal;                                        //Controller Right Thumb Horizontal value;
    float ThumbRVertical;                                        //Controller Right Thumb Vertical value;


    if (!Keyboard.Update()) PostQuitMessage(0);    //If DirectInput has crashed, go ahead and shutdown the app. Otherwise, get the current keyboard state.

    if (Controller1StateResult == ERROR_SUCCESS)    //If there is an XBox360 controller plugged in...
    {
        if(Controller1State.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) PostQuitMessage(0);        //Close the program if the Back button on the controller is pressed.

        ThumbLHorizontal = (float) Controller1State.Gamepad.sThumbLX/32768.0f;    //Get Controller's current Left Thumb horizontal value.
        ThumbLVertical = (float) Controller1State.Gamepad.sThumbLY/32768.0f;    //Get Controller's current Left Thumb vertical value.
        ThumbRHorizontal = (float) Controller1State.Gamepad.sThumbRX/32768.0f;    //Get Controller's current Left Thumb horizontal value.
        ThumbRVertical = (float) Controller1State.Gamepad.sThumbRY/32768.0f;    //Get Controller's current Left Thumb vertical value.

        if (ThumbLVertical > 0.2f || ThumbLVertical < -0.2f)
            CameraMovement = CameraFacingNormal * ThumbLVertical;        //Left thumb vert moves forward and back. CameraFacing is a vector and multiplying increases its length which is the speed here.
        if (ThumbLHorizontal > 0.2f || ThumbLHorizontal < -0.2f)
            CameraMovement += XMVector4Transform(CameraFacingNormal, XMMatrixRotationZ(XM_PIDIV2)) * ThumbLHorizontal;    //Move camera left or right. Pi over 2 is a quarter circle. So, this says that in addition to any other movement this frame, move in a direction 90 degrees away from the direction being faced by an amount of whatever the Horizontal Left thumb value is.
        if (ThumbRVertical > 0.2f || ThumbRVertical < -0.2f)
            CameraTilt += (ThumbRVertical * -0.001f * TimeDelta);
        if (ThumbRHorizontal > 0.3f || ThumbRHorizontal < -0.3f)
             CameraFacingNormal = XMVector4Transform(CameraFacingNormal, XMMatrixRotationZ(ThumbRHorizontal * 0.0010f * TimeDelta));    //Rotate camera.
    }

    
    if (Keyboard.KeyPressed(DIK_LSHIFT))    //If these keys are pressed while the left shift key is pressed...
    {
        if (Keyboard.KeyPressed(DIK_D)) CameraMovement += XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(XM_PIDIV2));    //Move right. Pi over 2 is 90 degrees.
        if (Keyboard.KeyPressed(DIK_A)) CameraMovement += XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(-XM_PIDIV2));    //Move left.
    }
    else
    {
        if (Keyboard.KeyPressed(DIK_ESCAPE)) PostQuitMessage(0);    //Stop program if escape is pressed.
        if (Keyboard.KeyPressed(DIK_W)) CameraMovement = CameraFacingNormal;        //Move forward.
        if (Keyboard.KeyPressed(DIK_S)) CameraMovement = -CameraFacingNormal;        //Move backward.
        if (Keyboard.KeyPressed(DIK_D))
        {
            CameraFacingNormal = XMVector4Transform(CameraFacingNormal, XMMatrixRotationZ(0.0010f * TimeDelta));    //Spin right.
        }
        if (Keyboard.KeyPressed(DIK_A)) CameraFacingNormal = XMVector4Transform(CameraFacingNormal,XMMatrixRotationZ(-0.0010f * TimeDelta));//Spin left.
        if (Keyboard.KeyPressed(DIK_E)) CameraTilt += (-0.001f * TimeDelta);    //Look up.
        if (Keyboard.KeyPressed(DIK_Q)) CameraTilt += (0.001f * TimeDelta);        //Look down.
        if (Keyboard.KeyPressed(DIK_I)) YellowCube.Transform(XMMatrixTranslation(0.0f, 0.0f, 0.01f));        //Move the Yellow Cube forward down the Z axis.
        if (Keyboard.KeyPressed(DIK_K)) YellowCube.Transform(XMMatrixTranslation(0.0f, 0.0f, -0.01f));        //Move the Yellow Cube backward down the Z axis.
    }
    
    if (Keyboard.KeyPressed(DIK_RALT))        //If the right Alt key is pressed...
    {
        if(Keyboard.KeyPressed(DIK_RETURN) )    //If return is pressed...
        {
            //Toggle between full screen and windowed mode.
            if(InFullScreenMode)
            {
                SwapChain->SetFullscreenState(false, NULL);
                InFullScreenMode = false;
            }
            else
            {
                SwapChain->SetFullscreenState(true, NULL);
                InFullScreenMode = true;
            }
        }
    }

    CameraPosition += CameraMovement * TimeDelta * 0.002f;    //Add the camera movement this frame scaled up or down by the amount of time that has passed since the last frame and a scale number you can change to the current camera position to give a new position.

    CameraLocation = XMVectorSet(XMVectorGetX(CameraPosition), CameraHeight, XMVectorGetY(CameraPosition), 1.0f);    //Throw away the height value of the CameraPosition and use the CameraHeight for the Y value.
    LookAtVector = CameraLocation + XMVectorSet(XMVectorGetX(CameraFacingNormal), 0.0f, XMVectorGetY(CameraFacingNormal), 1.0f);    //Camera should look at a spot that is in the direction of CameraFacingNormal (ignoring any Y value) and the distance in front of the camera position that is the length of CameraFacingNormal.
    
    View = XMMatrixLookAtRH(CameraLocation, LookAtVector, XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f));    //Create a right handed LookAt matrix for our view matrix putting the camera at CameraLocation looking towards the LookAt point and using the cheat for the Up direction.
    if (CameraTilt > XM_PIDIV2) CameraTilt = XM_PIDIV2;        //Don't allow the camera to tilt beyond 90 degrees upward.
    if (CameraTilt < -XM_PIDIV2) CameraTilt = -XM_PIDIV2;    //Don't allow the camera to tilt beyond 90 degrees downward.
    View = View * XMMatrixRotationX(CameraTilt);            //Apply camera tilt.

    Triangle.TransformAtOrigin(XMMatrixRotationY(0.001f * TimeDelta));    //Make the triangle spin by a constant rate regardless of frame rate.
    YellowCube.TransformAtOrigin(XMMatrixRotationY(-0.001f * TimeDelta));    //Make the yellow cube spin.
    //Move the model just for the fun of it.
    DirectX::XMMATRIX ModelRootMatrix = DirectX::XMLoadFloat4x4(&Model.Root.World);
    ModelRootMatrix *= XMMatrixTranslation(0.f, 0.f, -0.001f);    
    DirectX::XMStoreFloat4x4(&Model.Root.World, ModelRootMatrix);
    
}
//=====================================================================================================================

 

 

Actually, now that I look at this I think I like my newer camera for OpenGL a lot better. Over the years, I've gone to using straight matrices more and more and more. I used to be really big on vectors, but as time has gone by I've gotten where I try to keep everything in matrices. The big thing that I really don't like about my DX code here is that I use LookAt(), especially every frame.

 

Here's basically the same code for OpenGL:

//=====================================================================================================================
//  Game::Update()
//
//    Purpose:
//        To do everything that needs to be done in one frame except draw stuff to the screen.
//
//    Input:
//        float TimeDelta - Amount of time that has passed since the last frame occured in milliseconds.
//
//    Output:
//        None.
//
//  Notes:
//        This is where most of your game code will be. It gets called every frame to change anything that needs to be changed
//    or done during that frame. It runs in a loop that needs to be called at least 30 times per second but there's nothing
//    to control how often it gets called. Things would move at unpredictable rates if we did not use TimeDelta to take in to
//    account the amount of time that has passed since the last frame.
//
//        We start out by processing the keyboard and game controller input to change the camera's position and direction. You
//    can also toggle full screen on and off.
//
//        The camera movement this frame is stored as a 3D vector that we treat more like a 2D vector. The facing normal should
//    point in the direction we want the camera to face. And as a normal should have a length of 1. Any movement during the
//    frame is cumulative from the various controls. When you move it uses either the CameraFacingNormal or a normal rotated 90
//    degrees away from the camera facing. It's basic vector addition to add the movement to the camera position.
//
//        XMMatrixLookAtRH is used to create a view matrix to simulate the camera every frame. Generally, I would say it is a
//    good idea to not continuously recreate the view matrix but it's easier then maintaining a view matrix between frames and
//    this is really early in this tutorial series.
//
//        Finally some very simple rigid animation is thrown in to show you not only how to do it, but that it can be done and how
//    easy it is to do. Experiment by turning the rotations off and on and changing their directions and speed.
//
//        The scene is lit with a simple Blinn-Phong shader that has "directional" lighting as opposed to point lights or
//    spot lights. Directional lighting is nothing more than a direction that the light shines in. It is a normalized vector
//    describing a direction and it has a color. That's all it is. Look at the shader for more detail. By rotating that direction
//    the light source seems to orbit the scene similar to a day and night cycle except the light shines through solid objects.
//
//=====================================================================================================================
void Game::Update()
{
    const float MaxTiltAngle = glm::radians(45.0);
    const unsigned char* Buttons;
    int JoyStick1Present = false;
    int NumberOfJoyStickAxes = 0;
    int NumberOfJoyStickButtons = 0;
    const float* AxesArray = nullptr;
    float LeftThumbStickY = 0.0f;
    float LeftThumbStickX = 0.0f;
    float Triggers = 0.0f;    //XBox 360 controller triggers are a single axis for both triggers. Positive = Left. Negative = Right.
    float RightThumbStickY = 0.0f;
    float RightThumbStickX = 0.0f;
    bool AButton = false;
    bool BButton = false;
        
    glm::vec3 CameraMovement = glm::vec3(0.0f, 0.0f, 0.0f);
    glm::vec3 CameraLocation = glm::vec3(0.0f, 0.0f, 0.0f);
    glm::vec3 LookAtVector = glm::vec3(0.0f, 0.0f, 0.0f);

    if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_ESCAPE && OperatingSystem.Keyboard.ActionPressed == GLFW_PRESS) OperatingSystem.ShutDown();
    
    JoyStick1Present = glfwJoystickPresent(GLFW_JOYSTICK_1);
    if (JoyStick1Present)
    {
        AxesArray = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &NumberOfJoyStickAxes);
        Buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &NumberOfJoyStickButtons);
        LeftThumbStickY = AxesArray[0];
        LeftThumbStickX = AxesArray[1];
        Triggers = AxesArray[2];
        RightThumbStickY = AxesArray[3];
        RightThumbStickX = AxesArray[4];

        //Camera Controls with XBox 360 controller.
        if (RightThumbStickX > 0.2 || RightThumbStickX < -0.2) View = glm::rotate(glm::mat4(), RightThumbStickX *0.06f, glm::vec3(0.0f, 1.0f, 0.0f)) * View;
        if (LeftThumbStickX > 0.2 || LeftThumbStickX < -0.2) View = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, -LeftThumbStickX * 0.1f)) * View;    //*0.1f to slow it down. Negative to flip the axis. -0.2 for deadzone.

        if (RightThumbStickY > 0.2 || RightThumbStickY < -0.2) CameraTilt += 0.03 * RightThumbStickY;
        if (LeftThumbStickY > 0.2 || LeftThumbStickY < -0.2) View = glm::translate(glm::mat4(), glm::vec3(-LeftThumbStickY * 0.1f, 0.0f, 0.0f)) * View;

        if (Buttons[0] == '\x1') AButton = true;
        if (Buttons[1] == '\x1') BButton = true;
        if (Buttons[6] == '\x1') OperatingSystem.ShutDown();
    }


        //Camera Controls with keyboard.
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_W && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.05f)) * View;
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_S && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -0.05f)) * View;
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_E && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            CameraTilt += 0.1;
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_Q && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            CameraTilt -= 0.1;
        if (OperatingSystem.Keyboard.ModePressed == GLFW_MOD_SHIFT)
        {
            //Keys while Shift keys are also held down.
            if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_A && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
                View = glm::translate(glm::mat4(), glm::vec3(0.1f, 0.0f, 0.0f)) * View;
            if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_D && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
                View = glm::translate(glm::mat4(), glm::vec3(-0.1f, 0.0f, 0.0f)) * View;
        }
        else
        {
            //Keys when shift keys are not being held down.
            if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_D && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            View = glm::rotate(glm::mat4(1.0f), 0.05f, glm::vec3(0.0f, 1.0f, 0.0f)) * View;
            if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_A && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            View = glm::rotate(glm::mat4(1.0f), -0.05f, glm::vec3(0.0f, 1.0f, 0.0f)) * View;
        }
        
        
        //Yellow cube controls.
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_I && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            Cube.Transform(glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, 0.05f)));
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_K && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            Cube.Transform(glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, -0.05f)));
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_L && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            Cube.Transform(glm::rotate(glm::mat4(), glm::radians<float>(-1), glm::vec3(0.0f, 1.0f, 0.0f)));
        if (OperatingSystem.Keyboard.KeyPressed == GLFW_KEY_J && OperatingSystem.Keyboard.ActionPressed != GLFW_RELEASE)
            Cube.Transform(glm::rotate(glm::mat4(), glm::radians<float>(1), glm::vec3(0.0f, 1.0f, 0.0f)));


        if (CameraTilt > MaxTiltAngle) CameraTilt = MaxTiltAngle;
        if (CameraTilt < -MaxTiltAngle) CameraTilt = -MaxTiltAngle;
        
        Triangle.Transform(glm::rotate(glm::mat4(), glm::radians<float>(1), glm::vec3(0.0f, 1.0f, 0.0f)));


    
}
//=====================================================================================================================

 

I use the view matrix to store the camera orientation and position, but I wanted to limit the angle at which this first person camera can pitch up or down. So, I don't allow pitch with the view matrix (or roll since it's a 1st person camera). I apply pitch right before I draw every frame.

 

//=====================================================================================================================
//  Game::Draw()
//
//    Purpose:
//        To do draw a single frame on the computer screen.
//
//    Input:
//        float TimeDelta - Amount of time that has passed since the last frame occured in milliseconds.
//
//    Output:
//        None.
//
//  Notes:
//        Since all the drawing code is tucked away neatly elsewhere, this method ends up being very short and sweet. There's
//    basically nothing to it. The first two lines clear the backbuffer in corn flower blue which is a constant. And then
//    it clears the depth stencil. You can clear the screen in any color you like.
//
//        Then each game object's Draw() method needs to be called to tell it to draw it self to the back buffer. The parameters
//    for the shader have to be sent here.
//
//        Finaly, the swapchain is told to make the backbuffer the frontbuffer and draw it to the screen by presenting it and
//    the image appears on the computer monitor.
//
//=====================================================================================================================
void Game::Draw()
{
    glm::mat4 TiltedView = glm::rotate(glm::mat4(), CameraTilt, glm::vec3(1.0, 0.0, 0.0)) * View;


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
    Triangle.Draw(TiltedView, Projection, &Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
    Cube.Draw(TiltedView, Projection, &Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
    Ground.Draw(TiltedView, Projection, &Shader, DiffuseLightDirection, AmbientLightColor, DiffuseLightColor);
}
//=====================================================================================================================

 

I use the "TiltedView" matrix instead of the view matrix when I actually go to draw. And that's just the view matrix rotated by the pitch angle. The pitch angle itself is just a floating point radians amount. If I had of done this just as the view matrix and allowed a pitch rotation directly, it could have pitched 360 degrees over, which would be unusual for a 1st person camera.

 

But notice that in the OGL version I only call the LookAt method once, at startup. And the view matrix holds the camera orientation and position after that. Here's the initialization code:

 

    CameraHeight = 1.68f;        //Roughly the average eye height in meters of an average man. Our camera will stay at this level to make it feel like we are in the scene.
    CameraTilt = 0.0f;            //Will tilt the camera up and down.

    GameObjectInitializedProperly = true; //This should probably be set by error checking, but we don't have any error checking here.
    View = glm::lookAt(glm::vec3(0.0f, CameraHeight, 2.0f), glm::vec3(0.0f, CameraHeight, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));    //1.63 meters is roughly the height of the average man's eyes.
    //Projection = glm::perspective(0.96f, 1.770833f, 0.1f, 700.0f);    //0.96 is 55 degrees and 1.7708333 is the width to height ratio on my computer.
    Projection = glm::perspective(0.96f, OperatingSystem.AspectRatio(), 0.1f, 700.0f);    //0.96 is 55 degrees and 1.7708333 is the width to height ratio on my computer.
 
Edited by BBeck

Share this post


Link to post
Share on other sites

Thanks for the reply, 

 

I believe as I learn more and more I will move away from the LookAtLH function that I'm using right now to build my own view matrix. I will look at your code more in detail tonight when I get back from work :)

 

Once again thanks for taking your time!

Share this post


Link to post
Share on other sites

I'm always glad to help!

 

I'm kInd of glancing over my code and I notice that I'm using LookAtRH. I should probably point out that I decided to use a right handed coordinate system instead of left because that's what I was used to having come from XNA previously, plus (and this was a big plus) OpenGL uses a right handed coordinate system by default. I know this is against DX's default but it's basically the same thing as long as you pick one and stick with it. I was planning to continue on to OGL, and so I felt it made really good sense for me to use a right handed system. Just be aware that that itself will make all the code backwards from a left handed coordinate system.

Edited by BBeck

Share this post


Link to post
Share on other sites

I'm always glad to help!

 

I think I know Vectors pretty good but Matrixes is a totaly different story for me :) I will look throught the 4h of videos your videos before continueing. Hopefully in the end I will have a clearer grasp about it.

 

I thought my upVector got updated  when I used the transformcoord function together with the rotation matrix, but that might not be the case, learning by doing I guess :) I base that guess on that when I removed the transform of the upVector the rotation with the mouse worked flawless but then I couldn't get the rightVector since that one is the cross product between the upVector and forwardVector(the rotation vector) so I need to transform the upVector, just need to figure out why my mouse rotation won't work after I move forward :)

 

//Toastmastern

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!