Changeset View
Changeset View
Standalone View
Standalone View
source/graphics/Camera.cpp
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
CCamera::~CCamera() = default; | CCamera::~CCamera() = default; | ||||
void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov) | void CCamera::SetPerspectiveProjection(float nearp, float farp, float fov) | ||||
{ | { | ||||
m_NearPlane = nearp; | m_NearPlane = nearp; | ||||
m_FarPlane = farp; | m_FarPlane = farp; | ||||
m_FOV = fov; | m_FOV = fov; | ||||
const float aspect = static_cast<float>(m_ViewPort.m_Width) / static_cast<float>(m_ViewPort.m_Height); | m_ProjMat.SetPerspective(m_FOV, GetAspectRatio(), m_NearPlane, m_FarPlane); | ||||
m_ProjMat.SetPerspective(m_FOV, aspect, m_NearPlane, m_FarPlane); | |||||
} | } | ||||
void CCamera::SetPerspectiveProjectionTile(int tiles, int tile_x, int tile_y) | void CCamera::SetPerspectiveProjectionTile(int tiles, int tile_x, int tile_y) | ||||
{ | { | ||||
const float aspect = static_cast<float>(m_ViewPort.m_Width) / static_cast<float>(m_ViewPort.m_Height); | m_ProjMat.SetPerspectiveTile(m_FOV, GetAspectRatio(), m_NearPlane, m_FarPlane, tiles, tile_x, tile_y); | ||||
m_ProjMat.SetPerspectiveTile(m_FOV, aspect, m_NearPlane, m_FarPlane, tiles, tile_x, tile_y); | |||||
} | } | ||||
// Updates the frustum planes. Should be called | // Updates the frustum planes. Should be called | ||||
// everytime the view or projection matrices are | // everytime the view or projection matrices are | ||||
// altered. | // altered. | ||||
void CCamera::UpdateFrustum(const CBoundingBoxAligned& scissor) | void CCamera::UpdateFrustum(const CBoundingBoxAligned& scissor) | ||||
{ | { | ||||
CMatrix3D MatFinal; | CMatrix3D MatFinal; | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
void CCamera::SetViewPort(const SViewPort& viewport) | void CCamera::SetViewPort(const SViewPort& viewport) | ||||
{ | { | ||||
m_ViewPort.m_X = viewport.m_X; | m_ViewPort.m_X = viewport.m_X; | ||||
m_ViewPort.m_Y = viewport.m_Y; | m_ViewPort.m_Y = viewport.m_Y; | ||||
m_ViewPort.m_Width = viewport.m_Width; | m_ViewPort.m_Width = viewport.m_Width; | ||||
m_ViewPort.m_Height = viewport.m_Height; | m_ViewPort.m_Height = viewport.m_Height; | ||||
} | } | ||||
float CCamera::GetAspectRatio() const | |||||
{ | |||||
return static_cast<float>(m_ViewPort.m_Width) / static_cast<float>(m_ViewPort.m_Height); | |||||
} | |||||
elexis: (perhaps getViewPortAspectRatio, I dont mind) | |||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// | void CCamera::GetCameraPlanePoints(float dist, std::array<CVector3D, 4>& pts) const | ||||
// GetCameraPlanePoints: return four points in camera space at given distance from camera | { | ||||
void CCamera::GetCameraPlanePoints(float dist, CVector3D pts[4]) const | const float y = dist * tanf(m_FOV * 0.5f); | ||||
{ | const float x = y * GetAspectRatio(); | ||||
float aspect = float(m_ViewPort.m_Width)/float(m_ViewPort.m_Height); | |||||
float x = dist*aspect*tanf(m_FOV*0.5f); | |||||
float y = dist*tanf(m_FOV*0.5f); | |||||
pts[0].X = -x; | pts[0].X = -x; | ||||
pts[0].Y = -y; | pts[0].Y = -y; | ||||
pts[0].Z = dist; | pts[0].Z = dist; | ||||
pts[1].X = x; | pts[1].X = x; | ||||
pts[1].Y = -y; | pts[1].Y = -y; | ||||
pts[1].Z = dist; | pts[1].Z = dist; | ||||
pts[2].X = x; | pts[2].X = x; | ||||
pts[2].Y = y; | pts[2].Y = y; | ||||
pts[2].Z = dist; | pts[2].Z = dist; | ||||
pts[3].X = -x; | pts[3].X = -x; | ||||
pts[3].Y = y; | pts[3].Y = y; | ||||
pts[3].Z = dist; | pts[3].Z = dist; | ||||
Not Done Inline ActionsSince this function is called on Render, perhaps the GetAspectRatio should be cached. elexis: Since this function is called on `Render`, perhaps the `GetAspectRatio` should be cached. | |||||
} | } | ||||
void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const | void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const | ||||
{ | { | ||||
CVector3D cPts[4]; | // Coordinates relative to the camera plane. | ||||
GetCameraPlanePoints(m_FarPlane, cPts); | const float dx = (float)px / (float)g_Renderer.GetWidth(); | ||||
const float dy = 1 - (float)py / (float)g_Renderer.GetHeight(); | |||||
// transform to world space | std::array<CVector3D, 4> points; | ||||
CVector3D wPts[4]; | GetCameraPlanePoints(m_FarPlane, points); | ||||
for (int i = 0; i < 4; i++) | |||||
wPts[i] = m_Orientation.Transform(cPts[i]); | |||||
// get world space position of mouse point | // Transform from camera space to world space. | ||||
float dx = (float)px / (float)g_Renderer.GetWidth(); | for (int i = 0; i < 4; i++) | ||||
Not Done Inline Actions(Formally I wonder if the loop performance differs) elexis: (Formally I wonder if the loop performance differs) | |||||
float dz = 1 - (float)py / (float)g_Renderer.GetHeight(); | points[i] = m_Orientation.Transform(points[i]); | ||||
CVector3D vdx = wPts[1] - wPts[0]; | // Get world space position of mouse point at the far clipping plane. | ||||
CVector3D vdz = wPts[3] - wPts[0]; | CVector3D basisX = points[1] - points[0]; | ||||
CVector3D pt = wPts[0] + (vdx * dx) + (vdz * dz); | CVector3D basisY = points[3] - points[0]; | ||||
CVector3D targetPoint = points[0] + (basisX * dx) + (basisY * dy); | |||||
Not Done Inline Actions(why are the floats made const but not the vectors) elexis: (why are the floats made const but not the vectors) | |||||
// copy origin | |||||
origin = m_Orientation.GetTranslation(); | origin = m_Orientation.GetTranslation(); | ||||
// build direction | |||||
dir = pt - origin; | // Build direction for the camera origin to the target point. | ||||
dir = targetPoint - origin; | |||||
dir.Normalize(); | dir.Normalize(); | ||||
} | } | ||||
void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) const | void CCamera::GetScreenCoordinates(const CVector3D& world, float& x, float& y) const | ||||
{ | { | ||||
CMatrix3D transform = m_ProjMat * m_Orientation.GetInverse(); | CMatrix3D transform = m_ProjMat * m_Orientation.GetInverse(); | ||||
CVector4D screenspace = transform.Transform(CVector4D(world.X, world.Y, world.Z, 1.0f)); | CVector4D screenspace = transform.Transform(CVector4D(world.X, world.Y, world.Z, 1.0f)); | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | void CCamera::LookAlong(const CVector3D& camera, CVector3D orientation, CVector3D up) | ||||
CVector3D s = orientation.Cross(up); | CVector3D s = orientation.Cross(up); | ||||
m_Orientation._11 = -s.X; m_Orientation._12 = up.X; m_Orientation._13 = orientation.X; m_Orientation._14 = camera.X; | m_Orientation._11 = -s.X; m_Orientation._12 = up.X; m_Orientation._13 = orientation.X; m_Orientation._14 = camera.X; | ||||
m_Orientation._21 = -s.Y; m_Orientation._22 = up.Y; m_Orientation._23 = orientation.Y; m_Orientation._24 = camera.Y; | m_Orientation._21 = -s.Y; m_Orientation._22 = up.Y; m_Orientation._23 = orientation.Y; m_Orientation._24 = camera.Y; | ||||
m_Orientation._31 = -s.Z; m_Orientation._32 = up.Z; m_Orientation._33 = orientation.Z; m_Orientation._34 = camera.Z; | m_Orientation._31 = -s.Z; m_Orientation._32 = up.Z; m_Orientation._33 = orientation.Z; m_Orientation._34 = camera.Z; | ||||
m_Orientation._41 = 0.0f; m_Orientation._42 = 0.0f; m_Orientation._43 = 0.0f; m_Orientation._44 = 1.0f; | m_Orientation._41 = 0.0f; m_Orientation._42 = 0.0f; m_Orientation._43 = 0.0f; m_Orientation._44 = 1.0f; | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////////////////////// | |||||
// Render the camera's frustum | // Render the camera's frustum | ||||
void CCamera::Render(int intermediates) const | void CCamera::Render(int intermediates) const | ||||
{ | { | ||||
#if CONFIG2_GLES | #if CONFIG2_GLES | ||||
#warning TODO: implement camera frustum for GLES | #warning TODO: implement camera frustum for GLES | ||||
#else | #else | ||||
CVector3D nearPoints[4]; | std::array<CVector3D, 4> nearPoints; | ||||
CVector3D farPoints[4]; | std::array<CVector3D, 4> farPoints; | ||||
GetCameraPlanePoints(m_NearPlane, nearPoints); | GetCameraPlanePoints(m_NearPlane, nearPoints); | ||||
GetCameraPlanePoints(m_FarPlane, farPoints); | GetCameraPlanePoints(m_FarPlane, farPoints); | ||||
for(int i = 0; i < 4; i++) | for(int i = 0; i < 4; i++) | ||||
{ | { | ||||
nearPoints[i] = m_Orientation.Transform(nearPoints[i]); | nearPoints[i] = m_Orientation.Transform(nearPoints[i]); | ||||
farPoints[i] = m_Orientation.Transform(farPoints[i]); | farPoints[i] = m_Orientation.Transform(farPoints[i]); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
(perhaps getViewPortAspectRatio, I dont mind)