Cogs.Core
CameraUtils.h
1#pragma once
2
3#include "CameraHelper.h"
4#include "Math/Projection.h"
5
6
19{
28 template<class TransformComponent, class OrbitingCameraController>
29 inline glm::quat getCameraOrientation(const TransformComponent transformComponent, const OrbitingCameraController orbitingCameraController)
30 {
31 glm::quat orientation;
32 if (orbitingCameraController) {
33 orientation = Cogs::Utility::CameraHelper::getOrientation(orbitingCameraController->horizontalAngle, orbitingCameraController->verticalAngle);
34 }
35 else {
36 orientation = transformComponent->rotation;
37 }
38
39 return orientation;
40 }
41
55 template<class CameraComponent, class TransformComponent, class OrbitingCameraController, typename ProjectionMode>
56 inline glm::dvec3 viewAll(const CameraComponent cameraComponent, const TransformComponent transformComponent, const OrbitingCameraController orbitingCameraController, const ProjectionMode projectionMode, const Cogs::Geometry::DBoundingBox& boundingBox, glm::vec2 viewport = glm::vec2(0.0f, 0.0f))
57 {
58 float fieldOfView = cameraComponent->fieldOfView;
59 glm::quat orientation = Cogs::Utility::CameraUtils::getCameraOrientation(transformComponent, orbitingCameraController);
60 glm::dvec3 position = Cogs::Utility::CameraHelper::getViewAllPosition(boundingBox, orientation, fieldOfView, viewport);
61 float focalDistance = Cogs::Utility::CameraHelper::getFocalDistance(position, boundingBox);
62 if (orbitingCameraController) {
63 const glm::dvec3 center = Cogs::Utility::CameraHelper::getCenter(boundingBox);
64 orbitingCameraController->cameraTarget = center;
65 orbitingCameraController->distance = focalDistance;
66 orbitingCameraController->setChanged();
67 }
68 else {
69 transformComponent->coordinates = position;
70 transformComponent->position = glm::vec3(0, 0, 0);
71 transformComponent->setChanged();
72 }
73
74 const float farDistance = Cogs::Utility::CameraHelper::getFarDistance(position, boundingBox);
75 const float oldFarDistance = cameraComponent->farDistance;
76 if (oldFarDistance < farDistance) {
77 cameraComponent->farDistance = farDistance;
78 }
79
80 cameraComponent->focalDistance = focalDistance;
81
82 if (projectionMode == ProjectionMode::Orthographic) {
83 cameraComponent->orthoHeight = Cogs::Utility::CameraHelper::getOrthoHeight(boundingBox);
84 }
85
86 cameraComponent->setChanged();
87
88 return position;
89 }
90
102 template<class CameraData>
103 inline bool getProjectedCoordinates(const glm::vec2& coordinatesToProject, const CameraData& cameraData, const glm::vec3& targetPlaneNormal, const glm::vec3& targetPlanePosition, glm::vec3& projectedCoordinates)
104 {
105 glm::vec3 planeNormal = targetPlaneNormal;
106 if (planeNormal.x == 0.f && planeNormal.y == 0.f && planeNormal.z == 0.f) {
107 planeNormal = -glm::vec3(cameraData.inverseViewMatrix[2]);
108 }
109
110 const glm::vec3 cameraPosition = glm::vec3(cameraData.inverseViewMatrix[3]);
111 glm::mat4 invViewProj = glm::inverse(cameraData.rawProjectionMatrix * cameraData.viewMatrix);
112 float nx = ((2.0f * (static_cast<float>(coordinatesToProject.x) / cameraData.viewportSize.x)) - 1.0f);
113 float ny = -((2.0f * (static_cast<float>(coordinatesToProject.y) / cameraData.viewportSize.y)) - 1.0f);
114 glm::vec4 nearPlaneHit = invViewProj * glm::vec4(nx, ny, -1.f, 1.f);
115 glm::vec3 rayOrigin = (1.f / nearPlaneHit.w)*glm::vec3(nearPlaneHit);
116 glm::vec4 farPlaneHit = invViewProj * glm::vec4(nx, ny, 1.f, 1.f);
117
118 if (farPlaneHit.w == 0) {
119 farPlaneHit.w = glm::epsilon<float>();
120 }
121 glm::vec3 rayDirection = glm::normalize((1.f / farPlaneHit.w)*glm::vec3(farPlaneHit) - rayOrigin);
122 float t;
123 bool intersects = Cogs::Geometry::projectToPlane(rayOrigin, rayDirection, targetPlanePosition, planeNormal, projectedCoordinates, &t);
124 bool isInFrontOfCamera = t + glm::distance(cameraPosition, rayOrigin) >= 0;
125
126 return intersects && isInFrontOfCamera;
127 }
128}
COGSCORE_DLL_API float getOrthoHeight(const Cogs::Geometry::DBoundingBox &boundingBox)
Calculate Orthographic camera orthoHeight Field to view boundingbox.
COGSCORE_DLL_API glm::dvec3 getViewAllPosition(const Cogs::Geometry::DBoundingBox &boundingBox, const glm::quat &orientation, float fieldOfView, glm::vec2 viewport)
COGSCORE_DLL_API glm::dvec3 getCenter(const Cogs::Geometry::DBoundingBox &boundingBox)
Gets center of non-empty bounding box.
COGSCORE_DLL_API float getFocalDistance(const glm::dvec3 &position, const Cogs::Geometry::DBoundingBox &boundingBox)
Gets distance from given position (camera position) to center of bounding box.
COGSCORE_DLL_API float getFarDistance(const glm::dvec3 &position, const Cogs::Geometry::DBoundingBox &boundingBox)
Gets camera far distance given bounding box.
COGSCORE_DLL_API glm::quat getOrientation(float horizontalAngle, float verticalAngle)
Gets the camera orientation from the horizontal and vertical angle values.
Contains common operations for camera setup.
Definition: CameraUtils.h:19
bool getProjectedCoordinates(const glm::vec2 &coordinatesToProject, const CameraData &cameraData, const glm::vec3 &targetPlaneNormal, const glm::vec3 &targetPlanePosition, glm::vec3 &projectedCoordinates)
Project a screen coordinate onto a plane in 3d space.
Definition: CameraUtils.h:103
glm::dvec3 viewAll(const CameraComponent cameraComponent, const TransformComponent transformComponent, const OrbitingCameraController orbitingCameraController, const ProjectionMode projectionMode, const Cogs::Geometry::DBoundingBox &boundingBox, glm::vec2 viewport=glm::vec2(0.0f, 0.0f))
View all for given bounding box.
Definition: CameraUtils.h:56
glm::quat getCameraOrientation(const TransformComponent transformComponent, const OrbitingCameraController orbitingCameraController)
Definition: CameraUtils.h:29