SBgl 0.1.0
A graphics framework in C99
Loading...
Searching...
No Matches
sbgl_camera.h
Go to the documentation of this file.
1
10#ifndef SBGL_CAMERA_H
11#define SBGL_CAMERA_H
12
13#include "sbgl_math.h"
14
19
44
52
56typedef struct {
59} sbgl_AABB;
60
64typedef struct {
66 float radius;
68
78
85static inline sbgl_Camera
86sbgl_CameraPerspective(float fov_y_rad, float aspect, float near_p, float far_p) {
87 sbgl_Camera cam = { 0 };
89 cam.position = sbgl_Vec3Set(0, 0, 5);
90 cam.target = sbgl_Vec3Set(0, 0, 0);
91 cam.up = sbgl_Vec3Set(0, 1, 0);
92 cam.fov_y = fov_y_rad;
93 cam.aspect = aspect;
94 cam.near_plane = near_p;
95 cam.far_plane = far_p;
96 return cam;
97}
98
106 sbgl_Camera cam = { 0 };
108 cam.position = sbgl_Vec3Set(0, 0, 1);
109 cam.target = sbgl_Vec3Set(0, 0, 0);
110 cam.up = sbgl_Vec3Set(0, 1, 0);
111 cam.ortho_left = p.left;
112 cam.ortho_right = p.right;
113 cam.ortho_bottom = p.bottom;
114 cam.ortho_top = p.top;
115 cam.near_plane = p.near_p;
116 cam.far_plane = p.far_p;
117 return cam;
118}
119
126static inline sbgl_Mat4 sbgl_CameraGetView(const sbgl_Camera* cam) {
127 return sbgl_Mat4LookAt(cam->position, cam->target, cam->up);
128}
129
137 if (cam->type == SBGL_CAMERA_PERSPECTIVE) {
138 return sbgl_Mat4Perspective(cam->fov_y, cam->aspect, cam->near_plane, cam->far_plane);
139 }
140 sbgl_OrthoParams p = { .left = cam->ortho_left,
141 .right = cam->ortho_right,
142 .bottom = cam->ortho_bottom,
143 .top = cam->ortho_top,
144 .near_p = cam->near_plane,
145 .far_p = cam->far_plane };
146 return sbgl_Mat4Orthographic(p);
147}
148
156 sbgl_Ray ray,
157 const sbgl_Sphere* spheres,
158 sbgl_HitResult* results,
159 uint32_t count
160) {
161 for (uint32_t i = 0; i < count; ++i) {
162 sbgl_Vec3 oc = sbgl_Vec3Sub(ray.origin, spheres[i].center);
163 float a = sbgl_Vec3Dot(ray.direction, ray.direction);
164 float b = 2.0f * sbgl_Vec3Dot(oc, ray.direction);
165 float c = sbgl_Vec3Dot(oc, oc) - spheres[i].radius * spheres[i].radius;
166 float discriminant = b * b - 4 * a * c;
167
168 results[i].hit = false;
169 if (discriminant >= 0) {
170 float sqrt_d = sqrtf(discriminant);
171 float t0 = (-b - sqrt_d) / (2.0f * a);
172 float t1 = (-b + sqrt_d) / (2.0f * a);
173
174 float t = t0;
175 if (t < 0)
176 t = t1;
177
178 if (t > 0) {
179 results[i].hit = true;
180 results[i].distance = t;
181 results[i].point = sbgl_Vec3Add(ray.origin, sbgl_Vec3Mul(ray.direction, t));
182 results[i].normal =
183 sbgl_Vec3Normalize(sbgl_Vec3Sub(results[i].point, spheres[i].center));
184 }
185 }
186 }
187}
188
195static inline void sbgl_RayAABBIntersectBatch(
196 sbgl_Ray ray,
197 const sbgl_AABB* boxes,
198 sbgl_HitResult* results,
199 uint32_t count
200) {
201 sbgl_Vec3 inv_dir = {
202 { 1.0f / ray.direction.x, 1.0f / ray.direction.y, 1.0f / ray.direction.z, 0.0f }
203 };
204
205 for (uint32_t i = 0; i < count; ++i) {
206 float t1 = (boxes[i].min.x - ray.origin.x) * inv_dir.x;
207 float t2 = (boxes[i].max.x - ray.origin.x) * inv_dir.x;
208 float tmin = fminf(t1, t2);
209 float tmax = fmaxf(t1, t2);
210
211 t1 = (boxes[i].min.y - ray.origin.y) * inv_dir.y;
212 t2 = (boxes[i].max.y - ray.origin.y) * inv_dir.y;
213 tmin = fmaxf(tmin, fminf(t1, t2));
214 tmax = fminf(tmax, fmaxf(t1, t2));
215
216 t1 = (boxes[i].min.z - ray.origin.z) * inv_dir.z;
217 t2 = (boxes[i].max.z - ray.origin.z) * inv_dir.z;
218 tmin = fmaxf(tmin, fminf(t1, t2));
219 tmax = fminf(tmax, fmaxf(t1, t2));
220
221 results[i].hit = (tmax >= tmin && tmax > 0);
222 if (results[i].hit) {
223 results[i].distance = tmin > 0 ? tmin : tmax;
224 results[i].point =
225 sbgl_Vec3Add(ray.origin, sbgl_Vec3Mul(ray.direction, results[i].distance));
226
227 // Calculate normal based on which face was hit
228 sbgl_Vec3 center = sbgl_Vec3Mul(sbgl_Vec3Add(boxes[i].min, boxes[i].max), 0.5f);
229 sbgl_Vec3 p = sbgl_Vec3Sub(results[i].point, center);
230 sbgl_Vec3 d = sbgl_Vec3Mul(sbgl_Vec3Sub(boxes[i].max, boxes[i].min), 0.5f);
231 float epsilon = 0.0001f;
232
233 results[i].normal = sbgl_Vec3Set(0, 0, 0);
234 if (fabsf(p.x) >= fabsf(d.x) - epsilon)
235 results[i].normal.x = p.x > 0 ? 1.0f : -1.0f;
236 else if (fabsf(p.y) >= fabsf(d.y) - epsilon)
237 results[i].normal.y = p.y > 0 ? 1.0f : -1.0f;
238 else if (fabsf(p.z) >= fabsf(d.z) - epsilon)
239 results[i].normal.z = p.z > 0 ? 1.0f : -1.0f;
240 }
241 }
242}
243
244#endif // SBGL_CAMERA_H
static sbgl_Camera sbgl_CameraOrthographic(sbgl_OrthoParams p)
Initializes a camera with orthographic projection.
static void sbgl_RayAABBIntersectBatch(sbgl_Ray ray, const sbgl_AABB *boxes, sbgl_HitResult *results, uint32_t count)
Performs a batch ray-AABB intersection test.
static void sbgl_RaySphereIntersectBatch(sbgl_Ray ray, const sbgl_Sphere *spheres, sbgl_HitResult *results, uint32_t count)
Performs a batch ray-sphere intersection test.
static sbgl_Camera sbgl_CameraPerspective(float fov_y_rad, float aspect, float near_p, float far_p)
Initializes a camera with perspective projection.
Definition sbgl_camera.h:86
static sbgl_Mat4 sbgl_CameraGetProjection(const sbgl_Camera *cam)
Computes the projection matrix for the given camera.
sbgl_CameraType
Camera projection types.
Definition sbgl_camera.h:18
@ SBGL_CAMERA_ORTHOGRAPHIC
Definition sbgl_camera.h:18
@ SBGL_CAMERA_PERSPECTIVE
Definition sbgl_camera.h:18
static sbgl_Mat4 sbgl_CameraGetView(const sbgl_Camera *cam)
Computes the view matrix for the given camera.
Single-header math library for SBgl.
static sbgl_Mat4 sbgl_Mat4Orthographic(sbgl_OrthoParams p)
Creates an orthographic projection matrix.
Definition sbgl_math.h:296
static float sbgl_Vec3Dot(sbgl_Vec3 a, sbgl_Vec3 b)
Computes the dot product of two Vec3 vectors.
Definition sbgl_math.h:147
static sbgl_Vec3 sbgl_Vec3Set(float x, float y, float z)
Creates a Vec3, correctly padded.
Definition sbgl_math.h:93
static sbgl_Vec3 sbgl_Vec3Add(sbgl_Vec3 a, sbgl_Vec3 b)
Adds two Vec3 vectors.
Definition sbgl_math.h:132
static sbgl_Mat4 sbgl_Mat4Perspective(float fov_y_rad, float aspect, float near, float far)
Creates a perspective projection matrix.
Definition sbgl_math.h:278
static sbgl_Vec3 sbgl_Vec3Mul(sbgl_Vec3 a, float s)
Multiplies a Vec3 by a scalar.
Definition sbgl_math.h:142
static sbgl_Mat4 sbgl_Mat4LookAt(sbgl_Vec3 eye, sbgl_Vec3 center, sbgl_Vec3 up)
Creates a look-at view matrix.
Definition sbgl_math.h:308
static sbgl_Vec3 sbgl_Vec3Normalize(sbgl_Vec3 v)
Normalizes a Vec3.
Definition sbgl_math.h:162
static sbgl_Vec3 sbgl_Vec3Sub(sbgl_Vec3 a, sbgl_Vec3 b)
Subtracts b from a.
Definition sbgl_math.h:137
Axis-Aligned Bounding Box (AABB).
Definition sbgl_camera.h:56
sbgl_Vec3 max
Definition sbgl_camera.h:58
sbgl_Vec3 min
Definition sbgl_camera.h:57
Stateful camera representation.
Definition sbgl_camera.h:27
sbgl_CameraType type
Definition sbgl_camera.h:28
float far_plane
Definition sbgl_camera.h:37
sbgl_Vec3 target
Definition sbgl_camera.h:31
sbgl_Vec3 up
Definition sbgl_camera.h:32
float ortho_top
Definition sbgl_camera.h:42
float ortho_bottom
Definition sbgl_camera.h:41
sbgl_Vec3 position
Definition sbgl_camera.h:30
float ortho_left
Definition sbgl_camera.h:39
float ortho_right
Definition sbgl_camera.h:40
float near_plane
Definition sbgl_camera.h:36
Intersection result for batch testing.
Definition sbgl_camera.h:72
sbgl_Vec3 point
Definition sbgl_camera.h:75
sbgl_Vec3 normal
Definition sbgl_camera.h:76
4x4 Matrix, 16-byte aligned, column-major.
Definition sbgl_math.h:83
Parameters for orthographic projection.
Definition sbgl_math.h:29
Mathematical ray.
Definition sbgl_camera.h:48
sbgl_Vec3 direction
Definition sbgl_camera.h:50
sbgl_Vec3 origin
Definition sbgl_camera.h:49
Bounding sphere.
Definition sbgl_camera.h:64
sbgl_Vec3 center
Definition sbgl_camera.h:65
3D Vector, 16-byte aligned and padded for SIMD safety.
Definition sbgl_math.h:49
float y
Definition sbgl_math.h:52
float z
Definition sbgl_math.h:52
float x
Definition sbgl_math.h:52