scimesh 0.3.2
Headless CPU-only 3D software renderer for scientific mesh visualization
Loading...
Searching...
No Matches
camera.cpp
Go to the documentation of this file.
1#include <scimesh/camera.h>
2#include <glm/gtc/matrix_transform.hpp>
3#include <glm/gtc/constants.hpp>
4#include <cmath>
5#include <stdexcept>
6
7namespace scimesh {
8
10 return glm::lookAt(eye, center, up);
11}
12
13Mat4 Camera::get_projection_matrix(float aspect_ratio, float near_plane, float far_plane) const {
15 if (aspect_ratio <= 0.0f) {
16 throw std::invalid_argument(
17 "aspect_ratio must be > 0 for perspective projection");
18 }
19 if (near_plane <= 0.0f) {
20 throw std::invalid_argument(
21 "near_plane must be > 0 for perspective projection");
22 }
23 if (far_plane <= near_plane) {
24 throw std::invalid_argument(
25 "far_plane must be > near_plane for perspective projection");
26 }
27 return glm::perspective(glm::radians(fov_degrees), aspect_ratio, near_plane, far_plane);
28 } else {
29 float dist = glm::length(eye - center);
30 if (dist < 1e-6f)
31 dist = 1.0f;
32 float half_h = dist;
33 float half_w = half_h * aspect_ratio;
34 return glm::ortho(-half_w, half_w, -half_h, half_h, near_plane, far_plane);
35 }
36}
37
38Camera camera_look_at(const Vec3 &center, float radius,
39 const Vec3 &direction, const Vec3 &up,
40 float fov_degrees, float margin,
41 ProjectionType projection) {
42 Camera cam;
43 cam.center = center;
44 cam.up = glm::normalize(up);
45 cam.fov_degrees = fov_degrees;
46 cam.projection = projection;
47 float fov_rad = glm::radians(fov_degrees);
48 float dist;
49 if (projection == ProjectionType::ORTHOGRAPHIC) {
50 dist = radius * margin;
51 } else {
52 dist = radius / std::sin(fov_rad * 0.5f) * margin;
53 }
54 cam.eye = center + glm::normalize(direction) * dist;
55 return cam;
56}
57
58Camera camera_fit_scene(const Scene &scene, const Vec3 &direction,
59 const Vec3 &up, float fov_degrees, float margin,
60 ProjectionType projection) {
61 Vec3 bmin(0.0f), bmax(0.0f);
62 scene.compute_bounding_box(bmin, bmax);
63 Vec3 center = (bmin + bmax) * 0.5f;
64 Vec3 dir = glm::normalize(direction);
65 if (projection == ProjectionType::ORTHOGRAPHIC) {
66 float extent = max_ortho_extent(bmin, bmax, center, dir);
67 return camera_look_at(center, extent, direction, up, fov_degrees, margin, projection);
68 } else {
69 float radius = perp_extent_radius(bmin, bmax, center, dir,
70 glm::radians(fov_degrees));
71 return camera_look_at(center, radius, direction, up, fov_degrees, margin, projection);
72 }
73}
74
75Camera camera_fit_mesh(const Mesh &mesh, const Vec3 &direction,
76 const Vec3 &up, float fov_degrees, float margin,
77 ProjectionType projection) {
78 Vec3 bmin(0.0f), bmax(0.0f);
79 mesh.compute_bounding_box(bmin, bmax);
80 Vec3 center = (bmin + bmax) * 0.5f;
81 Vec3 dir = glm::normalize(direction);
82 if (projection == ProjectionType::ORTHOGRAPHIC) {
83 float extent = max_ortho_extent(bmin, bmax, center, dir);
84 return camera_look_at(center, extent, direction, up, fov_degrees, margin, projection);
85 } else {
86 float radius = perp_extent_radius(bmin, bmax, center, dir,
87 glm::radians(fov_degrees));
88 return camera_look_at(center, radius, direction, up, fov_degrees, margin, projection);
89 }
90}
91
92Camera camera_orbit(const Camera &camera, const Vec3 &axis, float angle_degrees) {
93 Camera result = camera;
94 float angle_rad = glm::radians(angle_degrees);
95 Mat4 rotation = glm::rotate(Mat4(1.0f), angle_rad, axis);
96 Vec4 rotated_dir = rotation * Vec4(camera.eye - camera.center, 0.0f);
97 result.eye = camera.center + Vec3(rotated_dir);
98 Vec4 rotated_up = rotation * Vec4(camera.up, 0.0f);
99 result.up = glm::normalize(Vec3(rotated_up));
100 return result;
101}
102
103} // namespace scimesh
Camera definition and helper functions for view setup.
Camera camera_look_at(const Vec3 &center, float radius, const Vec3 &direction, const Vec3 &up, float fov_degrees, float margin, ProjectionType projection)
Create a camera that looks at a point from a given distance and direction.
Definition camera.cpp:38
glm::mat4 Mat4
4Ɨ4 floating-point matrix.
Definition types.h:65
glm::vec3 Vec3
3-component floating-point vector (xyz).
Definition types.h:46
Camera camera_fit_scene(const Scene &scene, const Vec3 &direction, const Vec3 &up, float fov_degrees, float margin, ProjectionType projection)
Create a camera that automatically frames an entire Scene.
Definition camera.cpp:58
Camera camera_fit_mesh(const Mesh &mesh, const Vec3 &direction, const Vec3 &up, float fov_degrees, float margin, ProjectionType projection)
Create a camera that automatically frames a single Mesh.
Definition camera.cpp:75
ProjectionType
The type of 3D→2D projection used by the camera.
Definition camera.h:23
@ ORTHOGRAPHIC
Orthographic projection: parallel lines stay parallel.
@ PERSPECTIVE
Perspective projection: objects farther away appear smaller.
float perp_extent_radius(const Vec3 &bmin, const Vec3 &bmax, const Vec3 &center, const Vec3 &dir, float fov_radians, float *out_dist=nullptr)
Compute the "perpendicular extent radius" of an axis-aligned bounding box relative to a view directio...
Definition camera.h:149
float max_ortho_extent(const Vec3 &bmin, const Vec3 &bmax, const Vec3 &center, const Vec3 &dir)
Compute the maximum perpendicular extent of an AABB from a view ray (for orthographic projection fram...
Definition camera.h:196
Camera camera_orbit(const Camera &camera, const Vec3 &axis, float angle_degrees)
Orbit the camera around its look-at point.
Definition camera.cpp:92
glm::vec4 Vec4
4-component floating-point vector (xyzw).
Definition types.h:52
A virtual camera that defines the viewpoint for rendering.
Definition camera.h:77
Mat4 get_view_matrix() const
Compute the view matrix (world → camera space).
Definition camera.cpp:9
ProjectionType projection
Which projection type to use.
Definition camera.h:99
Vec3 center
The point the camera looks at.
Definition camera.h:88
Vec3 up
The camera's "up" direction.
Definition camera.h:94
Vec3 eye
Camera position in world space.
Definition camera.h:82
float fov_degrees
Vertical field of view in degrees (perspective only).
Definition camera.h:109
Mat4 get_projection_matrix(float aspect_ratio, float near_plane, float far_plane) const
Compute the projection matrix (camera → clip space).
Definition camera.cpp:13
A 3D triangle mesh using an indexed face set representation.
Definition mesh.h:76
void compute_bounding_box(Vec3 &min_bound, Vec3 &max_bound) const
Compute the axis-aligned bounding box (AABB) of the mesh.
Definition mesh.h:289
A collection of Mesh objects to be rendered together.
Definition scene.h:57
void compute_bounding_box(Vec3 &min_bound, Vec3 &max_bound) const
Compute the combined axis-aligned bounding box of all meshes, after applying each mesh's placement tr...
Definition scene.h:152