Advertisement

Cam class won't work

Started by September 26, 2018 03:54 PM
3 comments, last by Zakwayda 6 years, 2 months ago

I found some camera code on the net and tried to use it. It was really old so I converted it and the wasd works but the mouse look doesn't. It's giving strange results. I was wondering if anyone can see something in the math thats wrong? Like in the pitch and yaw functions for example.


#include "CCamera.h"

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Default constructor
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
CCamera::CCamera()
{
	m_maxPitch =DirectX::XMConvertToRadians(89.0f);
	m_maxVelocity = 1.0f;
	m_invertY = false;
	m_enableYMovement = true;
	m_position = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	m_velocity = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	m_look = DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
	CreateProjectionMatrix(DirectX::XMConvertToRadians(45.0f), 1920.0f / 1080.0f, 1.0f, 1000.0f);
	Update();
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Creates the projection matrix.
Parameters:
[in] fov - Field of view
[in] aspect - Aspect ratio
[in] near - Near plane
[in] far - Far plane
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::CreateProjectionMatrix(float fov, float aspect, float nearPlane, float farPlane)
{
	m_fov = fov;
	m_aspect = aspect;
	m_nearPlane = nearPlane;
	m_farPlane = farPlane;
	m_projection = DirectX::XMMatrixPerspectiveFovLH(m_fov, m_aspect, m_nearPlane, m_farPlane);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Moves the camera forward and backward
Parameters:
[in] units - Amount to move
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::MoveForward(float units)
{
	if (m_enableYMovement)
	{
		DirectX::XMVECTOR vec = DirectX::XMVectorScale(m_look, units);
		m_velocity = DirectX::XMVectorAdd(m_velocity, vec);
	}
	else
	{
		DirectX::XMFLOAT3 look;
		DirectX::XMStoreFloat3(&look, m_look);

		DirectX::XMVECTOR moveVector = DirectX::XMVectorSet(look.x, look.y, look.z, 0.0f);

		moveVector = DirectX::XMVector3Normalize(moveVector);
		moveVector = DirectX::XMVectorScale(moveVector, units);
		moveVector = DirectX::XMVectorAdd(m_velocity, moveVector);
	}
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Moves the camera left and right
Parameters:
[in] units - Amount to move
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::Strafe(float units)
{
	DirectX::XMVECTOR scaledRight = DirectX::XMVectorScale(m_right, units);
	m_velocity = DirectX::XMVectorAdd(m_velocity, scaledRight);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Moves the camera up and down
Parameters:
[in] units - Amount to move
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::MoveUp(float units)
{
	if (m_enableYMovement)
	{
		DirectX::XMFLOAT3 vel;
		DirectX::XMStoreFloat3(&vel, m_velocity);

		m_velocity = DirectX::XMVectorSet(vel.x, vel.y + units, vel.z, 0.0f);
	}
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Yaw the camera around its Y-axis.
Parameters:
[in] radians - Radians to yaw.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::Yaw(float radians)
{
	if (radians == 0.0f)
	{
		return;
	}
	DirectX::XMMATRIX rotation;
	rotation = DirectX::XMMatrixRotationAxis(m_up, radians);
	m_right = DirectX::XMVector3TransformNormal(m_right, rotation);
	m_look = DirectX::XMVector3TransformNormal(m_look, rotation);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Pitch the camera around its X-axis.
Parameters:
[in] radians - Radians to pitch.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::Pitch(float radians)
{
	if (radians == 0.0f)
	{
		return;
	}

	radians = (m_invertY) ? -radians : radians;
	m_pitch -= radians;
	if (m_pitch > m_maxPitch)
	{
		radians += m_pitch - m_maxPitch;
	}
	else if (m_pitch < -m_maxPitch)
	{
		radians += m_pitch + m_maxPitch;
	}

	DirectX::XMMATRIX rotation;
	rotation = DirectX::XMMatrixRotationAxis(m_right, radians);
	m_up = DirectX::XMVector3TransformNormal(m_up, rotation);
	m_look = DirectX::XMVector3TransformNormal(m_look, rotation);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Roll the camera around its Z-axis.
Parameters:
[in] radians - Radians to roll.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::Roll(float radians)
{
	if (radians == 0.0f)
	{
		return;
	}

	DirectX::XMMATRIX rotation;
	rotation = DirectX::XMMatrixRotationAxis(m_look, radians);
	DirectX::XMVector3TransformNormal(m_right, rotation);
	DirectX::XMVector3TransformNormal(m_up, rotation);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Updates the camera and creates a new view matrix.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::Update()
{
	// Cap velocity to max velocity
	/*
	if (D3DXVec3Length(&m_velocity) > m_maxVelocity)
	{
		m_velocity = *(D3DXVec3Normalize(&m_velocity, &m_velocity)) * m_maxVelocity;
	}*/

	// Move the camera
	m_position = DirectX::XMVectorAdd(m_position, m_velocity);
	// Could decelerate here. I'll just stop completely.
	m_velocity = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

	m_lookAt = DirectX::XMVectorAdd(m_position, m_look);

	// Calculate the new view matrix
	DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
	m_view = DirectX::XMMatrixLookAtLH(m_position, m_lookAt, up);

	// Set the camera axes from the view matrix

	DirectX::XMFLOAT4X4 view;
	DirectX::XMStoreFloat4x4(&view, m_view);

	m_right = DirectX::XMVectorSet(view._11, view._21, view._31, 0.0f);
	m_up = DirectX::XMVectorSet(view._12, view._22, view._32, 0.0f);
	m_look = DirectX::XMVectorSet(view._13, view._23, view._33, 0.0f);

	// Calculate yaw and pitch

	DirectX::XMFLOAT3 look;
	DirectX::XMStoreFloat3(&look, m_look);

	float lookLengthOnXZ = sqrtf(look.z * look.z + look.x * look.x);
	m_pitch = atan2f(look.y, lookLengthOnXZ);
	m_yaw = atan2f(look.x, look.z);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Updates the camera and creates a new view matrix.
Parameters:
[in] pPosition - New position
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::SetPosition(DirectX::XMVECTOR* pPosition)
{

	DirectX::XMFLOAT3 pos;
	DirectX::XMStoreFloat3(&pos, *(pPosition));

	m_position = DirectX::XMVectorSet(pos.x, pos.y, pos.z, 0.0f);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Updates the camera and creates a new view matrix.
Parameters:
[in] pPosition - New target
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void CCamera::SetLookAt(DirectX::XMVECTOR* pLookAt)
{
	DirectX::XMFLOAT3 look;
	DirectX::XMStoreFloat3(&look, *(pLookAt));
	m_lookAt = DirectX::XMVectorSet(look.x, look.y, look.z, 0.0f);


	DirectX::XMFLOAT3 la;
	DirectX::XMFLOAT3 p;
	DirectX::XMStoreFloat3(&la, m_lookAt);
	DirectX::XMStoreFloat3(&p, m_position);

	DirectX::XMVECTOR combined = DirectX::XMVectorSubtract(m_lookAt, m_position);

	m_lookAt = DirectX::XMVector3Normalize(combined);
}

 

Based on a quick look, there are some things about that code that look suspicious to me (that's just based on a quick review though).

Two common modes for motion are so-called 6DOF, where you can rotate freely (typical in space simulations), and 'fixed up' motion with absolute yaw and pitch (often used for humanoid characters). Are you wanting one of these? Or do you have something else in mind? (An easy way to communicate the type of behavior you want might be to provide a link to a video of a game that implements that behavior.)

Advertisement

Atm I'm focusing on a camera like what's in Unity or Unreal...so 6DOF I think. I want a first person camera with wasd movement but also q and e to move up and down. I'm making a game editor.

I'm reading a game math book and slowly wrapping my head around how to do a camera myself but if anyone has any code that works I'll take it.   ?

6 hours ago, TommyThree said:

Atm I'm focusing on a camera like what's in Unity or Unreal...so 6DOF I think. I want a first person camera with wasd movement but also q and e to move up and down. I'm making a game editor.

Can't say for sure, but I think it's probably not 6DOF that you want. The kind of camera you typically find in editors like Unity's editor (if I recall correctly) is a fixed-up pitch-and-yaw-only 'free' camera, which isn't 6DOF.

As I mentioned before, I see multiple issues or potential issues with the code you posted. I think you'd be better off with a from-scratch implementation (or at least a different reference), although I realize if you're not comfortable with the underlying math yet you may not want to tackle an implementation yourself.

As for the code you posted, I'll just point out one thing:


void CCamera::Yaw(float radians)
{
    if (radians == 0.0f)
    {
        return;
    }
    DirectX::XMMATRIX rotation;
    rotation = DirectX::XMMatrixRotationAxis(m_up, radians);
    m_right = DirectX::XMVector3TransformNormal(m_right, rotation);
    m_look = DirectX::XMVector3TransformNormal(m_look, rotation);
}

Based on what I'm seeing in the rest of the code, I'd think this rotation should be performed around the vector (0, 1, 0) rather than m_up. I'm not sure if that change would be sufficient to get the code working how you want, but it would be easy to try.

Again though, I think there are issues with that implementation in general, and that you'd probably be better off using other code or implementing something from scratch.

This topic is closed to new replies.

Advertisement