Cogs.Core
CameraHelper.cpp
1#include "CameraHelper.h"
2
3#include <cmath>
4
16{
17 glm::dvec3 CameraHelper::getCenter(const Cogs::Geometry::DBoundingBox& boundingBox)
18 {
19 glm::dvec3 center = (boundingBox.min + boundingBox.max) * 0.5;
20 return center;
21 }
22
23 float CameraHelper::getFarDistance(const glm::dvec3& position, const Cogs::Geometry::DBoundingBox& boundingBox)
24 {
25 float radius = getRadius(boundingBox);
26 return getFocalDistance(position, boundingBox) + radius;
27 }
28
29 float CameraHelper::getFocalDistance(const glm::dvec3& position, const Cogs::Geometry::DBoundingBox& boundingBox)
30 {
31 const glm::dvec3 center = getCenter(boundingBox);
32 float distance_to_midpoint = static_cast<float>(glm::length(position - center));
33 return distance_to_midpoint;
34 }
35
36 glm::quat CameraHelper::getOrientation(float horizontalAngle, float verticalAngle)
37 {
38 glm::quat horizontalRotation = glm::angleAxis(horizontalAngle, glm::vec3(0, 0, 1));
39 glm::quat verticalRotation = glm::angleAxis(verticalAngle, glm::vec3(1, 0, 0));
40 glm::quat rotation = horizontalRotation * verticalRotation;
41 return rotation;
42 }
43
44 float CameraHelper::getOrthoHeight(const Cogs::Geometry::DBoundingBox& boundingBox)
45 {
46 // Get the radius of the bounding sphere.
47 const float radius = getRadius(boundingBox);
48
49 const float orthoHeight = radius * 2;
50
51 return orthoHeight;
52 }
53
54 float CameraHelper::getRadius(const Cogs::Geometry::DBoundingBox& boundingBox)
55 {
56 const glm::dvec3 size = boundingBox.max - boundingBox.min;
57 const float radius = static_cast<float>(glm::length(size) / 2.0);
58 return radius;
59 }
60
61 glm::dvec3 CameraHelper::getFocalPosition(const glm::dvec3& position, const glm::quat& orientation, float focalDistance)
62 {
63 const glm::vec3 direction = orientation * glm::vec3(0, 0, -1);
64 glm::normalize(direction);
65 const glm::dvec3 result = position + glm::dvec3(direction * focalDistance);
66 return result;
67 }
68
69 glm::dvec3 CameraHelper::getViewAllPosition(const Cogs::Geometry::DBoundingBox& boundingBox,
70 const glm::quat& orientation, float fieldOfView, glm::vec2 viewport)
71 {
72 const float viewportWidth = viewport.x;
73 const float viewportHeight = viewport.y;
74
75 float aspect = 1.0f;
76 if ((viewportWidth > 0.0f) && (viewportHeight > 0.0f))
77 aspect = viewportWidth / viewportHeight;
78
79 // First, we want to move the camera in such a way that it is
80 // pointing straight at the center of the scene bounding box
81 const glm::vec3 cameraDirection = orientation * glm::vec3(0, 0, -1);
82 const glm::dvec3 center = getCenter(boundingBox);
83
84 // Get the radius of the bounding sphere.
85 const float radius = getRadius(boundingBox);
86
87 // Make sure that everything will still be inside the viewing volume
88 // even if the aspect ratio "favors" width over height.
89 const float aspectRadius = radius / (aspect < 1.0f ? aspect : 1.0f);
90
91 // Move the camera to the edge of the bounding sphere, while still
92 // pointing at the scene.
93 glm::vec3 direction = -cameraDirection;
94 glm::normalize(direction);
95
96 // There's a small chance that the frustum will intersect the
97 // bounding box when we calculate the movelength like this, but for
98 // all normal heightAngles it will yield a much better fit than
99 // the 100% safe version which also adds radius to movelength
100
101 const float movelength = aspectRadius / std::tan(fieldOfView / 2.0f);
102 const glm::dvec3 position = center + glm::dvec3(direction * movelength);
103 return position;
104 }
105}
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 getFocalPosition(const glm::dvec3 &position, const glm::quat &orientation, float focalDistance)
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 float getRadius(const Cogs::Geometry::DBoundingBox &boundingBox)
Gets the radius of the bounding sphere.
COGSCORE_DLL_API glm::quat getOrientation(float horizontalAngle, float verticalAngle)
Gets the camera orientation from the horizontal and vertical angle values.
Contains common utility members for camera setup Other camera utilities: Interpolation utilities can ...