Vecmat 0.2.3
C math and linear algebra library for 2D/3D graphics, physics, and science.
Loading...
Searching...
No Matches
vector3_ptr.c
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025-2026 Igal Alkon
2// SPDX-FileCopyrightText: 2026 ALKONTEK <git@alkontek.com>
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <vecmat.h>
6
14void vec3_add_ptr(vector3 *res, const vector3 *a, const vector3 *b)
15{
16 res->x = a->x + b->x;
17 res->y = a->y + b->y;
18 res->z = a->z + b->z;
19}
20
28void vec3_sub_ptr(vector3 *res, const vector3 *a, const vector3 *b)
29{
30 res->x = a->x - b->x;
31 res->y = a->y - b->y;
32 res->z = a->z - b->z;
33}
34
42void vec3_mul_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
43{
44 res->x = v->x * s;
45 res->y = v->y * s;
46 res->z = v->z * s;
47}
48
56void vec3_div_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
57{
58 if (s == 0.0f) {
59 *res = *v;
60 return;
61 }
62 res->x = v->x / s;
63 res->y = v->y / s;
64 res->z = v->z / s;
65}
66
74void vec3_mul_ptr(vector3 *res, const vector3 *a, const vector3 *b)
75{
76 res->x = a->x * b->x;
77 res->y = a->y * b->y;
78 res->z = a->z * b->z;
79}
80
87void vec3_neg_ptr(vector3 *res, const vector3 *v)
88{
89 res->x = -v->x;
90 res->y = -v->y;
91 res->z = -v->z;
92}
93
100void vec3_abs_ptr(vector3 *res, const vector3 *v)
101{
102 res->x = VECMAT_FABS(v->x);
103 res->y = VECMAT_FABS(v->y);
104 res->z = VECMAT_FABS(v->z);
105}
106
114{
115 const vm_float_t len = vec3_length(*v);
116 if (len == 0.0f) {
117 *res = *v;
118 return;
119 }
120 const vm_float_t inv_len = 1.0f / len;
121 res->x = v->x * inv_len;
122 res->y = v->y * inv_len;
123 res->z = v->z * inv_len;
124}
125
133void vec3_cross_ptr(vector3 *res, const vector3 *a, const vector3 *b)
134{
135 res->x = a->y * b->z - a->z * b->y;
136 res->y = a->z * b->x - a->x * b->z;
137 res->z = a->x * b->y - a->y * b->x;
138}
139
147void vec3_min_ptr(vector3 *res, const vector3 *a, const vector3 *b)
148{
149 res->x = VECMAT_FMIN(a->x, b->x);
150 res->y = VECMAT_FMIN(a->y, b->y);
151 res->z = VECMAT_FMIN(a->z, b->z);
152}
153
161void vec3_max_ptr(vector3 *res, const vector3 *a, const vector3 *b)
162{
163 res->x = VECMAT_FMAX(a->x, b->x);
164 res->y = VECMAT_FMAX(a->y, b->y);
165 res->z = VECMAT_FMAX(a->z, b->z);
166}
167
174void vec3_sign_ptr(vector3 *res, const vector3 *v)
175{
176 res->x = (v->x > 0.0f) - (v->x < 0.0f);
177 res->y = (v->y > 0.0f) - (v->y < 0.0f);
178 res->z = (v->z > 0.0f) - (v->z < 0.0f);
179}
180
187void vec3_floor_ptr(vector3 *res, const vector3 *v)
188{
189 res->x = VECMAT_FLOOR(v->x);
190 res->y = VECMAT_FLOOR(v->y);
191 res->z = VECMAT_FLOOR(v->z);
192}
193
200void vec3_ceil_ptr(vector3 *res, const vector3 *v)
201{
202 res->x = VECMAT_CEIL(v->x);
203 res->y = VECMAT_CEIL(v->y);
204 res->z = VECMAT_CEIL(v->z);
205}
206
213void vec3_round_ptr(vector3 *res, const vector3 *v)
214{
215 res->x = VECMAT_ROUND(v->x);
216 res->y = VECMAT_ROUND(v->y);
217 res->z = VECMAT_ROUND(v->z);
218}
219
227void vec3_reflect_ptr(vector3 *res, const vector3 *incident, const vector3 *normal)
228{
229 const vm_float_t dot = vec3_dot(*incident, *normal);
230 res->x = incident->x - 2.0f * dot * normal->x;
231 res->y = incident->y - 2.0f * dot * normal->y;
232 res->z = incident->z - 2.0f * dot * normal->z;
233}
234
243void vec3_refract_ptr(vector3 *res, const vector3 *incident, const vector3 *normal, const vm_float_t eta)
244{
245 const vm_float_t dot = vec3_dot(*incident, *normal);
246 const vm_float_t k = 1.0f - eta * eta * (1.0f - dot * dot);
247 if (k < 0.0f) {
248 res->x = res->y = res->z = 0.0f;
249 return;
250 }
251 const vm_float_t factor = eta * dot + VECMAT_SQRT(k);
252 res->x = eta * incident->x - factor * normal->x;
253 res->y = eta * incident->y - factor * normal->y;
254 res->z = eta * incident->z - factor * normal->z;
255}
256
265void vec3_lerp_ptr(vector3 *res, const vector3 *a, const vector3 *b, const vm_float_t t)
266{
267 res->x = a->x + t * (b->x - a->x);
268 res->y = a->y + t * (b->y - a->y);
269 res->z = a->z + t * (b->z - a->z);
270}
271
280void vec3_clamp_ptr(vector3 *res, const vector3 *v, const vector3 *min, const vector3 *max)
281{
282 res->x = VECMAT_FMAX(min->x, VECMAT_FMIN(max->x, v->x));
283 res->y = VECMAT_FMAX(min->y, VECMAT_FMIN(max->y, v->y));
284 res->z = VECMAT_FMAX(min->z, VECMAT_FMIN(max->z, v->z));
285}
286
294void vec3_scale_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
295{
296 vec3_mul_scalar_ptr(res, v, s);
297}
298
306void vec3_div_ptr(vector3 *res, const vector3 *a, const vector3 *b)
307{
308 res->x = (b->x == 0.0f) ? 0.0f : a->x / b->x;
309 res->y = (b->y == 0.0f) ? 0.0f : a->y / b->y;
310 res->z = (b->z == 0.0f) ? 0.0f : a->z / b->z;
311}
312
320void vec3_add_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
321{
322 res->x = v->x + s;
323 res->y = v->y + s;
324 res->z = v->z + s;
325}
326
334void vec3_sub_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
335{
336 res->x = v->x - s;
337 res->y = v->y - s;
338 res->z = v->z - s;
339}
340
349void vec3_clamp_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t min, const vm_float_t max)
350{
351 res->x = VECMAT_FMIN(VECMAT_FMAX(v->x, min), max);
352 res->y = VECMAT_FMIN(VECMAT_FMAX(v->y, min), max);
353 res->z = VECMAT_FMIN(VECMAT_FMAX(v->z, min), max);
354}
355
363{
364 vec3_clamp_scalar_ptr(res, v, 0.0f, 1.0f);
365}
366
373void vec3_fract_ptr(vector3 *res, const vector3 *v)
374{
375 res->x = v->x - VECMAT_FLOOR(v->x);
376 res->y = v->y - VECMAT_FLOOR(v->y);
377 res->z = v->z - VECMAT_FLOOR(v->z);
378}
379
387void vec3_project_ptr(vector3 *res, const vector3 *a, const vector3 *b)
388{
389 const vm_float_t denom = vec3_dot(*b, *b);
390 if (denom == 0.0f) {
391 res->x = 0.0f;
392 res->y = 0.0f;
393 res->z = 0.0f;
394 return;
395 }
396 const vm_float_t scale = vec3_dot(*a, *b) / denom;
397 res->x = b->x * scale;
398 res->y = b->y * scale;
399 res->z = b->z * scale;
400}
401
409void vec3_slide_ptr(vector3 *res, const vector3 *v, const vector3 *normal)
410{
411 const vm_float_t d = vec3_dot(*v, *normal);
412 res->x = v->x - normal->x * d;
413 res->y = v->y - normal->y * d;
414 res->z = v->z - normal->z * d;
415}
416
424void vec3_reject_ptr(vector3 *res, const vector3 *a, const vector3 *b)
425{
426 vector3 projected;
427 vec3_project_ptr(&projected, a, b);
428 res->x = a->x - projected.x;
429 res->y = a->y - projected.y;
430 res->z = a->z - projected.z;
431}
432
441void vec3_rotate_axis_ptr(vector3 *res, const vector3 *v, const vector3 *axis, const vm_float_t angle)
442{
443 vector3 k;
444 vec3_normalize_ptr(&k, axis);
445 const vm_float_t cs = VECMAT_COS(angle);
446 const vm_float_t sn = VECMAT_SIN(angle);
447 const vm_float_t d = vec3_dot(*v, k);
448 res->x = v->x * cs + (k.y * v->z - k.z * v->y) * sn + k.x * d * (1.0f - cs);
449 res->y = v->y * cs + (k.z * v->x - k.x * v->z) * sn + k.y * d * (1.0f - cs);
450 res->z = v->z * cs + (k.x * v->y - k.y * v->x) * sn + k.z * d * (1.0f - cs);
451}
452
460void vec3_from_vec2_ptr(vector3 *res, const vector2 *v, const vm_float_t z)
461{
462 res->x = v->x;
463 res->y = v->y;
464 res->z = z;
465}
466
473void vec3_xy_ptr(vector2 *res, const vector3 *v)
474{
475 res->x = v->x;
476 res->y = v->y;
477}
478
487void vec3_move_toward_ptr(vector3 *res, const vector3 *current, const vector3 *target, const vm_float_t max_delta)
488{
489 const vm_float_t dx = target->x - current->x;
490 const vm_float_t dy = target->y - current->y;
491 const vm_float_t dz = target->z - current->z;
492 const vm_float_t dist = VECMAT_SQRT(dx * dx + dy * dy + dz * dz);
493 if (dist <= max_delta || dist == 0.0f) {
494 *res = *target;
495 return;
496 }
497 const vm_float_t scale = max_delta / dist;
498 res->x = current->x + dx * scale;
499 res->y = current->y + dy * scale;
500 res->z = current->z + dz * scale;
501}
502
510void vec3_limit_length_ptr(vector3 *res, const vector3 *v, const vm_float_t max_len)
511{
512 const vm_float_t len = vec3_length(*v);
513 if (len <= max_len || len == 0.0f) {
514 *res = *v;
515 return;
516 }
517 const vm_float_t scale = max_len / len;
518 res->x = v->x * scale;
519 res->y = v->y * scale;
520 res->z = v->z * scale;
521}
522
531{
532 vector3 nn;
533 vec3_normalize_ptr(&nn, n);
534 const vector3 axis = (VECMAT_FABS(nn.x) > 0.9f)
535 ? (vector3){.x = 0.0f, .y = 1.0f, .z = 0.0f}
536 : (vector3){.x = 1.0f, .y = 0.0f, .z = 0.0f};
537 vec3_cross_ptr(t, &nn, &axis);
538 vec3_normalize_ptr(t, t);
539 vec3_cross_ptr(b, &nn, t);
540}
vm_float_t y
Definition vecmat.h:128
vm_float_t x
Definition vecmat.h:127
vm_float_t z
Definition vecmat.h:139
vm_float_t y
Definition vecmat.h:138
vm_float_t x
Definition vecmat.h:137
#define VECMAT_FMAX(a, b)
Definition vecmat.h:423
#define VECMAT_FLOOR(x)
Definition vecmat.h:424
#define VECMAT_FMIN(a, b)
Definition vecmat.h:422
vm_float_t vec3_dot(vector3 a, vector3 b)
Computes the dot product of two vector3.
Definition vector3.c:428
vm_float_t vec3_length(vector3 v)
Computes the length (magnitude) of a vector3.
Definition vector3.c:439
#define VECMAT_ROUND(x)
Definition vecmat.h:426
#define VECMAT_CEIL(x)
Definition vecmat.h:425
#define VECMAT_SIN(x)
Definition vecmat.h:415
double vm_float_t
Definition vecmat.h:79
#define VECMAT_FABS(x)
Definition vecmat.h:413
#define VECMAT_SQRT(x)
Definition vecmat.h:414
#define VECMAT_COS(x)
Definition vecmat.h:416
void vec3_refract_ptr(vector3 *res, const vector3 *incident, const vector3 *normal, const vm_float_t eta)
Compute refraction of the incident vector through normal with eta.
void vec3_mul_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Component-wise multiplication of two vectors.
Definition vector3_ptr.c:74
void vec3_abs_ptr(vector3 *res, const vector3 *v)
Computes the absolute value per component of a vector3.
void vec3_sub_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
Subtracts a scalar from each component.
void vec3_min_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Component-wise minimum of two vectors.
void vec3_sign_ptr(vector3 *res, const vector3 *v)
Component-wise sign of a vector.
void vec3_clamp_ptr(vector3 *res, const vector3 *v, const vector3 *min, const vector3 *max)
Clamp vector components between min and max.
void vec3_div_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Divides two vectors component-wise.
void vec3_saturate_ptr(vector3 *res, const vector3 *v)
Clamps each component to the range [0, 1].
void vec3_xy_ptr(vector2 *res, const vector3 *v)
Returns the x and y components as a 2D vector.
void vec3_from_vec2_ptr(vector3 *res, const vector2 *v, const vm_float_t z)
Builds a higher-dimension vector from a vector2.
void vec3_add_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Component-wise addition of two vectors.
Definition vector3_ptr.c:14
void vec3_sub_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Component-wise subtraction of two vectors.
Definition vector3_ptr.c:28
void vec3_lerp_ptr(vector3 *res, const vector3 *a, const vector3 *b, const vm_float_t t)
Linear interpolation between two vectors.
void vec3_round_ptr(vector3 *res, const vector3 *v)
Component-wise round of a vector.
void vec3_move_toward_ptr(vector3 *res, const vector3 *current, const vector3 *target, const vm_float_t max_delta)
Moves current toward target by at most max_delta.
void vec3_max_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Component-wise maximum of two vectors.
void vec3_rotate_axis_ptr(vector3 *res, const vector3 *v, const vector3 *axis, const vm_float_t angle)
Rotates v around axis by angle radians.
void vec3_fract_ptr(vector3 *res, const vector3 *v)
Returns the fractional part of each component.
void vec3_limit_length_ptr(vector3 *res, const vector3 *v, const vm_float_t max_len)
Clamps the vector length to max_len.
void vec3_slide_ptr(vector3 *res, const vector3 *v, const vector3 *normal)
Removes the component of v along normal.
void vec3_clamp_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t min, const vm_float_t max)
Clamps each component to the scalar range [min, max].
void vec3_add_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
Adds a scalar to each component.
void vec3_cross_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Compute cross-product of two vectors.
void vec3_normalize_ptr(vector3 *res, const vector3 *v)
Normalize a vector to unit length.
void vec3_ceil_ptr(vector3 *res, const vector3 *v)
Component-wise ceil of a vector.
void vec3_reject_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Returns the component of a orthogonal to b.
void vec3_orthonormal_basis_ptr(const vector3 *n, vector3 *t, vector3 *b)
Builds a tangent and bitangent orthonormal to n.
void vec3_scale_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
Scales the vector by a scalar.
void vec3_project_ptr(vector3 *res, const vector3 *a, const vector3 *b)
Projects a onto b.
void vec3_floor_ptr(vector3 *res, const vector3 *v)
Component-wise floor of a vector.
void vec3_neg_ptr(vector3 *res, const vector3 *v)
Negation of a vector.
Definition vector3_ptr.c:87
void vec3_reflect_ptr(vector3 *res, const vector3 *incident, const vector3 *normal)
Compute reflection of the incident vector over normal.
void vec3_div_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
Component-wise division of vector by scalar.
Definition vector3_ptr.c:56
void vec3_mul_scalar_ptr(vector3 *res, const vector3 *v, const vm_float_t s)
Component-wise multiplication of vector by scalar.
Definition vector3_ptr.c:42