codesamples >> crossplatform camera class

Crossplatform: Camera class

Project:

Crossplatform application (Windows & PS3)

Engine:

Custom

Code language:

C++

Class description:

A rotating camera system to view the objects from various angles for Windows and PS3.

Camera.cpp

#include "Camera.h"
#include "string.h"
#include "math.h"

#if defined(WIN32)
// Win32 code
Camera::Camera(UINT width, UINT height): m_ClientWndWidth(width), m_ClientWndHeight(height)
{
	m_Eye.x = 0.0f;	
	m_Eye.y = 0.0f;	
	m_Eye.z = 100.0f;		
	m_Eye.w = 0.0f;

	m_At.x = 0.0f;		
	m_At.y = 0.0f;		
	m_At.z = 0.0f;		
	m_At.w = 0.0f;

	InitCamera();
}

Camera::~Camera()
{
	if(m_pCBNeverChanges) m_pCBNeverChanges->Release();
	if(m_pCBChangeOnResize) m_pCBChangeOnResize->Release();
	if(m_pCBChangesEveryFrame) m_pCBChangesEveryFrame->Release();
}
#endif

// gets the distance between a given point and the camera
float Camera::GetDistanceToPoint(float x, float y, float z)
{
	// uses the distance formula by taking the square of the combined
	// powers of the differences in position between two points
	return sqrt(pow(x - m_Eye.x, 2) + pow(y - m_Eye.y, 2) + pow(z - m_Eye.z, 2));
}

// update per frame
void Camera::Update(float deltaTime)
{
	// variable used for time based rotation
	float x = 0.15f * deltaTime;

	// calculation the camera's circular movement around its target using trig
	float newX = m_Eye.x * cos(x) - m_Eye.z * sin(x);
	float newY = m_Eye.x * sin(x) + m_Eye.z * cos(x);

	// setting the new position values
	m_Eye.x = newX;
	m_Eye.z = newY;

	// re-initialize the camera because the position has changed
	InitCamera();
}

#if defined(PS3)
// PS3 code
Camera::Camera()
{
	m_Eye.x = 0.0f;	
	m_Eye.y = 0.0f;	
	m_Eye.z = 100.0f;		
	m_Eye.w = 0.0f;

	m_At.x = 0.0f;		
	m_At.y = 0.0f;		
	m_At.z = 0.0f;		
	m_At.w = 0.0f;

	InitCamera();
	InitProjectionMatrix();
}

Camera::~Camera()
{
}

void Camera::InitProjectionMatrix()
{
	// Transform
	float P[16];
	float V[16];

	// projection 
	BuildGLProjection(P, -1.0f, 1.0f, -1.0f, 1.0f, 1.0, 10000.0f); 

	// 16:9 scale
	MatrixTranslate(V, 0.0f, 0.0f, 0.0);
	V[0*4 + 0] = 9.0f / 16.0f; 
	V[1*4 + 1] = 1.0f; 

	// model view 
	MatrixMul(m_MVP, P, V);

}
#endif

// initializes the camera
void Camera::InitCamera()
{
#ifdef WIN32
	// sets the position, target and up vectors
	XMVECTOR Eye = XMVectorSet( m_Eye.x, m_Eye.y, m_Eye.z, m_Eye.w);
	XMVECTOR At = XMVectorSet( m_At.x, m_At.y, m_At.z, m_At.w);
	XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );

	// view matrix
	m_View = XMMatrixLookAtLH( Eye, At, Up );

	// projection matrix
	m_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, 480 / (FLOAT)320, 0.01f, 10000.0f );
#elif defined PS3
	// sets the position, target and up vectors
	T_VECTOR4 Eye = VectorSet( m_Eye.x, m_Eye.y, m_Eye.z, m_Eye.w);
	T_VECTOR4 At = VectorSet( m_At.x, m_At.y, m_At.z, m_At.w);
	T_VECTOR4 Up = VectorSet( 0.0f, 1.0f, 0.0f, 0.0f );

	// view matrix
	m_View = XMMatrixLookAtLH( Eye, At, Up );
	
	// projection matrix
	InitProjectionMatrix();
#endif
}


#if defined(PS3)
void Camera::BuildGLProjection(float *M, const float top, const float bottom, 
const float left, const float right, const float near, const float far)
{
	memset(M, 0, 16*sizeof(float)); 

	M[0*4+0] = (2.0f*near) / -(right - left);
	M[1*4+1] = (2.0f*near) / (bottom - top);

	float A = (right + left) / (right - left);
	float B = (top + bottom) / (top - bottom);
	float C = -(far + near) / (far - near);
	float D = -(2.0f*far*near) / (far - near);

	M[0*4 + 2] = A;
	M[1*4 + 2] = B;
	M[2*4 + 2] = C;
	M[2*4 + 3] = D;
	M[3*4 + 2] = -1.0f; 
}

void Camera::MatrixMul(float *Dest, float *A, float *B)
{
	for (int i=0; i < 4; i++)
	{
		for (int j=0; j < 4; j++)
		{
			Dest[i*4+j] = A[i*4+0]*B[0*4+j] + A[i*4+1]*B[1*4+j] +
			A[i*4+2]*B[2*4+j] + A[i*4+3]*B[3*4+j];
		}
    }

}

void Camera::MatrixTranslate(float *M, const float x, const float y, const float z)
{
	memset(M, 0, sizeof(float)*16);
	M[0*4+3] = x;
	M[1*4+3] = y;
	M[2*4+3] = z;

	M[0*4+0] = 1.0f;
	M[1*4+1] = 1.0f;
	M[2*4+2] = 1.0f;
	M[3*4+3] = 1.0f;
}

void Camera::EulerRotate(float *M, const float Rx, const float Ry, const float Rz)
{
	const float Sx = sinf(Rx);
	const float Cx = cosf(Rx);

	const float Cy = cosf(Ry);
	const float Sy = sinf(Ry);

	const float Cz = cosf(Rz);
	const float Sz = sinf(Rz);

	// x * y * z order
	M[0*4+0] = Cy*Cz;
	M[0*4+1] = Cy*Sz;
	M[0*4+2] = -Sy;
	M[0*4+3] = 0.0f;

	M[1*4+0] = Sx*Sy*Cz - Cx*Sz;
	M[1*4+1] = Sx*Sy*Sz + Cx*Cz;
	M[1*4+2] = Sx*Cy;
	M[1*4+3] = 0.0f;

	M[2*4+0] = Cx*Sy*Cz + Sz*Sx;
	M[2*4+1] = Cx*Sy*Sz - Cz*Sx;
	M[2*4+2] = Cx*Cy;
	M[2*4+3] = 0.0f;
 
	M[3*4+0] = 0.0f;
	M[3*4+1] = 0.0f;
	M[3*4+2] = 0.0f;
	M[3*4+3] = 1.0f;
}
#endif

Camera.h

#ifndef _CAMERA_H
#define _CAMERA_H

#if defined(WIN32)
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <assert.h>
#include <vector>
#include "Structs.h"

// define what type to use for matrices
#define MATRIX XMMATRIX

#endif

#if defined(PS3)
#include "vectormath.h"
#include <vector>
#include "Structs.h"

// define what type to use for matrices
#define MATRIX T_MATRIX_44

#endif

struct T_Vector4
{
	float x, y, z, w;
};

class Camera
{
public:

	float GetDistanceToPoint(float x, float y, float z);
	MATRIX GetView(){return m_View;}
	MATRIX GetProjection(){return m_Projection;}
	void InitCamera();
	void Update(float deltaTime);

#if defined(WIN32)
	Camera(UINT width, UINT height);
	virtual ~Camera();

	ID3D11Buffer*& GetpCBNeverChanges(){return m_pCBNeverChanges;}
	ID3D11Buffer*& GetpCBChangeOnResize(){return m_pCBChangeOnResize;}
	ID3D11Buffer*& GetpCBChangesEveryFrame(){return m_pCBChangesEveryFrame;}

	// Needed to make you pass matrices
	static void* operator new (size_t size) { return _aligned_malloc(size, 16); }
	static void operator delete (void *p) { _aligned_free(p); }
#endif

#if defined(PS3)
	Camera();
	virtual ~Camera();

	// Functions
	void InitProjectionMatrix();
	void BuildGLProjection(float *M, const float top, const float bottom,
	const float left, const float right, const float near, const float far);
	void MatrixMul(float *Dest, float *A, float *B);
	void MatrixTranslate(float *M, const float x, const float y, const float z);
	void EulerRotate(float *M, const float Rx, const float Ry, const float Rz);
	float m_MVP[16];
#endif

private:
// Win32 Datamembers

	MATRIX  m_View, m_Projection;
	// vectors used for orientation and movement
	T_Vector4 m_Eye; 
	T_Vector4 m_At;

#if defined(WIN32)
	//MATRIX  m_View, m_Projection;
	UINT m_ClientWndWidth, m_ClientWndHeight;
	ID3D11Buffer* m_pCBNeverChanges;
	ID3D11Buffer* m_pCBChangeOnResize;
	ID3D11Buffer* m_pCBChangesEveryFrame;
#endif

// PS3 Datamembers
#if defined(PS3)
	MATRIX		m_CameraMatrix;
#endif

	Camera(const Camera& ref);
	Camera& operator=(const Camera& ref);
};

#endif