scimesh 0.3.4
Headless CPU-only 3D software renderer for scientific mesh visualization
Loading...
Searching...
No Matches
camera.h
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <scimesh/types.h>
12#include <scimesh/scene.h>
13
14namespace scimesh {
15
16// ---------------------------------------------------------------------------
17// ProjectionType
18// ---------------------------------------------------------------------------
19
23enum class ProjectionType {
30
36};
37
38// ---------------------------------------------------------------------------
39// Camera
40// ---------------------------------------------------------------------------
41
77struct Camera {
82 Vec3 eye = Vec3(0.0f, 0.0f, 10.0f);
83
88 Vec3 center = Vec3(0.0f, 0.0f, 0.0f);
89
94 Vec3 up = Vec3(0.0f, 1.0f, 0.0f);
95
100
109 float fov_degrees = 45.0f;
110
117 Mat4 get_view_matrix() const;
118
125 Mat4 get_projection_matrix(float aspect_ratio, float near_plane, float far_plane) const;
126};
127
128// ---------------------------------------------------------------------------
129// Projection of world points into the image
130// ---------------------------------------------------------------------------
131
137 Vec2 pixel = Vec2(0.0f);
138
143 float depth = 1.0f;
144
149 bool in_front = false;
150};
151
183 int height, ProjectionType projection,
184 float near_plane, float far_plane);
185
186// ---------------------------------------------------------------------------
187// Camera helper functions
188// ---------------------------------------------------------------------------
189
207inline float perp_extent_radius(const Vec3 &bmin, const Vec3 &bmax,
208 const Vec3 &center, const Vec3 &dir,
209 float fov_radians, float *out_dist = nullptr) {
210 Vec3 corners[8] = {
211 Vec3(bmin.x, bmin.y, bmin.z), Vec3(bmax.x, bmin.y, bmin.z),
212 Vec3(bmin.x, bmax.y, bmin.z), Vec3(bmax.x, bmax.y, bmin.z),
213 Vec3(bmin.x, bmin.y, bmax.z), Vec3(bmax.x, bmin.y, bmax.z),
214 Vec3(bmin.x, bmax.y, bmax.z), Vec3(bmax.x, bmax.y, bmax.z),
215 };
216 float max_dist = 0.0f;
217 float half_tan = std::tan(fov_radians * 0.5f);
218 if (half_tan < 1e-6f) half_tan = 1e-6f;
219
220 for (int i = 0; i < 8; i++) {
221 Vec3 delta = corners[i] - center;
222 float along = glm::dot(delta, dir);
223 float perp_sq = glm::dot(delta, delta) - along * along;
224 float perp = std::sqrt(perp_sq);
225 // At the corner's depth (centre_z + along), required eye distance
226 // so that this corner stays inside the frustum:
227 // perp ≤ (dist - along) * tan(half_fov)
228 // ⇒ dist ≥ perp / tan(half_fov) + along
229 float d = perp / half_tan + along;
230 if (d > max_dist) max_dist = d;
231 }
232 if (max_dist < 1e-6f) max_dist = 1.0f;
233
234 if (out_dist) *out_dist = max_dist;
235 // Convert back to the "sphere radius" that camera_look_at expects.
236 float sin_half = std::sin(fov_radians * 0.5f);
237 if (sin_half < 1e-6f) sin_half = 1e-6f;
238 return max_dist * sin_half;
239}
240
254inline float max_ortho_extent(const Vec3 &bmin, const Vec3 &bmax,
255 const Vec3 &center, const Vec3 &dir) {
256 Vec3 corners[8] = {
257 Vec3(bmin.x, bmin.y, bmin.z), Vec3(bmax.x, bmin.y, bmin.z),
258 Vec3(bmin.x, bmax.y, bmin.z), Vec3(bmax.x, bmax.y, bmin.z),
259 Vec3(bmin.x, bmin.y, bmax.z), Vec3(bmax.x, bmin.y, bmax.z),
260 Vec3(bmin.x, bmax.y, bmax.z), Vec3(bmax.x, bmax.y, bmax.z),
261 };
262 float max_perp = 0.0f;
263 for (int i = 0; i < 8; i++) {
264 Vec3 delta = corners[i] - center;
265 float along = glm::dot(delta, dir);
266 float perp = std::sqrt(std::max(0.0f, glm::dot(delta, delta) - along * along));
267 if (perp > max_perp) max_perp = perp;
268 }
269 if (max_perp < 1e-6f) max_perp = 1.0f;
270 return max_perp;
271}
272
296Camera camera_look_at(const Vec3 &center, float radius,
297 const Vec3 &direction, const Vec3 &up,
298 float fov_degrees, float margin = 1.1f,
300
326Camera camera_fit_scene(const Scene &scene, const Vec3 &direction,
327 const Vec3 &up, float fov_degrees, float margin = 1.1f,
329
350Camera camera_fit_mesh(const Mesh &mesh, const Vec3 &direction,
351 const Vec3 &up, float fov_degrees, float margin = 1.1f,
353
372Camera camera_orbit(const Camera &camera, const Vec3 &axis, float angle_degrees);
373
374} // namespace scimesh
glm::vec2 Vec2
2-component floating-point vector (xy).
Definition types.h:32
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:71
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:91
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:108
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:207
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:254
Camera camera_orbit(const Camera &camera, const Vec3 &axis, float angle_degrees)
Orbit the camera around its look-at point.
Definition camera.cpp:125
ProjectedPoint world_to_screen(const Camera &camera, const Vec3 &world, int width, int height, ProjectionType projection, float near_plane, float far_plane)
Project a world-space point to the pixel coordinates of a rendered image.
Definition camera.cpp:39
float width
Definition renderer.cpp:36
The Scene — a collection of meshes rendered together.
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:10
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:14
A world-space point projected into the rendered image.
Definition camera.h:135
bool in_front
Whether the point is in front of the camera.
Definition camera.h:149
float depth
Depth in normalized device coordinates, in [-1, 1]; smaller values are closer to the camera.
Definition camera.h:143
Vec2 pixel
Pixel coordinates, origin at the top left, y growing down.
Definition camera.h:137
int x
Left edge of the bitmap, in image pixels.
Definition text.cpp:223
Fundamental types used throughout the scimesh rendering engine.