SBgl 0.1.0
A graphics framework in C99
Loading...
Searching...
No Matches
sbgl_math.h
Go to the documentation of this file.
1
9#ifndef SBGL_MATH_H
10#define SBGL_MATH_H
11
12#include <math.h>
13#include <stdbool.h>
14#include <stdint.h>
15
16#if defined(_MSC_VER)
17#define SBGL_ALIGN(n) __declspec(align(n))
18#else
19#define SBGL_ALIGN(n) __attribute__((aligned(n)))
20#endif
21
22#define SBGL_PI 3.14159265358979323846f
23
24// --- Types ---
25
29typedef struct {
30 float left, right;
31 float bottom, top;
32 float near_p, far_p;
34
38typedef union {
39 /* __extension__ suppresses ISO C99 pedantic warnings for anonymous structs */
40 __extension__ struct {
41 float x, y;
42 };
43 float v[2];
44} sbgl_Vec2;
45
49typedef union {
50 /* __extension__ suppresses ISO C99 pedantic warnings for anonymous structs */
51 __extension__ struct {
52 float x, y, z;
53 float _pad;
54 };
55 float v[4];
57
61typedef union {
62 /* __extension__ suppresses ISO C99 pedantic warnings for anonymous structs */
63 __extension__ struct {
64 float x, y, z, w;
65 };
66 float v[4];
68
72typedef union {
73 /* __extension__ suppresses ISO C99 pedantic warnings for anonymous structs */
74 __extension__ struct {
75 float x, y, z, w;
76 };
77 float v[4];
79
83typedef struct {
84 SBGL_ALIGN(16) float m[4][4];
85} sbgl_Mat4;
86
87// --- Constructors ---
88
90static inline sbgl_Vec2 sbgl_Vec2Set(float x, float y) { return (sbgl_Vec2){ { x, y } }; }
91
93static inline sbgl_Vec3 sbgl_Vec3Set(float x, float y, float z) {
94 return (sbgl_Vec3){ { x, y, z, 0.0f } };
95}
96
98static inline sbgl_Vec4 sbgl_Vec4Set(float x, float y, float z, float w) {
99 return (sbgl_Vec4){ { x, y, z, w } };
100}
101
103static inline sbgl_Quat sbgl_QuatSet(float x, float y, float z, float w) {
104 return (sbgl_Quat){ { x, y, z, w } };
105}
106
107// --- Math Operations ---
108
114static inline float sbgl_InvSqrt(float x) {
115 union {
116 float f;
117 uint32_t i;
118 } pun;
119
120 float xhalf = 0.5f * x;
121 pun.f = x;
122 pun.i = 0x5f3759df - (pun.i >> 1);
123 pun.f = pun.f * (1.5f - xhalf * pun.f * pun.f);
124 // Second iteration for better precision
125 pun.f = pun.f * (1.5f - xhalf * pun.f * pun.f);
126 return pun.f;
127}
128
129// --- Vector Operations ---
130
133 return (sbgl_Vec3){ { a.x + b.x, a.y + b.y, a.z + b.z, 0.0f } };
134}
135
138 return (sbgl_Vec3){ { a.x - b.x, a.y - b.y, a.z - b.z, 0.0f } };
139}
140
142static inline sbgl_Vec3 sbgl_Vec3Mul(sbgl_Vec3 a, float s) {
143 return (sbgl_Vec3){ { a.x * s, a.y * s, a.z * s, 0.0f } };
144}
145
147static inline float sbgl_Vec3Dot(sbgl_Vec3 a, sbgl_Vec3 b) {
148 return a.x * b.x + a.y * b.y + a.z * b.z;
149}
150
153 return (sbgl_Vec3){
154 { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f }
155 };
156}
157
159static inline float sbgl_Vec3Length(sbgl_Vec3 v) { return sqrtf(sbgl_Vec3Dot(v, v)); }
160
163 float len_sq = sbgl_Vec3Dot(v, v);
164 if (len_sq < 0.000001f)
165 return (sbgl_Vec3){ { 0 } };
166 return sbgl_Vec3Mul(v, sbgl_InvSqrt(len_sq));
167}
168
171 return (sbgl_Vec4){ { a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w } };
172}
173
175static inline sbgl_Vec4 sbgl_Vec4Mul(sbgl_Vec4 a, float s) {
176 return (sbgl_Vec4){ { a.x * s, a.y * s, a.z * s, a.w * s } };
177}
178
179// --- Quaternion Operations ---
180
182static inline sbgl_Quat sbgl_QuatIdentity(void) { return (sbgl_Quat){ { 0, 0, 0, 1.0f } }; }
183
186 return (sbgl_Quat){ { a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
187 a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
188 a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x,
189 a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z } };
190}
191
193static inline sbgl_Quat sbgl_QuatFromAxisAngle(sbgl_Vec3 axis, float angle_rad) {
194 float s = sinf(angle_rad / 2.0f);
196 return (sbgl_Quat){ { n.x * s, n.y * s, n.z * s, cosf(angle_rad / 2.0f) } };
197}
198
200static inline sbgl_Mat4 sbgl_Mat4Identity(void) {
201 sbgl_Mat4 res = { 0 };
202 res.m[0][0] = 1.0f;
203 res.m[1][1] = 1.0f;
204 res.m[2][2] = 1.0f;
205 res.m[3][3] = 1.0f;
206 return res;
207}
208
212 float xx = q.x * q.x;
213 float yy = q.y * q.y;
214 float zz = q.z * q.z;
215 float xy = q.x * q.y;
216 float xz = q.x * q.z;
217 float yz = q.y * q.z;
218 float wx = q.w * q.x;
219 float wy = q.w * q.y;
220 float wz = q.w * q.z;
221
222 res.m[0][0] = 1.0f - 2.0f * (yy + zz);
223 res.m[0][1] = 2.0f * (xy + wz);
224 res.m[0][2] = 2.0f * (xz - wy);
225
226 res.m[1][0] = 2.0f * (xy - wz);
227 res.m[1][1] = 1.0f - 2.0f * (xx + zz);
228 res.m[1][2] = 2.0f * (yz + wx);
229
230 res.m[2][0] = 2.0f * (xz + wy);
231 res.m[2][1] = 2.0f * (yz - wx);
232 res.m[2][2] = 1.0f - 2.0f * (xx + yy);
233
234 return res;
235}
236
237// --- Matrix Operations ---
238
241 sbgl_Mat4 res = { 0 };
242 for (int c = 0; c < 4; ++c) {
243 for (int r = 0; r < 4; ++r) {
244 res.m[c][r] = a.m[0][r] * b.m[c][0] + a.m[1][r] * b.m[c][1] + a.m[2][r] * b.m[c][2] +
245 a.m[3][r] * b.m[c][3];
246 }
247 }
248 return res;
249}
250
253 return (sbgl_Vec4){ { m.m[0][0] * v.x + m.m[1][0] * v.y + m.m[2][0] * v.z + m.m[3][0] * v.w,
254 m.m[0][1] * v.x + m.m[1][1] * v.y + m.m[2][1] * v.z + m.m[3][1] * v.w,
255 m.m[0][2] * v.x + m.m[1][2] * v.y + m.m[2][2] * v.z + m.m[3][2] * v.w,
256 m.m[0][3] * v.x + m.m[1][3] * v.y + m.m[2][3] * v.z + m.m[3][3] * v.w } };
257}
258
262 res.m[3][0] = v.x;
263 res.m[3][1] = v.y;
264 res.m[3][2] = v.z;
265 return res;
266}
267
271 res.m[0][0] = v.x;
272 res.m[1][1] = v.y;
273 res.m[2][2] = v.z;
274 return res;
275}
276
278static inline sbgl_Mat4 sbgl_Mat4Perspective(float fov_y_rad, float aspect, float near, float far) {
279 float f = 1.0f / tanf(fov_y_rad / 2.0f);
280 sbgl_Mat4 res = { 0 };
281 res.m[0][0] = f / aspect;
282 res.m[1][1] = f;
283 res.m[2][2] = far / (near - far);
284 res.m[2][3] = -1.0f;
285 res.m[3][2] = (far * near) / (near - far);
286 return res;
287}
288
290static inline sbgl_Mat4 sbgl_Mat4Rotate(float angle_rad, sbgl_Vec3 axis) {
291 sbgl_Quat q = sbgl_QuatFromAxisAngle(axis, angle_rad);
292 return sbgl_QuatToMat4(q);
293}
294
298 res.m[0][0] = 2.0f / (p.right - p.left);
299 res.m[1][1] = 2.0f / (p.top - p.bottom);
300 res.m[2][2] = -2.0f / (p.far_p - p.near_p);
301 res.m[3][0] = -(p.right + p.left) / (p.right - p.left);
302 res.m[3][1] = -(p.top + p.bottom) / (p.top - p.bottom);
303 res.m[3][2] = -(p.far_p + p.near_p) / (p.far_p - p.near_p);
304 return res;
305}
306
308static inline sbgl_Mat4 sbgl_Mat4LookAt(sbgl_Vec3 eye, sbgl_Vec3 center, sbgl_Vec3 up) {
309 sbgl_Vec3 f = sbgl_Vec3Normalize(sbgl_Vec3Sub(center, eye));
311 sbgl_Vec3 u = sbgl_Vec3Cross(s, f);
312
314 res.m[0][0] = s.x;
315 res.m[1][0] = s.y;
316 res.m[2][0] = s.z;
317 res.m[0][1] = u.x;
318 res.m[1][1] = u.y;
319 res.m[2][1] = u.z;
320 res.m[0][2] = -f.x;
321 res.m[1][2] = -f.y;
322 res.m[2][2] = -f.z;
323 res.m[3][0] = -sbgl_Vec3Dot(s, eye);
324 res.m[3][1] = -sbgl_Vec3Dot(u, eye);
325 res.m[3][2] = sbgl_Vec3Dot(f, eye);
326 return res;
327}
328
329#endif // SBGL_MATH_H
static sbgl_Mat4 sbgl_Mat4Orthographic(sbgl_OrthoParams p)
Creates an orthographic projection matrix.
Definition sbgl_math.h:296
#define SBGL_ALIGN(n)
Definition sbgl_math.h:19
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_Mat4 sbgl_QuatToMat4(sbgl_Quat q)
Converts a quaternion to a rotation matrix.
Definition sbgl_math.h:210
static sbgl_Mat4 sbgl_Mat4Scale(sbgl_Vec3 v)
Creates a scaling matrix.
Definition sbgl_math.h:269
static sbgl_Vec4 sbgl_Mat4MulVec4(sbgl_Mat4 m, sbgl_Vec4 v)
Multiplies a matrix by a Vec4.
Definition sbgl_math.h:252
static sbgl_Quat sbgl_QuatSet(float x, float y, float z, float w)
Creates a Quat.
Definition sbgl_math.h:103
static sbgl_Vec4 sbgl_Vec4Add(sbgl_Vec4 a, sbgl_Vec4 b)
Adds two Vec4 vectors.
Definition sbgl_math.h:170
static sbgl_Mat4 sbgl_Mat4Identity(void)
Returns an identity matrix.
Definition sbgl_math.h:200
static sbgl_Quat sbgl_QuatMul(sbgl_Quat a, sbgl_Quat b)
Multiplies two quaternions.
Definition sbgl_math.h:185
static sbgl_Quat sbgl_QuatFromAxisAngle(sbgl_Vec3 axis, float angle_rad)
Creates a quaternion from an axis and an angle (in radians).
Definition sbgl_math.h:193
static sbgl_Vec3 sbgl_Vec3Set(float x, float y, float z)
Creates a Vec3, correctly padded.
Definition sbgl_math.h:93
static sbgl_Quat sbgl_QuatIdentity(void)
Returns an identity quaternion.
Definition sbgl_math.h:182
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_Mat4Translate(sbgl_Vec3 v)
Creates a translation matrix.
Definition sbgl_math.h:260
static sbgl_Vec4 sbgl_Vec4Mul(sbgl_Vec4 a, float s)
Multiplies a Vec4 by a scalar.
Definition sbgl_math.h:175
static float sbgl_InvSqrt(float x)
Approximate Inverse Square Root algorithm.
Definition sbgl_math.h:114
static sbgl_Mat4 sbgl_Mat4Rotate(float angle_rad, sbgl_Vec3 axis)
Creates a rotation matrix from axis and angle.
Definition sbgl_math.h:290
static float sbgl_Vec3Length(sbgl_Vec3 v)
Returns the length of a Vec3.
Definition sbgl_math.h:159
static sbgl_Mat4 sbgl_Mat4Mul(sbgl_Mat4 a, sbgl_Mat4 b)
Multiplies two matrices.
Definition sbgl_math.h:240
static sbgl_Vec2 sbgl_Vec2Set(float x, float y)
Creates a Vec2.
Definition sbgl_math.h:90
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_Vec3Cross(sbgl_Vec3 a, sbgl_Vec3 b)
Computes the cross product of two Vec3 vectors.
Definition sbgl_math.h:152
static sbgl_Vec3 sbgl_Vec3Normalize(sbgl_Vec3 v)
Normalizes a Vec3.
Definition sbgl_math.h:162
static sbgl_Vec4 sbgl_Vec4Set(float x, float y, float z, float w)
Creates a Vec4.
Definition sbgl_math.h:98
static sbgl_Vec3 sbgl_Vec3Sub(sbgl_Vec3 a, sbgl_Vec3 b)
Subtracts b from a.
Definition sbgl_math.h:137
4x4 Matrix, 16-byte aligned, column-major.
Definition sbgl_math.h:83
float m[4][4]
Definition sbgl_math.h:84
Parameters for orthographic projection.
Definition sbgl_math.h:29
Quaternion, 16-byte aligned.
Definition sbgl_math.h:72
float z
Definition sbgl_math.h:75
float w
Definition sbgl_math.h:75
float y
Definition sbgl_math.h:75
float x
Definition sbgl_math.h:75
2D Vector.
Definition sbgl_math.h:38
float x
Definition sbgl_math.h:41
3D Vector, 16-byte aligned and padded for SIMD safety.
Definition sbgl_math.h:49
float _pad
Definition sbgl_math.h:53
float y
Definition sbgl_math.h:52
float z
Definition sbgl_math.h:52
float x
Definition sbgl_math.h:52
4D Vector, 16-byte aligned.
Definition sbgl_math.h:61
float x
Definition sbgl_math.h:64
float w
Definition sbgl_math.h:64
float z
Definition sbgl_math.h:64
float y
Definition sbgl_math.h:64