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