diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3cf3668..0000000 --- a/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: c -compiler: - - clang - - gcc - -script: - - ./run_tests.sh diff --git a/LICENSE b/LICENSE index 459e0f0..0c59f7a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2016 Felipe Ferreira da Silva +Copyright © 2018 Felipe Ferreira da Silva This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of diff --git a/README.md b/README.md index dfc63cd..ec8fe84 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,127 @@ -# MathC +# MATHC -[![Build Status](https://travis-ci.org/ferreiradaselva/mathc.svg?branch=master)](https://travis-ci.org/ferreiradaselva/mathc) +MATHC is a simple math library for 2D and 3D programming. -MathC is a simple math library for 2D and 3D programming. It contains implementations for: +## Features -- 2D vectors -- 3D vectors +- Vectors (2D, 3D and 4D) (integer type and floating-point type) - Quaternions -- Matrices +- Matrices (2×2, 3×3, and 4×4) - Easing functions -It support C99 standard or later. +## Contributions and Development -# Reference +You can help with the development of MATHC testing the library, sending in-scope math functions, reporting errors and giving feedback. -The reference is the file `REFERENCE.md`. +I work little on the library nowadays, but I am always open to suggestions and contributions. -# Float +## Versioning -Every structure and function uses `float`, because it is the most used type on 2D and 3D programming with OpenGL. +Starting on version 2, the development of MATHC uses calendar versioning, with a tag `YYYY.MM.DD.MICRO` for each stable release. If a release breaks backward compatibility, then it is mentioned in the release notes. -**The type `float` loses precision with large numbers, why not use `double`?** Because every `double` value would be converted to `float` before sending to OpenGL, anyway. Which means your physics would run with high precision, but the rendering would still be affected by the `float` imprecision. Instead, *the good practice* to solve the problem with large numbers is to truncate the world position back to `[0.0f, 0.0f, 0.0f]` when the world distance to the center is too large. If the world is too big that even when truncating there is stil large numbers, the correct approach is to divide the world in chunks. +## Configuring -# Passing Arguments as Value or Pointer +MATHC can be configured using these preprocessors: -For every function **that takes a structure**, there are two versions. One that you pass structures as value and other that you pass as pointer. The functions that pass the value by pointer have a prefix `p` before the type name (pvector2, pvector3, pquaternion and pmatrix) and the result is the `*result` argument or a returned `float`. +- `MATHC_NO_INT`: disable implementations using `mint_t`. +- `MATHC_USE_INT8`: define `mint_t` as `int8_t`. +- `MATHC_USE_INT16`: define `mint_t` as `int16_t`. +- `MATHC_USE_INT32`: define `mint_t` as `int32_t`. This is the default. +- `MATHC_USE_INT64`: define `mint_t` as `int64_t`. +- `MATHC_INT_TYPE`: set a custom type for `mint_t`. +- `MATHC_NO_FLOATING_POINT`: disable implementations using `mfloat_t`. +- `MATHC_USE_SINGLE_FLOATING_POINT`: define `mfloat_t` as `float`. This is the default. +- `MATHC_USE_DOUBLE_FLOATING_POINT`: define `mfloat_t` as `double`. +- `MATHC_FLOATING_POINT_TYPE`: set a custom type for `mfloat_t`. +- `MATHC_USE_UNIONS`: define anonymous unions inside structures. +- `MATHC_NO_POINTER_STRUCT_FUNCTIONS`: don't define the functions that take pointer to structures. +- `MATHC_NO_STRUCT_FUNCTIONS`: don't define the functions that take structures as value. +- `MATHC_NO_EASING_FUNCTIONS`: don't define the easing functions. -You can decide which one you want to use. +You can define these preprocessors using the compiler's option `-D` or using the compiler's option `-include` to include a configuration header with the configuration preprocessors inside it. -Examples: +Example of a configuration header that makes `mint_t` a `int16_t`, `mfloat_t` a `GLfloat` and uses the standard math functions with double floating-point precision: ```c -/* Pass by value and return a value */ -struct mat projection = matrix_ortho(-100.0f, 100.0f, -100.0f, 100.0f, 0.0f, 1.0f); -struct mat view = matrix_look_at(to_vector3(0.0f, 0.0f, 1.0f), - to_vector3(0.0f, 0.0f, 0.0f), - to_vector3(0.0f, 1.0f, 0.0f)); -struct mat pv = matrix_multiply_matrix(projection, view); - -/* Pass by pointer */ -struct vec pos = {0}; -struct vec target = {0}; -struct vec up = {0}; -struct mat projection; -struct mat view; -struct mat multiplied_matrix; - -to_pvector3(0.0f, 0.0f, 1.0f, &pos); -to_pvector3(0.0f, 0.0f, 0.0f, &target); -to_pvector3(0.0f, 1.0f, 0.0f, &up); -pmatrix_ortho(-100.0f, 100.0f, -100.0f, 100.0f, 0.0f, 1.0f, &projection); -pmatrix_look_at(&pos, &target, &up, &view); -pmatrix_multiply_matrix(&projection, &view, &multiplied_matrix); -``` +#include -# Vectors +#define MATHC_USE_INT16 +#define MATHC_FLOATING_POINT_TYPE GLfloat +#define MATHC_USE_DOUBLE_FLOATING_POINT +``` -All vectors (2D, 3D and quaternions ) use the same structure type `struct vec`. +## Types -Examples: +By default, vectors, quaternions and matrices can be declared as arrays of `mint_t`, arrays of `mfloat_t`, or structures. -```c -/* Rotate a 2D vector 90º */ -struct vec direction = to_vector2(0.0f, -1.0f); -direction = vector2_rotate(90.0f * M_PIF / 180.0f); +## Functions -/* Get the angle (radians) of a 2D vector */ -float angle = vector2_angle(direction); +By default, MATHC has functions that take as argument arrays of `mint_t`, arrays of `mfloat_t`, structures as value, or pointer to structures. Functions that take structure as value have a prefix `s`. Functions that take structure pointer have a prefix `ps`. -/* Create a 3D vector */ -struct vec position = to_vector3(0.0f, 0.0f, 0.0f); +## Easing Functions -/* Create a quaternion */ -struct vec quaternion = to_quaternion(0.0f, 0.0f, 0.0f, 1.0f); -/* Spherical interpolation between two quaternions */ -struct vec interpolated = quaternion_spherical_linear_interpolation(a, b, 0.5f); -``` +The easing functions are an implementation of the functions presented in [easings.net](http://easings.net/), useful particularly for animations. -# Matrices +Easing functions take a value inside the range `0.0-1.0` and usually will return a value inside that same range. -All matrices are 4×4. There are functions for setting up projection matrices, view matrices and model matrices. +## Usage -Usually, model matrices are used to modify vertices on client-side or GPU-side. If you want to modify on client-side, you can use the functions `matrix_multiply_f4()` or `pmatrix_multiply_f4()` to modify an array with 4 `float` elements. Example: +Creating a "look at" view matrix, useful for 3D programming: ```c -float v[4] = {0.0f, 10.0f, 0.0f, 1.0f}; /* Compoments X, Y, Z and W */ -struct mat rotation = matrix_rotation_z(to_radians(45.0f)); -matrix_multiply_f4(rotation, v); +mfloat_t position[VEC3_SIZE]; +mfloat_t target[VEC3_SIZE]; +mfloat_t up[VEC3_SIZE]; +mfloat_t view[MAT4_SIZE]; + +mat4_look_at(view, + vec3(position, 0.0, 0.0, 10.0), + vec3(target, 0.0, 0.0, 0.0), + vec3(up, 0.0, 1.0, 0.0)); ``` -If you want to modify on GPU-side, you can use the functions `matrix_to_array()` or `pmatrix_to_array()` to push the matrix to an array with 16 `float` elements. Example: +Creating a perspective projection matrix: ```c -float v[16]; -struct mat projection = matrix_ortho(-100.0f, 100.0f, -100.0f, 100.0f, 0.0f, 1.0f); -struct mat view = matrix_look_at(to_vector3(0.0f, 0.0f, 1.0f), - to_vector3(0.0f, 0.0f, 0.0f), - to_vector3(0.0f, 1.0f, 0.0f)); -struct mat pv = matrix_multiply_matrix(projection, view); -matrix_to_array(pv, v); -``` - -# Easing Functions +mfloat_t perspective[MAT4_SIZE]; -The easing functions are an implementation of the functions presented in [easing.net](http://easings.net/). They are mainly useful for animations. - -Easing functions take a value that range from `0.0f` to `1.0f` and usually will return a value inside that same range. However, in some of the easing functions, the returned value extrapolate that range. - -# Contributing +mat4_perspective(perspective, to_radians(60.0), 1.0, 0.1, 100.0); +``` -- Before sending any pull request, open an issue asking if the feature or fix is already being worked on. -- If you find any error, you can open an issue. -- You can request more useful functions in the issues regarding 2D vectors, 3D vectors, quaternions and matrices. If you have already an implementation or know where to find, better. -- Everything here will stay licensed under ZLIB, which is a ***very*** permissive license. +Creating a model matrix: -# LICENSE +```c +mfloat_t position[VEC3_SIZE]; +mfloat_t scaling[VEC3_SIZE]; +struct { + mfloat_t position[MAT4_SIZE]; + mfloat_t rotation[MAT4_SIZE]; + mfloat_t scaling[MAT4_SIZE]; + mfloat_t model[MAT4_SIZE]; +} matrices; + +/* Position */ +mat4_identity(matrices.position); +mat4_translation(matrices.position, + vec3(position, 0.0, 0.0, 0.0)); + +/* Rotation */ +mat4_identity(matrices.rotation); +mat4_rotation_x(matrices.rotation, to_radians(30.0)); + +/* Scaling */ +mat4_identity(matrices.scaling); +mat4_translation(matrices.scaling, + vec3(scaling, 1.0, 1.0, 1.0)); + +/* Model matrix */ +mat4_multiply(matrices.model, matrices.scaling, matrices.rotation); +mat4_multiply(matrices.model, matrices.position, matrices.model); +``` -The source code of this project is licensed under the terms of the ZLIB license: +## License -Copyright (C) 2016 Felipe Ferreira da Silva +Copyright © 2018 Felipe Ferreira da Silva This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/REFERENCE.md b/REFERENCE.md deleted file mode 100644 index 53446b1..0000000 --- a/REFERENCE.md +++ /dev/null @@ -1,285 +0,0 @@ -# MathC Reference - -## Utils - -```c -int nearly_equal(float a, float b, float epsilon); -``` - -Used to compare two `float` variables with an error margin `epsilon`. The standard header `` comes with the macro `FLT_EPSILON` that can be used as the error margin. Greater values are also acceptable in most cases, such as `FLT_EPSILON * 10.0f` and `FLT_EPSILON * 100.0f`. - -Returns `TRUE` if the values are accepted as equal and `FALSE` otherwise. - -```c -float to_radians(float degrees); -``` - -Return the angle `degrees` in radians. - -```c -float to_degrees(float radians); -``` - -Return the angle `radians` in degrees. - -## Vector and Quaternion Structure - -Vectors (2D and 3D) and quaternions use the same structure `struct vec`. - -```c -struct vec { - float x; - float y; - float z; - float w; -}; -``` - -## 2D Vector - -When using 2D vectors, it is good practice to initialize the variable with `0`, so the value of the `z` component is set to `0.0f`. - -Example: - -``` -struct vec position = {0}; -``` - -The only functions that will set the `z` component of a 2D vector to `0.0f` are `to_pvector2()` and `to_vector2()`. The other operation functions will not change the `z` value, since it's useful when you need to modify yourself. - -Every function for 2D vectors will set the value of `w` to `1.0f`. - -```c -void to_pvector2(float x, float y, struct vec *result); -struct vec to_vector2(float x, float y); -``` - -The result is a 2D vector for the position `x` and `y`. The value of `z` is set to `0.0f` and the value of `w` is set to `1.0f`. - -```c -void pvector2_add(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_add(struct vec a, struct vec b); -``` - -The result is a 2D vector for the addition of the 2D vector `a` with the 2D vector `b`. - -```c -void pvector2_subtract(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_subtract(struct vec a, struct vec b); -``` - -The result is a 2D vector for the subraction of the 2D vector `a` with the 2D vector `b`. - -```c -void pvector2_scale(struct vec *a, float scale, struct vec *result); -struct vec vector2_scale(struct vec a, float scale); -``` - -The result is a 2D vector for the scaling of the 2D vector `a` with the value `scale`. - -```c -void pvector2_multiply(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_multiply(struct vec a, struct vec b); -``` - -The result is a 2D vector for the multiplication of the 2D vector `a` with the 2D vector `b`. - -```c -void pvector2_divide(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_divide(struct vec a, struct vec b); -``` - -The result is a 2D vector for the division of the 2D vector `a` with the 2D vector `b`. - -```c -void pvector2_negative(struct vec *a, struct vec *result); -struct vec vector2_negative(struct vec a); -``` - -The result is a 2D vector for the negation of the 2D vector `a`. - -```c -void pvector2_inverse(struct vec *a, struct vec *result); -struct vec vector2_inverse(struct vec a); -``` - -The result is a 2D vector for the inversion of the 2D vector `a`. - -```c -void pvector2_abs(struct vec *a, struct vec *result); -struct vec vector2_abs(struct vec a); -``` - -The result is a 2D vector for the 2D vector `a` with absolute values. - -```c -void pvector2_floor(struct vec *a, struct vec *result); -struct vec vector2_floor(struct vec a); -``` - -The result is a 2D vector for the 2D vector `a` with floored values. - -```c -void pvector2_ceil(struct vec *a, struct vec *result); -struct vec vector2_ceil(struct vec a); -``` - -The result is a 2D vector for the 2D vector `a` with ceiled values. - -```c -void pvector2_round(struct vec *a, struct vec *result); -struct vec vector2_round(struct vec a); -``` - -The result is a 2D vector for the 2D vector `a` with rounded values. - -```c -void pvector2_max(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_max(struct vec a, struct vec b); -``` - -The result is a 2D vector with the maximum values between the 2D vector `a` and the 2D vector `b`. - -```c -void pvector2_min(struct vec *a, struct vec *b, struct vec *result); -struct vec vector2_min(struct vec a, struct vec b); -``` - -The result is a 2D vector with the minimum values between the 2D vector `a` and the 2D vector `b`. - -```c -float pvector2_dot(struct vec *a, struct vec *b); -float vector2_dot(struct vec a, struct vec b); -``` - -The result is the dot product of the 2D vector `a` with the 2D vector `b`. - -```c -float pvector2_angle(struct vec *a); -float vector2_angle(struct vec a); -``` - -The result is the angle of the 2D vector `a` with the origin. - -```c -float pvector2_length_squared(struct vec *a); -float vector2_length_squared(struct vec a); -``` - -The result is the length squared of the 2D vector `a`. - -```c -float pvector2_length(struct vec *a); -float vector2_length(struct vec a); -``` - -The result is the length of the 2D vector `a`. - -```c -void pvector2_normalize(struct vec *a, struct vec *result); -struct vec vector2_normalize(struct vec a); -``` - -The result is a 2D vector for the normalized 2D vector `a`. - -```c -void pvector2_slide(struct vec *a, struct vec *normal, struct vec *result); -struct vec vector2_slide(struct vec a, struct vec normal); -``` - -The result is a 2D vector for the slided 2D vector `a` against the 2D vector `normal`. - -```c -void pvector2_reflect(struct vec *a, struct vec *normal, struct vec *result); -struct vec vector2_reflect(struct vec a, struct vec normal); -``` - -The result is a 2D vector for the reflected 2D vector `a` against the 2D vector `normal`. - -```c -void pvector2_tangent(struct vec *a, struct vec *result); -struct vec vector2_tangent(struct vec a); -``` - -The result is a 2D vector for the tangent of the 2D vector `a`. - -```c -void pvector2_rotate(struct vec *a, float angle, struct vec *result); -struct vec vector2_rotate(struct vec a, float angle); -``` - -The result is a 2D vector for the rotated 2D vector `a` with the value in radians `angle`. - -```c -float pvector2_distance_to(struct vec *a, struct vec *b); -float vector2_distance_to(struct vec a, struct vec b); -``` - -The result is the distance between the 2D vector `a` and the 2D vector `b`. - -```c -float pvector2_distance_squared_to(struct vec *a, struct vec *b); -float vector2_distance_squared_to(struct vec a, struct vec b); -``` - -The result is the distance squared between the 2D vector `a` and the 2D vector `b`. - -```c -void pvector2_linear_interpolation(struct vec *a, struct vec *b, float, p, struct vec *result); -struct vec vector2_linear_interpolation(struct vec a, struct vec b, float p); -``` - -The result is a 2D vector for the linear interpolation between the 2D vector `a` and the 2D vector `b` with the value `p`. - -### Easing Functions - -```c -float quadratic_ease_in(float p); -float quadratic_ease_out(float p); -float quadratic_ease_in_out(float p); -float cubic_ease_in(float p); -float cubic_ease_out(float p); -float cubic_ease_in_out(float p); -float quartic_ease_in(float p); -float quartic_ease_out(float p); -float quartic_ease_in_out(float p); -float quintic_ease_in(float p); -float quintic_ease_out(float p); -float quintic_ease_in_out(float p); -float sine_ease_in(float p); -float sine_ease_out(float p); -float sine_ease_in_out(float p); -float circular_ease_in(float p); -float circular_ease_out(float p); -float circular_ease_in_out(float p); -float exponential_ease_in(float p); -float exponential_ease_out(float p); -float exponential_ease_in_out(float p); -float elastic_ease_in(float p); -float elastic_ease_out(float p); -float elastic_ease_in_out(float p); -float back_ease_in(float p); -float back_ease_out(float p); -float back_ease_in_out(float p); -float bounce_ease_in(float p); -float bounce_ease_out(float p); -float bounce_ease_in_out(float p); -``` - -Each easing function will return a rate of change for `p`. The value of `p` must be inside the range `0.0f-1.0f`. - -The graphic visualization of the easing functions can be found on [easing.net](http://easings.net/). - -# LICENSE - -The source code of this project is licensed under the terms of the ZLIB license: - -Copyright (C) 2016 Felipe Ferreira da Silva - -This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. diff --git a/mathc.c b/mathc.c index 9af25d6..888d9f3 100644 --- a/mathc.c +++ b/mathc.c @@ -1,5 +1,5 @@ /* -Copyright (C) 2016 Felipe Ferreira da Silva +Copyright © 2018 Felipe Ferreira da Silva This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of @@ -18,1885 +18,6867 @@ the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#include -#include #include "mathc.h" -/* Check C standard */ -#ifdef __STDC__ - #define PREDEF_STANDARD_C89 - #ifdef __STDC_VERSION__ - #if __STDC_VERSION__ >= 199901L - #define PREDEF_STANDARD_C99 - #endif - #endif +#if defined(MATHC_USE_INT) +mint_t clampi(mint_t value, mint_t min, mint_t max) +{ + if (value < min) { + value = min; + } else if (value > max) { + value = max; + } + return value; +} +#endif + +#if defined(MATHC_USE_FLOATING_POINT) +bool nearly_equal(mfloat_t a, mfloat_t b, mfloat_t epsilon) +{ + bool result = false; + if (a == b) { + result = true; + } else if (MFABS(a - b) <= epsilon) { + result = true; + } + return result; +} + +mfloat_t to_radians(mfloat_t degrees) +{ + return MRADIANS(degrees); +} + +mfloat_t to_degrees(mfloat_t radians) +{ + return MDEGREES(radians); +} + +mfloat_t clampf(mfloat_t value, mfloat_t min, mfloat_t max) +{ + if (value < min) { + value = min; + } else if (value > max) { + value = max; + } + return value; +} +#endif + +#if defined(MATHC_USE_INT) +bool vec2i_is_zero(mint_t *v0) +{ + return v0[0] == 0 && v0[1] == 0; +} + +bool vec2i_is_equal(mint_t *v0, mint_t *v1) +{ + return v0[0] == v1[0] && v0[1] == v1[1]; +} + +mint_t *vec2i(mint_t *result, mint_t x, mint_t y) +{ + result[0] = x; + result[1] = y; + return result; +} + +mint_t *vec2i_assign(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec2i_assign_vec2(mint_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + return result; +} +#endif + +mint_t *vec2i_zero(mint_t *result) +{ + result[0] = 0; + result[1] = 0; + return result; +} + +mint_t *vec2i_one(mint_t *result) +{ + result[0] = 1; + result[1] = 1; + return result; +} + +mint_t *vec2i_sign(mint_t *result, mint_t *v0) +{ + if (v0[0] > 0) { + result[0] = 1; + } else if (v0[0] < 0) { + result[0] = -1; + } else { + result[0] = 0; + } + if (v0[1] > 0) { + result[1] = 1; + } else if (v0[1] < 0) { + result[1] = -1; + } else { + result[1] = 0; + } + return result; +} + +mint_t *vec2i_add(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + return result; +} + +mint_t *vec2i_add_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] + i; + result[1] = v0[1] + i; + return result; +} + +mint_t *vec2i_subtract(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + return result; +} + +mint_t *vec2i_subtract_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] - i; + result[1] = v0[1] - i; + return result; +} + +mint_t *vec2i_multiply(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + return result; +} + +mint_t *vec2i_multiply_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] * i; + result[1] = v0[1] * i; + return result; +} + +mint_t *vec2i_divide(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + return result; +} + +mint_t *vec2i_divide_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] / i; + result[1] = v0[1] / i; + return result; +} + +mint_t *vec2i_snap(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = (v0[0] / v1[0]) * v1[0]; + result[1] = (v0[1] / v1[1]) * v1[1]; + return result; +} + +mint_t *vec2i_snap_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = (v0[0] / i) * i; + result[1] = (v0[1] / i) * i; + return result; +} + +mint_t *vec2i_negative(mint_t *result, mint_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + return result; +} + +mint_t *vec2i_abs(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + if (result[0] < 0) { + result[0] = -result[0]; + } + result[1] = v0[1]; + if (result[1] < 0) { + result[1] = -result[1]; + } + return result; +} + +mint_t *vec2i_max(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] > v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] > v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + return result; +} + +mint_t *vec2i_min(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] < v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] < v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + return result; +} + +mint_t *vec2i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2) +{ + vec2i_min(result, v0, v1); + vec2i_max(result, v0, v2); + return result; +} + +mint_t *vec2i_tangent(mint_t *result, mint_t *v0) +{ + mint_t a0 = v0[0]; + mint_t a1 = v0[1]; + result[0] = a1; + result[1] = -a0; + return result; +} + +bool vec3i_is_zero(mint_t *v0) +{ + return v0[0] == 0 && v0[1] == 0 && v0[2] == 0; +} + +bool vec3i_is_equal(mint_t *v0, mint_t *v1) +{ + return v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2]; +} + +mint_t *vec3i(mint_t *result, mint_t x, mint_t y, mint_t z) +{ + result[0] = x; + result[1] = y; + result[2] = z; + return result; +} + +mint_t *vec3i_assign(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec3i_assign_vec3(mint_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + return result; +} +#endif + +mint_t *vec3i_zero(mint_t *result) +{ + result[0] = 0; + result[1] = 0; + result[2] = 0; + return result; +} + +mint_t *vec3i_one(mint_t *result) +{ + result[0] = 1; + result[1] = 1; + result[2] = 1; + return result; +} + +mint_t *vec3i_sign(mint_t *result, mint_t *v0) +{ + if (v0[0] > 0) { + result[0] = 1; + } else if (v0[0] < 0) { + result[0] = -1; + } else { + result[0] = 0; + } + if (v0[1] > 0) { + result[1] = 1; + } else if (v0[1] < 0) { + result[1] = -1; + } else { + result[1] = 0; + } + if (v0[2] > 0) { + result[2] = 1; + } else if (v0[2] < 0) { + result[2] = -1; + } else { + result[2] = 0; + } + return result; +} + +mint_t *vec3i_add(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + result[2] = v0[2] + v1[2]; + return result; +} + +mint_t *vec3i_add_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] + i; + result[1] = v0[1] + i; + result[2] = v0[2] + i; + return result; +} + +mint_t *vec3i_subtract(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + result[2] = v0[2] - v1[2]; + return result; +} + +mint_t *vec3i_subtract_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] - i; + result[1] = v0[1] - i; + result[2] = v0[2] - i; + return result; +} + +mint_t *vec3i_multiply(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + result[2] = v0[2] * v1[2]; + return result; +} + +mint_t *vec3i_multiply_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] * i; + result[1] = v0[1] * i; + result[2] = v0[2] * i; + return result; +} + +mint_t *vec3i_divide(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + result[2] = v0[2] / v1[2]; + return result; +} + +mint_t *vec3i_divide_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] / i; + result[1] = v0[1] / i; + result[2] = v0[2] / i; + return result; +} + +mint_t *vec3i_snap(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = (v0[0] / v1[0]) * v1[0]; + result[1] = (v0[1] / v1[1]) * v1[1]; + result[2] = (v0[2] / v1[2]) * v1[2]; + return result; +} + +mint_t *vec3i_snap_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = (v0[0] / i) * i; + result[1] = (v0[1] / i) * i; + result[2] = (v0[2] / i) * i; + return result; +} + +mint_t *vec3i_cross(mint_t *result, mint_t *v0, mint_t *v1) +{ + mint_t cross[VEC3_SIZE]; + cross[0] = v0[1] * v1[2] - v0[2] * v1[1]; + cross[1] = v0[2] * v1[0] - v0[0] * v1[2]; + cross[2] = v0[0] * v1[1] - v0[1] * v1[0]; + result[0] = cross[0]; + result[1] = cross[1]; + result[2] = cross[2]; + return result; +} + +mint_t *vec3i_negative(mint_t *result, mint_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + result[2] = -v0[2]; + return result; +} + +mint_t *vec3i_abs(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + if (result[0] < 0) { + result[0] = -result[0]; + } + result[1] = v0[1]; + if (result[1] < 0) { + result[1] = -result[1]; + } + result[2] = v0[2]; + if (result[2] < 0) { + result[2] = -result[2]; + } + return result; +} + +mint_t *vec3i_max(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] > v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] > v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + if (v0[2] > v1[2]) { + result[2] = v0[2]; + } else { + result[2] = v1[2]; + } + return result; +} + +mint_t *vec3i_min(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] < v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] < v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + if (v0[2] < v1[2]) { + result[2] = v0[2]; + } else { + result[2] = v1[2]; + } + return result; +} + +mint_t *vec3i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2) +{ + vec3i_min(result, v0, v1); + vec3i_max(result, v0, v2); + return result; +} + +bool vec4i_is_zero(mint_t *v0) +{ + return v0[0] == 0 && v0[1] == 0 && v0[2] == 0 && v0[3] == 0; +} + +bool vec4i_is_equal(mint_t *v0, mint_t *v1) +{ + return v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2] && v0[3] == v1[3]; +} + +mint_t *vec4i(mint_t *result, mint_t x, mint_t y, mint_t z, mint_t w) +{ + result[0] = x; + result[1] = y; + result[2] = z; + result[3] = w; + return result; +} + +mint_t *vec4i_assign(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + result[3] = v0[3]; + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec4i_assign_vec4(mint_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + result[3] = v0[3]; + return result; +} +#endif + +mint_t *vec4i_zero(mint_t *result) +{ + result[0] = 0; + result[1] = 0; + result[2] = 0; + result[3] = 0; + return result; +} + +mint_t *vec4i_one(mint_t *result) +{ + result[0] = 1; + result[1] = 1; + result[2] = 1; + result[3] = 1; + return result; +} + +mint_t *vec4i_sign(mint_t *result, mint_t *v0) +{ + if (v0[0] > 0) { + result[0] = 1; + } else if (v0[0] < 0) { + result[0] = -1; + } else { + result[0] = 0; + } + if (v0[1] > 0) { + result[1] = 1; + } else if (v0[1] < 0) { + result[1] = -1; + } else { + result[1] = 0; + } + if (v0[2] > 0) { + result[2] = 1; + } else if (v0[2] < 0) { + result[2] = -1; + } else { + result[2] = 0; + } + if (v0[3] > 0) { + result[3] = 1; + } else if (v0[3] < 0) { + result[3] = -1; + } else { + result[3] = 0; + } + return result; +} + +mint_t *vec4i_add(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + result[2] = v0[2] + v1[2]; + result[3] = v0[3] + v1[3]; + return result; +} + +mint_t *vec4i_add_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] + i; + result[1] = v0[1] + i; + result[2] = v0[2] + i; + result[3] = v0[3] + i; + return result; +} + +mint_t *vec4i_subtract(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + result[2] = v0[2] - v1[2]; + result[3] = v0[3] - v1[3]; + return result; +} + +mint_t *vec4i_subtract_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] - i; + result[1] = v0[1] - i; + result[2] = v0[2] - i; + result[3] = v0[3] - i; + return result; +} + +mint_t *vec4i_multiply(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + result[2] = v0[2] * v1[2]; + result[3] = v0[3] * v1[3]; + return result; +} + +mint_t *vec4i_multiply_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] * i; + result[1] = v0[1] * i; + result[2] = v0[2] * i; + result[3] = v0[3] * i; + return result; +} + +mint_t *vec4i_divide(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + result[2] = v0[2] / v1[2]; + result[3] = v0[3] / v1[3]; + return result; +} + +mint_t *vec4i_divide_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = v0[0] / i; + result[1] = v0[1] / i; + result[2] = v0[2] / i; + result[3] = v0[3] / i; + return result; +} + +mint_t *vec4i_snap(mint_t *result, mint_t *v0, mint_t *v1) +{ + result[0] = (v0[0] / v1[0]) * v1[0]; + result[1] = (v0[1] / v1[1]) * v1[1]; + result[2] = (v0[2] / v1[2]) * v1[2]; + result[3] = (v0[3] / v1[3]) * v1[3]; + return result; +} + +mint_t *vec4i_snap_i(mint_t *result, mint_t *v0, mint_t i) +{ + result[0] = (v0[0] / i) * i; + result[1] = (v0[1] / i) * i; + result[2] = (v0[2] / i) * i; + result[3] = (v0[3] / i) * i; + return result; +} + +mint_t *vec4i_negative(mint_t *result, mint_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + result[2] = -v0[2]; + result[3] = -v0[3]; + return result; +} + +mint_t *vec4i_abs(mint_t *result, mint_t *v0) +{ + result[0] = v0[0]; + if (result[0] < 0) { + result[0] = -result[0]; + } + result[1] = v0[1]; + if (result[1] < 0) { + result[1] = -result[1]; + } + result[2] = v0[2]; + if (result[2] < 0) { + result[2] = -result[2]; + } + result[3] = v0[3]; + if (result[3] < 0) { + result[3] = -result[3]; + } + return result; +} + +mint_t *vec4i_max(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] > v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] > v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + if (v0[2] > v1[2]) { + result[2] = v0[2]; + } else { + result[2] = v1[2]; + } + if (v0[3] > v1[3]) { + result[3] = v0[3]; + } else { + result[3] = v1[3]; + } + return result; +} + +mint_t *vec4i_min(mint_t *result, mint_t *v0, mint_t *v1) +{ + if (v0[0] < v1[0]) { + result[0] = v0[0]; + } else { + result[0] = v1[0]; + } + if (v0[1] < v1[1]) { + result[1] = v0[1]; + } else { + result[1] = v1[1]; + } + if (v0[2] < v1[2]) { + result[2] = v0[2]; + } else { + result[2] = v1[2]; + } + if (v0[3] < v1[3]) { + result[3] = v0[3]; + } else { + result[3] = v1[3]; + } + return result; +} + +mint_t *vec4i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2) +{ + vec4i_min(result, v0, v1); + vec4i_max(result, v0, v2); + return result; +} +#endif + +#if defined(MATHC_USE_FLOATING_POINT) +bool vec2_is_zero(mfloat_t *v0) +{ + return MFABS(v0[0]) < MFLT_EPSILON && MFABS(v0[1]) < MFLT_EPSILON; +} + +bool vec2_is_equal(mfloat_t *v0, mfloat_t *v1) +{ + return MFABS(v0[0] - v1[0]) < MFLT_EPSILON && MFABS(v0[1] - v1[1]) < MFLT_EPSILON; +} + +mfloat_t *vec2(mfloat_t *result, mfloat_t x, mfloat_t y) +{ + result[0] = x; + result[1] = y; + return result; +} + +mfloat_t *vec2_assign(mfloat_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + return result; +} + +#if defined(MATHC_USE_INT) +mfloat_t *vec2_assign_vec2i(mfloat_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + return result; +} +#endif + +mfloat_t *vec2_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *vec2_one(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *vec2_sign(mfloat_t *result, mfloat_t *v0) +{ + if (v0[0] > MFLOAT_C(0.0)) { + result[0] = MFLOAT_C(1.0); + } else if (v0[0] < MFLOAT_C(0.0)) { + result[0] = -MFLOAT_C(1.0); + } else { + result[0] = MFLOAT_C(0.0); + } + if (v0[1] > MFLOAT_C(0.0)) { + result[1] = MFLOAT_C(1.0); + } else if (v0[1] < MFLOAT_C(0.0)) { + result[1] = -MFLOAT_C(1.0); + } else { + result[1] = MFLOAT_C(0.0); + } + return result; +} + +mfloat_t *vec2_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + return result; +} + +mfloat_t *vec2_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] + f; + result[1] = v0[1] + f; + return result; +} + +mfloat_t *vec2_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + return result; +} + +mfloat_t *vec2_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] - f; + result[1] = v0[1] - f; + return result; +} + +mfloat_t *vec2_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + return result; +} + +mfloat_t *vec2_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] * f; + result[1] = v0[1] * f; + return result; +} + +mfloat_t *vec2_multiply_mat2(mfloat_t *result, mfloat_t *v0, mfloat_t *m0) +{ + mfloat_t x = v0[0]; + mfloat_t y = v0[1]; + result[0] = m0[0] * x + m0[2] * y; + result[1] = m0[1] * x + m0[3] * y; + return result; +} + +mfloat_t *vec2_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + return result; +} + +mfloat_t *vec2_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] / f; + result[1] = v0[1] / f; + return result; +} + +mfloat_t *vec2_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFLOOR(v0[0] / v1[0]) * v1[0]; + result[1] = MFLOOR(v0[1] / v1[1]) * v1[1]; + return result; +} + +mfloat_t *vec2_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = MFLOOR(v0[0] / f) * f; + result[1] = MFLOOR(v0[1] / f) * f; + return result; +} + +mfloat_t *vec2_negative(mfloat_t *result, mfloat_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + return result; +} + +mfloat_t *vec2_abs(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFABS(v0[0]); + result[1] = MFABS(v0[1]); + return result; +} + +mfloat_t *vec2_floor(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFLOOR(v0[0]); + result[1] = MFLOOR(v0[1]); + return result; +} + +mfloat_t *vec2_ceil(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MCEIL(v0[0]); + result[1] = MCEIL(v0[1]); + return result; +} + +mfloat_t *vec2_round(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MROUND(v0[0]); + result[1] = MROUND(v0[1]); + return result; +} + +mfloat_t *vec2_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMAX(v0[0], v1[0]); + result[1] = MFMAX(v0[1], v1[1]); + return result; +} + +mfloat_t *vec2_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMIN(v0[0], v1[0]); + result[1] = MFMIN(v0[1], v1[1]); + return result; +} + +mfloat_t *vec2_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2) +{ + vec2_min(result, v0, v1); + vec2_max(result, v0, v2); + return result; +} + +mfloat_t *vec2_normalize(mfloat_t *result, mfloat_t *v0) +{ + mfloat_t l = MSQRT(v0[0] * v0[0] + v0[1] * v0[1]); + result[0] = v0[0] / l; + result[1] = v0[1] / l; + return result; +} + +mfloat_t vec2_dot(mfloat_t *v0, mfloat_t *v1) +{ + return v0[0] * v1[0] + v0[1] * v1[1]; +} + +mfloat_t *vec2_project(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + mfloat_t d = vec2_dot(v1, v1); + mfloat_t s = vec2_dot(v0, v1) / d; + result[0] = v1[0] * s; + result[1] = v1[1] * s; + return result; +} + +mfloat_t *vec2_slide(mfloat_t *result, mfloat_t *v0, mfloat_t *normal) +{ + mfloat_t d = vec2_dot(v0, normal); + result[0] = v0[0] - normal[0] * d; + result[1] = v0[1] - normal[1] * d; + return result; +} + +mfloat_t *vec2_reflect(mfloat_t *result, mfloat_t *v0, mfloat_t *normal) +{ + mfloat_t d = MFLOAT_C(2.0) * vec2_dot(v0, normal); + result[0] = normal[0] * d - v0[0]; + result[1] = normal[1] * d - v0[1]; + return result; +} + +mfloat_t *vec2_tangent(mfloat_t *result, mfloat_t *v0) +{ + mfloat_t a0 = v0[0]; + mfloat_t a1 = v0[1]; + result[0] = a1; + result[1] = -a0; + return result; +} + +mfloat_t *vec2_rotate(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + mfloat_t cs = MCOS(f); + mfloat_t sn = MSIN(f); + mfloat_t x = v0[0]; + mfloat_t y = v0[1]; + result[0] = x * cs - y * sn; + result[1] = x * sn + y * cs; + return result; +} + +mfloat_t *vec2_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f) +{ + result[0] = v0[0] + (v1[0] - v0[0]) * f; + result[1] = v0[1] + (v1[1] - v0[1]) * f; + return result; +} + +mfloat_t *vec2_bezier3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t f) +{ + mfloat_t tmp0[VEC2_SIZE]; + mfloat_t tmp1[VEC2_SIZE]; + vec2_lerp(tmp0, v0, v1, f); + vec2_lerp(tmp1, v1, v2, f); + vec2_lerp(result, tmp0, tmp1, f); + return result; +} + +mfloat_t *vec2_bezier4(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t *v3, mfloat_t f) +{ + mfloat_t tmp0[VEC2_SIZE]; + mfloat_t tmp1[VEC2_SIZE]; + mfloat_t tmp2[VEC2_SIZE]; + mfloat_t tmp3[VEC2_SIZE]; + mfloat_t tmp4[VEC2_SIZE]; + vec2_lerp(tmp0, v0, v1, f); + vec2_lerp(tmp1, v1, v2, f); + vec2_lerp(tmp2, v2, v3, f); + vec2_lerp(tmp3, tmp0, tmp1, f); + vec2_lerp(tmp4, tmp1, tmp2, f); + vec2_lerp(result, tmp3, tmp4, f); + return result; +} + +mfloat_t vec2_angle(mfloat_t *v0) +{ + return MATAN2(v0[1], v0[0]); +} + +mfloat_t vec2_length(mfloat_t *v0) +{ + return MSQRT(v0[0] * v0[0] + v0[1] * v0[1]); +} + +mfloat_t vec2_length_squared(mfloat_t *v0) +{ + return v0[0] * v0[0] + v0[1] * v0[1]; +} + +mfloat_t vec2_distance(mfloat_t *v0, mfloat_t *v1) +{ + return MSQRT((v0[0] - v1[0]) * (v0[0] - v1[0]) + (v0[1] - v1[1]) * (v0[1] - v1[1])); +} + +mfloat_t vec2_distance_squared(mfloat_t *v0, mfloat_t *v1) +{ + return (v0[0] - v1[0]) * (v0[0] - v1[0]) + (v0[1] - v1[1]) * (v0[1] - v1[1]); +} + +bool vec2_linear_independent(mfloat_t *v0, mfloat_t *v1) +{ + return (v0[0] * v1[1] - v1[0] * v0[1]) != 0; +} + +mfloat_t** vec2_orthonormalization(mfloat_t result[2][2], mfloat_t basis[2][2]) +{ + mfloat_t v0[2]; + mfloat_t v1[2]; + + for(int32_t i = 0; i < 2; ++i) { + v0[i] = basis[0][i]; + v1[i] = basis[1][i]; + } + + if (!vec2_linear_independent(v0, v1)) { + return (mfloat_t**)result; + } + + mfloat_t proju1[2]; + mfloat_t u0[2]; + mfloat_t u1[2]; + + for(int32_t i = 0; i < 2; ++i) { + u0[i] = v0[i]; + } + + vec2_project(proju1, v1, v0); + vec2_subtract(u1, v1, proju1); + vec2_normalize(result[0], u0); + vec2_normalize(result[1], u1); + + return (mfloat_t**)result; +} + +bool vec3_is_zero(mfloat_t *v0) +{ + return MFABS(v0[0]) < MFLT_EPSILON && MFABS(v0[1]) < MFLT_EPSILON && MFABS(v0[2]) < MFLT_EPSILON; +} + +bool vec3_is_equal(mfloat_t *v0, mfloat_t *v1) +{ + return MFABS(v0[0] - v1[0]) < MFLT_EPSILON && MFABS(v0[1] - v1[1]) < MFLT_EPSILON && MFABS(v0[2] - v1[2]) < MFLT_EPSILON; +} + +mfloat_t *vec3(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z) +{ + result[0] = x; + result[1] = y; + result[2] = z; + return result; +} + +mfloat_t *vec3_assign(mfloat_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + return result; +} + +#if defined(MATHC_USE_INT) +mfloat_t *vec3_assign_vec3i(mfloat_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + return result; +} +#endif + +mfloat_t *vec3_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *vec3_one(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(1.0); + result[2] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *vec3_sign(mfloat_t *result, mfloat_t *v0) +{ + if (v0[0] > MFLOAT_C(0.0)) { + result[0] = MFLOAT_C(1.0); + } else if (v0[0] < 0) { + result[0] = -MFLOAT_C(1.0); + } else { + result[0] = MFLOAT_C(0.0); + } + if (v0[1] > MFLOAT_C(0.0)) { + result[1] = MFLOAT_C(1.0); + } else if (v0[1] < 0) { + result[1] = -MFLOAT_C(1.0); + } else { + result[1] = MFLOAT_C(0.0); + } + if (v0[2] > MFLOAT_C(0.0)) { + result[2] = MFLOAT_C(1.0); + } else if (v0[2] < 0) { + result[2] = -MFLOAT_C(1.0); + } else { + result[2] = MFLOAT_C(0.0); + } + return result; +} + +mfloat_t *vec3_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + result[2] = v0[2] + v1[2]; + return result; +} + +mfloat_t *vec3_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] + f; + result[1] = v0[1] + f; + result[2] = v0[2] + f; + return result; +} + +mfloat_t *vec3_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + result[2] = v0[2] - v1[2]; + return result; +} + +mfloat_t *vec3_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] - f; + result[1] = v0[1] - f; + result[2] = v0[2] - f; + return result; +} + +mfloat_t *vec3_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + result[2] = v0[2] * v1[2]; + return result; +} + +mfloat_t *vec3_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] * f; + result[1] = v0[1] * f; + result[2] = v0[2] * f; + return result; +} + +mfloat_t *vec3_multiply_mat3(mfloat_t *result, mfloat_t *v0, mfloat_t *m0) +{ + mfloat_t x = v0[0]; + mfloat_t y = v0[1]; + mfloat_t z = v0[2]; + result[0] = m0[0] * x + m0[3] * y + m0[6] * z; + result[1] = m0[1] * x + m0[4] * y + m0[7] * z; + result[2] = m0[2] * x + m0[5] * y + m0[8] * z; + return result; +} + +mfloat_t *vec3_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + result[2] = v0[2] / v1[2]; + return result; +} + +mfloat_t *vec3_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] / f; + result[1] = v0[1] / f; + result[2] = v0[2] / f; + return result; +} + +mfloat_t *vec3_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFLOOR(v0[0] / v1[0]) * v1[0]; + result[1] = MFLOOR(v0[1] / v1[1]) * v1[1]; + result[2] = MFLOOR(v0[2] / v1[2]) * v1[2]; + return result; +} + +mfloat_t *vec3_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = MFLOOR(v0[0] / f) * f; + result[1] = MFLOOR(v0[1] / f) * f; + result[2] = MFLOOR(v0[2] / f) * f; + return result; +} + +mfloat_t *vec3_negative(mfloat_t *result, mfloat_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + result[2] = -v0[2]; + return result; +} + +mfloat_t *vec3_abs(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFABS(v0[0]); + result[1] = MFABS(v0[1]); + result[2] = MFABS(v0[2]); + return result; +} + +mfloat_t *vec3_floor(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFLOOR(v0[0]); + result[1] = MFLOOR(v0[1]); + result[2] = MFLOOR(v0[2]); + return result; +} + +mfloat_t *vec3_ceil(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MCEIL(v0[0]); + result[1] = MCEIL(v0[1]); + result[2] = MCEIL(v0[2]); + return result; +} + +mfloat_t *vec3_round(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MROUND(v0[0]); + result[1] = MROUND(v0[1]); + result[2] = MROUND(v0[2]); + return result; +} + +mfloat_t *vec3_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMAX(v0[0], v1[0]); + result[1] = MFMAX(v0[1], v1[1]); + result[2] = MFMAX(v0[2], v1[2]); + return result; +} + +mfloat_t *vec3_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMIN(v0[0], v1[0]); + result[1] = MFMIN(v0[1], v1[1]); + result[2] = MFMIN(v0[2], v1[2]); + return result; +} + +mfloat_t *vec3_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2) +{ + vec3_min(result, v0, v1); + vec3_max(result, v0, v2); + return result; +} + +mfloat_t *vec3_cross(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + mfloat_t cross[VEC3_SIZE]; + cross[0] = v0[1] * v1[2] - v0[2] * v1[1]; + cross[1] = v0[2] * v1[0] - v0[0] * v1[2]; + cross[2] = v0[0] * v1[1] - v0[1] * v1[0]; + result[0] = cross[0]; + result[1] = cross[1]; + result[2] = cross[2]; + return result; +} + +mfloat_t *vec3_normalize(mfloat_t *result, mfloat_t *v0) +{ + mfloat_t l = MSQRT(v0[0] * v0[0] + v0[1] * v0[1] + v0[2] * v0[2]); + result[0] = v0[0] / l; + result[1] = v0[1] / l; + result[2] = v0[2] / l; + return result; +} + +mfloat_t vec3_dot(mfloat_t *v0, mfloat_t *v1) +{ + return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; +} + +mfloat_t *vec3_project(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + mfloat_t d = vec3_dot(v1, v1); + mfloat_t s = vec3_dot(v0, v1) / d; + result[0] = v1[0] * s; + result[1] = v1[1] * s; + result[2] = v1[2] * s; + return result; +} + +mfloat_t *vec3_slide(mfloat_t *result, mfloat_t *v0, mfloat_t *normal) +{ + mfloat_t d = vec3_dot(v0, normal); + result[0] = v0[0] - normal[0] * d; + result[1] = v0[1] - normal[1] * d; + result[2] = v0[2] - normal[2] * d; + return result; +} + +mfloat_t *vec3_reflect(mfloat_t *result, mfloat_t *v0, mfloat_t *normal) +{ + mfloat_t d = MFLOAT_C(2.0) * vec3_dot(v0, normal); + result[0] = normal[0] * d - v0[0]; + result[1] = normal[1] * d - v0[1]; + result[2] = normal[2] * d - v0[2]; + return result; +} + +mfloat_t *vec3_rotate(mfloat_t *result, mfloat_t *v0, mfloat_t *ra, mfloat_t f) +{ + mfloat_t cs; + mfloat_t sn; + mfloat_t x; + mfloat_t y; + mfloat_t z; + mfloat_t rx; + mfloat_t ry; + mfloat_t rz; + cs = MCOS(f); + sn = MSIN(f); + x = v0[0]; + y = v0[1]; + z = v0[2]; + vec3_normalize(ra, ra); + rx = ra[0]; + ry = ra[1]; + rz = ra[2]; + result[0] = x * (cs + rx * rx * (1 - cs)) + y * (rx * ry * (1 - cs) - rz * sn) + z * (rx * rz * (1 - cs) + ry * sn); + result[1] = x * (ry * rx * (1 - cs) + rz * sn) + y * (cs + ry * ry * (1 - cs)) + z * (ry * rz * (1 - cs) - rx * sn); + result[2] = x * (rz * rx * (1 - cs) - ry * sn) + y * (rz * ry * (1 - cs) + rx * sn) + z * (cs + rz * rz * (1 - cs)); + return result; +} + +mfloat_t *vec3_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f) +{ + result[0] = v0[0] + (v1[0] - v0[0]) * f; + result[1] = v0[1] + (v1[1] - v0[1]) * f; + result[2] = v0[2] + (v1[2] - v0[2]) * f; + return result; +} + +mfloat_t *vec3_bezier3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t f) +{ + mfloat_t tmp0[VEC3_SIZE]; + mfloat_t tmp1[VEC3_SIZE]; + vec3_lerp(tmp0, v0, v1, f); + vec3_lerp(tmp1, v1, v2, f); + vec3_lerp(result, tmp0, tmp1, f); + return result; +} + +mfloat_t *vec3_bezier4(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t *v3, mfloat_t f) +{ + mfloat_t tmp0[VEC3_SIZE]; + mfloat_t tmp1[VEC3_SIZE]; + mfloat_t tmp2[VEC3_SIZE]; + mfloat_t tmp3[VEC3_SIZE]; + mfloat_t tmp4[VEC3_SIZE]; + vec3_lerp(tmp0, v0, v1, f); + vec3_lerp(tmp1, v1, v2, f); + vec3_lerp(tmp2, v2, v3, f); + vec3_lerp(tmp3, tmp0, tmp1, f); + vec3_lerp(tmp4, tmp1, tmp2, f); + vec3_lerp(result, tmp3, tmp4, f); + return result; +} + +mfloat_t vec3_length(mfloat_t *v0) +{ + return MSQRT(v0[0] * v0[0] + v0[1] * v0[1] + v0[2] * v0[2]); +} + +mfloat_t vec3_length_squared(mfloat_t *v0) +{ + return v0[0] * v0[0] + v0[1] * v0[1] + v0[2] * v0[2]; +} + +mfloat_t vec3_distance(mfloat_t *v0, mfloat_t *v1) +{ + return MSQRT((v0[0] - v1[0]) * (v0[0] - v1[0]) + (v0[1] - v1[1]) * (v0[1] - v1[1]) + (v0[2] - v1[2]) * (v0[2] - v1[2])); +} + +mfloat_t vec3_distance_squared(mfloat_t *v0, mfloat_t *v1) +{ + return (v0[0] - v1[0]) * (v0[0] - v1[0]) + (v0[1] - v1[1]) * (v0[1] - v1[1]) + (v0[2] - v1[2]) * (v0[2] - v1[2]); +} + +bool vec3_linear_independent(mfloat_t *v0, mfloat_t *v1, mfloat_t *v2) +{ + return v0[0] * v1[1] * v2[2] + v0[1] * v1[2] * v2[0] + v0[2] * v1[0] * v2[1] + - v0[2] * v1[1] * v2[0] - v0[1] * v1[0] * v2[2] - v0[0] * v1[2] * v2[1]; +} + +mfloat_t** vec3_orthonormalization(mfloat_t result[3][3], mfloat_t basis[3][3]) +{ + mfloat_t v0[3]; + mfloat_t v1[3]; + mfloat_t v2[3]; + + for(int32_t i = 0; i < 3; ++i) { + v0[i] = basis[0][i]; + v1[i] = basis[1][i]; + v2[i] = basis[2][i]; + } + + if (!vec3_linear_independent(v0, v1, v2)) { + return (mfloat_t**)result; + } + + mfloat_t proj[3]; + mfloat_t u0[3]; + mfloat_t u1[3]; + mfloat_t u2[3]; + + for(int32_t i = 0; i < 3; ++i) { + u0[i] = v0[i]; + } + + vec3_project(proj, v1, u0); + vec3_subtract(u1, v1, proj); + + vec3_project(proj, v2, u0); + vec3_subtract(u2, v2, proj); + vec3_project(proj, v2, u1); + vec3_subtract(u2, u2, proj); + + vec3_normalize(result[0], u0); + vec3_normalize(result[1], u1); + vec3_normalize(result[2], u2); + + return (mfloat_t**)result; +} + +bool vec4_is_zero(mfloat_t *v0) +{ + return MFABS(v0[0]) < MFLT_EPSILON && MFABS(v0[1]) < MFLT_EPSILON && MFABS(v0[2]) < MFLT_EPSILON && MFABS(v0[3]) < MFLT_EPSILON; +} + +bool vec4_is_equal(mfloat_t *v0, mfloat_t *v1) +{ + return MFABS(v0[0] - v1[0]) < MFLT_EPSILON && MFABS(v0[1] - v1[1]) < MFLT_EPSILON && MFABS(v0[2] - v1[2]) < MFLT_EPSILON && MFABS(v0[3] - v1[3]) < MFLT_EPSILON; +} + +mfloat_t *vec4(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) +{ + result[0] = x; + result[1] = y; + result[2] = z; + result[3] = w; + return result; +} + +mfloat_t *vec4_assign(mfloat_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + result[3] = v0[3]; + return result; +} + +#if defined(MATHC_USE_INT) +mfloat_t *vec4_assign_vec4i(mfloat_t *result, mint_t *v0) +{ + result[0] = v0[0]; + result[1] = v0[1]; + result[2] = v0[2]; + result[3] = v0[3]; + return result; +} +#endif + +mfloat_t *vec4_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *vec4_one(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(1.0); + result[2] = MFLOAT_C(1.0); + result[3] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *vec4_sign(mfloat_t *result, mfloat_t *v0) +{ + if (v0[0] > MFLOAT_C(0.0)) { + result[0] = MFLOAT_C(1.0); + } else if (v0[0] < 0) { + result[0] = -MFLOAT_C(1.0); + } else { + result[0] = MFLOAT_C(0.0); + } + if (v0[1] > MFLOAT_C(0.0)) { + result[1] = MFLOAT_C(1.0); + } else if (v0[1] < 0) { + result[1] = -MFLOAT_C(1.0); + } else { + result[1] = MFLOAT_C(0.0); + } + if (v0[2] > MFLOAT_C(0.0)) { + result[2] = MFLOAT_C(1.0); + } else if (v0[2] < 0) { + result[2] = -MFLOAT_C(1.0); + } else { + result[2] = MFLOAT_C(0.0); + } + if (v0[3] > MFLOAT_C(0.0)) { + result[3] = MFLOAT_C(1.0); + } else if (v0[3] < 0) { + result[3] = -MFLOAT_C(1.0); + } else { + result[3] = MFLOAT_C(0.0); + } + return result; +} + +mfloat_t *vec4_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] + v1[0]; + result[1] = v0[1] + v1[1]; + result[2] = v0[2] + v1[2]; + result[3] = v0[3] + v1[3]; + return result; +} + +mfloat_t *vec4_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] + f; + result[1] = v0[1] + f; + result[2] = v0[2] + f; + result[3] = v0[3] + f; + return result; +} + +mfloat_t *vec4_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] - v1[0]; + result[1] = v0[1] - v1[1]; + result[2] = v0[2] - v1[2]; + result[3] = v0[3] - v1[3]; + return result; +} + +mfloat_t *vec4_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] - f; + result[1] = v0[1] - f; + result[2] = v0[2] - f; + result[3] = v0[3] - f; + return result; +} + +mfloat_t *vec4_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] * v1[0]; + result[1] = v0[1] * v1[1]; + result[2] = v0[2] * v1[2]; + result[3] = v0[3] * v1[3]; + return result; +} + +mfloat_t *vec4_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] * f; + result[1] = v0[1] * f; + result[2] = v0[2] * f; + result[3] = v0[3] * f; + return result; +} + +mfloat_t *vec4_multiply_mat4(mfloat_t *result, mfloat_t *v0, mfloat_t *m0) +{ + mfloat_t x = v0[0]; + mfloat_t y = v0[1]; + mfloat_t z = v0[2]; + mfloat_t w = v0[3]; + result[0] = m0[0] * x + m0[4] * y + m0[8] * z + m0[12] * w; + result[1] = m0[1] * x + m0[5] * y + m0[9] * z + m0[13] * w; + result[2] = m0[2] * x + m0[6] * y + m0[10] * z + m0[14] * w; + result[3] = m0[3] * x + m0[7] * y + m0[11] * z + m0[15] * w; + return result; +} + +mfloat_t *vec4_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = v0[0] / v1[0]; + result[1] = v0[1] / v1[1]; + result[2] = v0[2] / v1[2]; + result[3] = v0[3] / v1[3]; + return result; +} + +mfloat_t *vec4_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = v0[0] / f; + result[1] = v0[1] / f; + result[2] = v0[2] / f; + result[3] = v0[3] / f; + return result; +} + +mfloat_t *vec4_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFLOOR(v0[0] / v1[0]) * v1[0]; + result[1] = MFLOOR(v0[1] / v1[1]) * v1[1]; + result[2] = MFLOOR(v0[2] / v1[2]) * v1[2]; + result[3] = MFLOOR(v0[3] / v1[3]) * v1[3]; + return result; +} + +mfloat_t *vec4_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + result[0] = MFLOOR(v0[0] / f) * f; + result[1] = MFLOOR(v0[1] / f) * f; + result[2] = MFLOOR(v0[2] / f) * f; + result[3] = MFLOOR(v0[3] / f) * f; + return result; +} + +mfloat_t *vec4_negative(mfloat_t *result, mfloat_t *v0) +{ + result[0] = -v0[0]; + result[1] = -v0[1]; + result[2] = -v0[2]; + result[3] = -v0[3]; + return result; +} + +mfloat_t *vec4_abs(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFABS(v0[0]); + result[1] = MFABS(v0[1]); + result[2] = MFABS(v0[2]); + result[3] = MFABS(v0[3]); + return result; +} + +mfloat_t *vec4_floor(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MFLOOR(v0[0]); + result[1] = MFLOOR(v0[1]); + result[2] = MFLOOR(v0[2]); + result[3] = MFLOOR(v0[3]); + return result; +} + +mfloat_t *vec4_ceil(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MCEIL(v0[0]); + result[1] = MCEIL(v0[1]); + result[2] = MCEIL(v0[2]); + result[3] = MCEIL(v0[3]); + return result; +} + +mfloat_t *vec4_round(mfloat_t *result, mfloat_t *v0) +{ + result[0] = MROUND(v0[0]); + result[1] = MROUND(v0[1]); + result[2] = MROUND(v0[2]); + result[3] = MROUND(v0[3]); + return result; +} + +mfloat_t *vec4_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMAX(v0[0], v1[0]); + result[1] = MFMAX(v0[1], v1[1]); + result[2] = MFMAX(v0[2], v1[2]); + result[3] = MFMAX(v0[3], v1[3]); + return result; +} + +mfloat_t *vec4_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + result[0] = MFMIN(v0[0], v1[0]); + result[1] = MFMIN(v0[1], v1[1]); + result[2] = MFMIN(v0[2], v1[2]); + result[3] = MFMIN(v0[3], v1[3]); + return result; +} + +mfloat_t *vec4_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2) +{ + vec4_min(result, v0, v1); + vec4_max(result, v0, v2); + return result; +} + +mfloat_t *vec4_normalize(mfloat_t *result, mfloat_t *v0) +{ + mfloat_t l = MSQRT(v0[0] * v0[0] + v0[1] * v0[1] + v0[2] * v0[2] + v0[3] * v0[3]); + result[0] = v0[0] / l; + result[1] = v0[1] / l; + result[2] = v0[2] / l; + result[3] = v0[3] / l; + return result; +} + +mfloat_t *vec4_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f) +{ + result[0] = v0[0] + (v1[0] - v0[0]) * f; + result[1] = v0[1] + (v1[1] - v0[1]) * f; + result[2] = v0[2] + (v1[2] - v0[2]) * f; + result[3] = v0[3] + (v1[3] - v0[3]) * f; + return result; +} + +bool quat_is_zero(mfloat_t *q0) +{ + return MFABS(q0[0]) < MFLT_EPSILON && MFABS(q0[1]) < MFLT_EPSILON && MFABS(q0[2]) < MFLT_EPSILON && MFABS(q0[3]) < MFLT_EPSILON; +} + +bool quat_is_equal(mfloat_t *q0, mfloat_t *q1) +{ + return MFABS(q0[0] - q1[0]) < MFLT_EPSILON && MFABS(q0[1] - q1[1]) < MFLT_EPSILON && MFABS(q0[2] - q1[2]) < MFLT_EPSILON && MFABS(q0[3] - q1[3]) < MFLT_EPSILON; +} + +mfloat_t *quat(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) +{ + result[0] = x; + result[1] = y; + result[2] = z; + result[3] = w; + return result; +} + +mfloat_t *quat_assign(mfloat_t *result, mfloat_t *q0) +{ + result[0] = q0[0]; + result[1] = q0[1]; + result[2] = q0[2]; + result[3] = q0[3]; + return result; +} + +mfloat_t *quat_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *quat_null(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *quat_multiply(mfloat_t *result, mfloat_t *q0, mfloat_t *q1) +{ + result[0] = q0[3] * q1[0] + q0[0] * q1[3] + q0[1] * q1[2] - q0[2] * q1[1]; + result[1] = q0[3] * q1[1] + q0[1] * q1[3] + q0[2] * q1[0] - q0[0] * q1[2]; + result[2] = q0[3] * q1[2] + q0[2] * q1[3] + q0[0] * q1[1] - q0[1] * q1[0]; + result[3] = q0[3] * q1[3] - q0[0] * q1[0] - q0[1] * q1[1] - q0[2] * q1[2]; + return result; +} + +mfloat_t *quat_multiply_f(mfloat_t *result, mfloat_t *q0, mfloat_t f) +{ + result[0] = q0[0] * f; + result[1] = q0[1] * f; + result[2] = q0[2] * f; + result[3] = q0[3] * f; + return result; +} + +mfloat_t *quat_divide(mfloat_t *result, mfloat_t *q0, mfloat_t *q1) +{ + mfloat_t x = q0[0]; + mfloat_t y = q0[1]; + mfloat_t z = q0[2]; + mfloat_t w = q0[3]; + mfloat_t ls = q1[0] * q1[0] + q1[1] * q1[1] + q1[8] * q1[8] + q1[3] * q1[3]; + mfloat_t normalized_x = -q1[0] / ls; + mfloat_t normalized_y = -q1[1] / ls; + mfloat_t normalized_z = -q1[8] / ls; + mfloat_t normalized_w = q1[3] / ls; + result[0] = x * normalized_w + normalized_x * w + (y * normalized_z - z * normalized_y); + result[1] = y * normalized_w + normalized_y * w + (z * normalized_x - x * normalized_z); + result[2] = z * normalized_w + normalized_z * w + (x * normalized_y - y * normalized_x); + result[3] = w * normalized_w - (x * normalized_x + y * normalized_y + z * normalized_z); + return result; +} + +mfloat_t *quat_divide_f(mfloat_t *result, mfloat_t *q0, mfloat_t f) +{ + result[0] = q0[0] / f; + result[1] = q0[1] / f; + result[2] = q0[2] / f; + result[3] = q0[3] / f; + return result; +} + +mfloat_t *quat_negative(mfloat_t *result, mfloat_t *q0) +{ + result[0] = -q0[0]; + result[1] = -q0[1]; + result[2] = -q0[2]; + result[3] = -q0[3]; + return result; +} + +mfloat_t *quat_conjugate(mfloat_t *result, mfloat_t *q0) +{ + result[0] = -q0[0]; + result[1] = -q0[1]; + result[2] = -q0[2]; + result[3] = q0[3]; + return result; +} + +mfloat_t *quat_inverse(mfloat_t *result, mfloat_t *q0) +{ + mfloat_t l = MFLOAT_C(1.0) / (q0[0] * q0[0] + q0[1] * q0[1] + q0[2] * q0[2] + q0[3] * q0[3]); + result[0] = -q0[0] * l; + result[1] = -q0[1] * l; + result[2] = -q0[2] * l; + result[3] = q0[3] * l; + return result; +} + +mfloat_t *quat_normalize(mfloat_t *result, mfloat_t *q0) +{ + mfloat_t l = MFLOAT_C(1.0) / MSQRT(q0[0] * q0[0] + q0[1] * q0[1] + q0[2] * q0[2] + q0[3] * q0[3]); + result[0] = q0[0] * l; + result[1] = q0[1] * l; + result[2] = q0[2] * l; + result[3] = q0[3] * l; + return result; +} + +mfloat_t quat_dot(mfloat_t *q0, mfloat_t *q1) +{ + return q0[0] * q1[0] + q0[1] * q1[1] + q0[2] * q1[2] + q0[3] * q1[3]; +} + +mfloat_t *quat_power(mfloat_t *result, mfloat_t *q0, mfloat_t exponent) +{ + if (MFABS(q0[3]) < MFLOAT_C(1.0) - MFLT_EPSILON) { + mfloat_t alpha = MACOS(q0[3]); + mfloat_t new_alpha = alpha * exponent; + mfloat_t s = MSIN(new_alpha) / MSIN(alpha); + result[0] = result[0] * s; + result[1] = result[1] * s; + result[2] = result[2] * s; + result[3] = MCOS(new_alpha); + } else { + result[0] = q0[0]; + result[1] = q0[1]; + result[2] = q0[1]; + result[3] = q0[3]; + } + return result; +} + +mfloat_t *quat_from_axis_angle(mfloat_t *result, mfloat_t *v0, mfloat_t angle) +{ + mfloat_t half = angle * MFLOAT_C(0.5); + mfloat_t s = MSIN(half); + result[0] = v0[0] * s; + result[1] = v0[1] * s; + result[2] = v0[2] * s; + result[3] = MCOS(half); + return result; +} + +mfloat_t *quat_from_vec3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1) +{ + mfloat_t cross[VEC3_SIZE]; + mfloat_t d = vec3_dot(v0, v1); + mfloat_t a_ls = vec3_length_squared(v0); + mfloat_t b_ls = vec3_length_squared(v0); + vec3_cross(cross, v0, v1); + quat(result, cross[0], cross[1], cross[1], d + MSQRT(a_ls * b_ls)); + quat_normalize(result, result); + return result; +} + +mfloat_t *quat_from_mat4(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t scale = m0[0] + m0[5] + m0[10]; + if (scale > MFLOAT_C(0.0)) { + mfloat_t sr = MSQRT(scale + MFLOAT_C(1.0)); + result[3] = sr * MFLOAT_C(0.5); + sr = MFLOAT_C(0.5) / sr; + result[0] = (m0[9] - m0[6]) * sr; + result[1] = (m0[2] - m0[8]) * sr; + result[2] = (m0[4] - m0[1]) * sr; + } else if ((m0[0] >= m0[5]) && (m0[0] >= m0[10])) { + mfloat_t sr = MSQRT(MFLOAT_C(1.0) + m0[0] - m0[5] - m0[10]); + mfloat_t half = MFLOAT_C(0.5) / sr; + result[0] = MFLOAT_C(0.5) * sr; + result[1] = (m0[4] + m0[1]) * half; + result[2] = (m0[8] + m0[2]) * half; + result[3] = (m0[9] - m0[6]) * half; + } else if (m0[5] > m0[10]) { + mfloat_t sr = MSQRT(MFLOAT_C(1.0) + m0[5] - m0[0] - m0[10]); + mfloat_t half = MFLOAT_C(0.5) / sr; + result[0] = (m0[1] + m0[4]) * half; + result[1] = MFLOAT_C(0.5) * sr; + result[2] = (m0[6] + m0[9]) * half; + result[3] = (m0[2] - m0[8]) * half; + } else { + mfloat_t sr = MSQRT(MFLOAT_C(1.0) + m0[10] - m0[0] - m0[5]); + mfloat_t half = MFLOAT_C(0.5) / sr; + result[0] = (m0[2] + m0[8]) * half; + result[1] = (m0[6] + m0[9]) * half; + result[2] = MFLOAT_C(0.5) * sr; + result[3] = (m0[4] - m0[1]) * half; + } + return result; +} + +mfloat_t *quat_lerp(mfloat_t *result, mfloat_t *q0, mfloat_t *q1, mfloat_t f) +{ + result[0] = q0[0] + (q1[0] - q0[0]) * f; + result[1] = q0[1] + (q1[1] - q0[1]) * f; + result[2] = q0[2] + (q1[2] - q0[2]) * f; + result[3] = q0[3] + (q1[3] - q0[3]) * f; + return result; +} + +mfloat_t *quat_slerp(mfloat_t *result, mfloat_t *q0, mfloat_t *q1, mfloat_t f) +{ + mfloat_t tmp1[QUAT_SIZE]; + mfloat_t d = quat_dot(q0, q1); + mfloat_t f0; + mfloat_t f1; + quat_assign(tmp1, q1); + if (d < MFLOAT_C(0.0)) { + quat_negative(tmp1, tmp1); + d = -d; + } + if (d > MFLOAT_C(0.9995)) { + f0 = MFLOAT_C(1.0) - f; + f1 = f; + } else { + mfloat_t theta = MACOS(d); + mfloat_t sin_theta = MSIN(theta); + f0 = MSIN((MFLOAT_C(1.0) - f) * theta) / sin_theta; + f1 = MSIN(f * theta) / sin_theta; + } + result[0] = q0[0] * f0 + tmp1[0] * f1; + result[1] = q0[1] * f0 + tmp1[1] * f1; + result[2] = q0[2] * f0 + tmp1[2] * f1; + result[3] = q0[3] * f0 + tmp1[3] * f1; + return result; +} + +mfloat_t quat_length(mfloat_t *q0) +{ + return MSQRT(q0[0] * q0[0] + q0[1] * q0[1] + q0[2] * q0[2] + q0[3] * q0[3]); +} + +mfloat_t quat_length_squared(mfloat_t *q0) +{ + return q0[0] * q0[0] + q0[1] * q0[1] + q0[2] * q0[2] + q0[3] * q0[3]; +} + +mfloat_t quat_angle(mfloat_t *q0, mfloat_t *q1) +{ + mfloat_t s = MSQRT(quat_length_squared(q0) * quat_length_squared(q1)); + s = MFLOAT_C(1.0) / s; + return MACOS(quat_dot(q0, q1) * s); +} + +mfloat_t *mat2(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22) +{ + result[0] = m11; + result[1] = m21; + result[2] = m12; + result[3] = m22; + return result; +} + +mfloat_t *mat2_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *mat2_identity(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(1.0); + return result; +} + +mfloat_t mat2_determinant(mfloat_t *m0) +{ + return m0[0] * m0[3] - m0[2] * m0[1]; +} + +mfloat_t *mat2_assign(mfloat_t *result, mfloat_t *m0) +{ + result[0] = m0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + return result; +} + +mfloat_t *mat2_negative(mfloat_t *result, mfloat_t *m0) +{ + result[0] = -m0[0]; + result[1] = -m0[1]; + result[2] = -m0[2]; + result[3] = -m0[3]; + return result; +} + +mfloat_t *mat2_transpose(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t transposed[MAT2_SIZE]; + transposed[0] = m0[0]; + transposed[1] = m0[2]; + transposed[2] = m0[1]; + transposed[3] = m0[3]; + result[0] = transposed[0]; + result[1] = transposed[1]; + result[2] = transposed[2]; + result[3] = transposed[3]; + return result; +} + +mfloat_t *mat2_cofactor(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t cofactor[MAT2_SIZE]; + cofactor[0] = m0[3]; + cofactor[1] = -m0[2]; + cofactor[2] = -m0[1]; + cofactor[3] = m0[0]; + result[0] = cofactor[0]; + result[1] = cofactor[1]; + result[2] = cofactor[2]; + result[3] = cofactor[3]; + return result; +} + +mfloat_t *mat2_adjugate(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t adjugate[MAT2_SIZE]; + adjugate[0] = m0[3]; + adjugate[1] = -m0[1]; + adjugate[2] = -m0[2]; + adjugate[3] = m0[0]; + result[0] = adjugate[0]; + result[1] = adjugate[1]; + result[2] = adjugate[2]; + result[3] = adjugate[3]; + return result; +} + +mfloat_t *mat2_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1) +{ + mfloat_t multiplied[MAT3_SIZE]; + multiplied[0] = m0[0] * m1[0] + m0[2] * m1[1]; + multiplied[1] = m0[1] * m1[0] + m0[3] * m1[1]; + multiplied[2] = m0[0] * m1[2] + m0[2] * m1[3]; + multiplied[3] = m0[1] * m1[2] + m0[3] * m1[3]; + result[0] = multiplied[0]; + result[1] = multiplied[1]; + result[2] = multiplied[2]; + result[3] = multiplied[3]; + return result; +} + +mfloat_t *mat2_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f) +{ + result[0] = m0[0] * f; + result[1] = m0[1] * f; + result[2] = m0[2] * f; + result[3] = m0[3] * f; + return result; +} + +mfloat_t *mat2_inverse(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t inverse[MAT2_SIZE]; + mfloat_t det = mat2_determinant(m0); + mat2_cofactor(inverse, m0); + mat2_multiply_f(inverse, inverse, MFLOAT_C(1.0) / det); + result[0] = inverse[0]; + result[1] = inverse[1]; + result[2] = inverse[2]; + result[3] = inverse[3]; + return result; +} + +mfloat_t *mat2_scaling(mfloat_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[3] = v0[1]; + return result; +} + +mfloat_t *mat2_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = m0[0] * v0[0]; + result[3] = m0[3] * v0[1]; + return result; +} + +mfloat_t *mat2_rotation_z(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[0] = c; + result[1] = s; + result[2] = -s; + result[3] = c; + return result; +} + +mfloat_t *mat2_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f) +{ + result[0] = m0[0] + (m1[0] - m0[0]) * f; + result[1] = m0[1] + (m1[1] - m0[1]) * f; + result[2] = m0[2] + (m1[2] - m0[2]) * f; + result[3] = m0[3] + (m1[3] - m0[3]) * f; + return result; +} + +mfloat_t *mat3(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33) +{ + result[0] = m11; + result[1] = m21; + result[2] = m31; + result[3] = m12; + result[4] = m22; + result[5] = m32; + result[6] = m13; + result[7] = m23; + result[8] = m33; + return result; +} + +mfloat_t *mat3_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(0.0); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *mat3_identity(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(1.0); + result[5] = MFLOAT_C(0.0); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(1.0); + return result; +} + +mfloat_t mat3_determinant(mfloat_t *m0) +{ + mfloat_t m11 = m0[0]; + mfloat_t m21 = m0[1]; + mfloat_t m31 = m0[2]; + mfloat_t m12 = m0[3]; + mfloat_t m22 = m0[4]; + mfloat_t m32 = m0[5]; + mfloat_t m13 = m0[6]; + mfloat_t m23 = m0[7]; + mfloat_t m33 = m0[8]; + mfloat_t determinant = m11 * m22 * m33 + + m12 * m23 * m31 + + m13 * m21 * m32 + - m11 * m23 * m32 + - m12 * m21 * m33 + - m13 * m22 * m31; + return determinant; +} + +mfloat_t *mat3_assign(mfloat_t *result, mfloat_t *m0) +{ + result[0] = m0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = m0[5]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + return result; +} + +mfloat_t *mat3_negative(mfloat_t *result, mfloat_t *m0) +{ + result[0] = -m0[0]; + result[1] = -m0[1]; + result[2] = -m0[2]; + result[3] = -m0[3]; + result[4] = -m0[4]; + result[5] = -m0[5]; + result[6] = -m0[6]; + result[7] = -m0[7]; + result[8] = -m0[8]; + return result; +} + +mfloat_t *mat3_transpose(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t transposed[MAT4_SIZE]; + transposed[0] = m0[0]; + transposed[1] = m0[3]; + transposed[2] = m0[6]; + transposed[3] = m0[1]; + transposed[4] = m0[4]; + transposed[5] = m0[7]; + transposed[6] = m0[2]; + transposed[7] = m0[5]; + transposed[8] = m0[8]; + result[0] = transposed[0]; + result[1] = transposed[1]; + result[2] = transposed[2]; + result[3] = transposed[3]; + result[4] = transposed[4]; + result[5] = transposed[5]; + result[6] = transposed[6]; + result[7] = transposed[7]; + result[8] = transposed[8]; + return result; +} + +mfloat_t *mat3_cofactor(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t cofactor[MAT3_SIZE]; + mfloat_t minor[MAT2_SIZE]; + minor[0] = m0[4]; + minor[1] = m0[5]; + minor[2] = m0[7]; + minor[3] = m0[8]; + cofactor[0] = mat2_determinant(minor); + minor[0] = m0[3]; + minor[1] = m0[5]; + minor[2] = m0[6]; + minor[3] = m0[8]; + cofactor[1] = -mat2_determinant(minor); + minor[0] = m0[3]; + minor[1] = m0[4]; + minor[2] = m0[6]; + minor[3] = m0[7]; + cofactor[2] = mat2_determinant(minor); + minor[0] = m0[1]; + minor[1] = m0[2]; + minor[2] = m0[7]; + minor[3] = m0[8]; + cofactor[3] = -mat2_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[2]; + minor[2] = m0[6]; + minor[3] = m0[8]; + cofactor[4] = mat2_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[6]; + minor[3] = m0[7]; + cofactor[5] = -mat2_determinant(minor); + minor[0] = m0[1]; + minor[1] = m0[2]; + minor[2] = m0[4]; + minor[3] = m0[5]; + cofactor[6] = mat2_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[5]; + cofactor[7] = -mat2_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[3]; + minor[3] = m0[4]; + cofactor[8] = mat2_determinant(minor); + result[0] = cofactor[0]; + result[1] = cofactor[1]; + result[2] = cofactor[2]; + result[3] = cofactor[3]; + result[4] = cofactor[4]; + result[5] = cofactor[5]; + result[6] = cofactor[6]; + result[7] = cofactor[7]; + result[8] = cofactor[8]; + return result; +} + +mfloat_t *mat3_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1) +{ + mfloat_t multiplied[MAT3_SIZE]; + multiplied[0] = m0[0] * m1[0] + m0[3] * m1[1] + m0[6] * m1[2]; + multiplied[1] = m0[1] * m1[0] + m0[4] * m1[1] + m0[7] * m1[2]; + multiplied[2] = m0[2] * m1[0] + m0[5] * m1[1] + m0[8] * m1[2]; + multiplied[3] = m0[0] * m1[3] + m0[3] * m1[4] + m0[6] * m1[5]; + multiplied[4] = m0[1] * m1[3] + m0[4] * m1[4] + m0[7] * m1[5]; + multiplied[5] = m0[2] * m1[3] + m0[5] * m1[4] + m0[8] * m1[5]; + multiplied[6] = m0[0] * m1[6] + m0[3] * m1[7] + m0[6] * m1[8]; + multiplied[7] = m0[1] * m1[6] + m0[4] * m1[7] + m0[7] * m1[8]; + multiplied[8] = m0[2] * m1[6] + m0[5] * m1[7] + m0[8] * m1[8]; + result[0] = multiplied[0]; + result[1] = multiplied[1]; + result[2] = multiplied[2]; + result[3] = multiplied[3]; + result[4] = multiplied[4]; + result[5] = multiplied[5]; + result[6] = multiplied[6]; + result[7] = multiplied[7]; + result[8] = multiplied[8]; + return result; +} + +mfloat_t *mat3_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f) +{ + result[0] = m0[0] * f; + result[1] = m0[1] * f; + result[2] = m0[2] * f; + result[3] = m0[3] * f; + result[4] = m0[4] * f; + result[5] = m0[5] * f; + result[6] = m0[6] * f; + result[7] = m0[7] * f; + result[8] = m0[8] * f; + return result; +} + +mfloat_t *mat3_inverse(mfloat_t *result, mfloat_t *m0) +{ + result = m0; + return result; +} + +mfloat_t *mat3_scaling(mfloat_t *result, mfloat_t *v0) +{ + result[0] = v0[0]; + result[4] = v0[1]; + result[8] = v0[2]; + return result; +} + +mfloat_t *mat3_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = m0[0] * v0[0]; + result[4] = m0[4] * v0[1]; + result[8] = m0[8] * v0[2]; + return result; +} + +mfloat_t *mat3_rotation_x(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[4] = c; + result[5] = s; + result[7] = -s; + result[8] = c; + return result; +} + +mfloat_t *mat3_rotation_y(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[0] = c; + result[2] = -s; + result[6] = s; + result[8] = c; + return result; +} + +mfloat_t *mat3_rotation_z(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[0] = c; + result[1] = s; + result[3] = -s; + result[4] = c; + return result; +} + +mfloat_t *mat3_rotation_axis(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + mfloat_t one_c = MFLOAT_C(1.0) - c; + mfloat_t x = v0[0]; + mfloat_t y = v0[4]; + mfloat_t z = v0[8]; + mfloat_t xx = x * x; + mfloat_t xy = x * y; + mfloat_t xz = x * z; + mfloat_t yy = y * y; + mfloat_t yz = y * z; + mfloat_t zz = z * z; + mfloat_t l = xx + yy + zz; + mfloat_t sqrt_l = MSQRT(l); + result[0] = (xx + (yy + zz) * c) / l; + result[1] = (xy * one_c + v0[2] * sqrt_l * s) / l; + result[2] = (xz * one_c - v0[1] * sqrt_l * s) / l; + result[3] = (xy * one_c - v0[2] * sqrt_l * s) / l; + result[4] = (yy + (xx + zz) * c) / l; + result[5] = (yz * one_c + v0[0] * sqrt_l * s) / l; + result[6] = (xz * one_c + v0[1] * sqrt_l * s) / l; + result[7] = (yz * one_c - v0[0] * sqrt_l * s) / l; + result[8] = (zz + (xx + yy) * c) / l; + return result; +} + +mfloat_t *mat3_rotation_quat(mfloat_t *result, mfloat_t *q0) +{ + mfloat_t xx = q0[0] * q0[0]; + mfloat_t yy = q0[1] * q0[1]; + mfloat_t zz = q0[2] * q0[2]; + mfloat_t xy = q0[0] * q0[1]; + mfloat_t zw = q0[2] * q0[3]; + mfloat_t xz = q0[8] * q0[0]; + mfloat_t yw = q0[1] * q0[3]; + mfloat_t yz = q0[1] * q0[2]; + mfloat_t xw = q0[0] * q0[3]; + result[0] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (yy - zz); + result[1] = MFLOAT_C(2.0) * (xy + zw); + result[2] = MFLOAT_C(2.0) * (xz - yw); + result[3] = MFLOAT_C(2.0) * (xy - zw); + result[4] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (xx - zz); + result[5] = MFLOAT_C(2.0) * (yz + xw); + result[6] = MFLOAT_C(2.0) * (xz + yw); + result[7] = MFLOAT_C(2.0) * (yz - xw); + result[8] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (xx - yy); + return result; +} + +mfloat_t *mat3_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f) +{ + result[0] = m0[0] + (m1[0] - m0[0]) * f; + result[1] = m0[1] + (m1[1] - m0[1]) * f; + result[2] = m0[2] + (m1[2] - m0[2]) * f; + result[3] = m0[3] + (m1[3] - m0[3]) * f; + result[4] = m0[4] + (m1[4] - m0[4]) * f; + result[5] = m0[5] + (m1[5] - m0[5]) * f; + result[6] = m0[6] + (m1[6] - m0[6]) * f; + result[7] = m0[7] + (m1[7] - m0[7]) * f; + result[8] = m0[8] + (m1[8] - m0[8]) * f; + return result; +} + +mfloat_t *mat4(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44) +{ + result[0] = m11; + result[1] = m21; + result[2] = m31; + result[3] = m41; + result[4] = m12; + result[5] = m22; + result[6] = m32; + result[7] = m42; + result[8] = m13; + result[9] = m23; + result[10] = m33; + result[11] = m43; + result[12] = m14; + result[13] = m24; + result[14] = m34; + result[15] = m44; + return result; +} + +mfloat_t *mat4_zero(mfloat_t *result) +{ + result[0] = MFLOAT_C(0.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(0.0); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = MFLOAT_C(0.0); + result[11] = MFLOAT_C(0.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = MFLOAT_C(0.0); + result[15] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *mat4_identity(mfloat_t *result) +{ + result[0] = MFLOAT_C(1.0); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(1.0); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = MFLOAT_C(1.0); + result[11] = MFLOAT_C(0.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = MFLOAT_C(0.0); + result[15] = MFLOAT_C(1.0); + return result; +} + +mfloat_t mat4_determinant(mfloat_t *m0) +{ + mfloat_t m11 = m0[0]; + mfloat_t m21 = m0[1]; + mfloat_t m31 = m0[2]; + mfloat_t m41 = m0[3]; + mfloat_t m12 = m0[4]; + mfloat_t m22 = m0[5]; + mfloat_t m32 = m0[6]; + mfloat_t m42 = m0[7]; + mfloat_t m13 = m0[8]; + mfloat_t m23 = m0[9]; + mfloat_t m33 = m0[10]; + mfloat_t m43 = m0[11]; + mfloat_t m14 = m0[12]; + mfloat_t m24 = m0[13]; + mfloat_t m34 = m0[14]; + mfloat_t m44 = m0[15]; + mfloat_t determinant = m14 * m23 * m32 * m41 - m13 * m24 * m32 * m41 + - m14 * m22 * m33 * m41 + m12 * m24 * m33 * m41 + + m13 * m22 * m34 * m41 - m12 * m23 * m34 * m41 + - m14 * m23 * m31 * m42 + m13 * m24 * m31 * m42 + + m14 * m21 * m33 * m42 - m11 * m24 * m33 * m42 + - m13 * m21 * m34 * m42 + m11 * m23 * m34 * m42 + + m14 * m22 * m31 * m43 - m12 * m24 * m31 * m43 + - m14 * m21 * m32 * m43 + m11 * m24 * m32 * m43 + + m12 * m21 * m34 * m43 - m11 * m22 * m34 * m43 + - m13 * m22 * m31 * m44 + m12 * m23 * m31 * m44 + + m13 * m21 * m32 * m44 - m11 * m23 * m32 * m44 + - m12 * m21 * m33 * m44 + m11 * m22 * m33 * m44; + return determinant; +} + +mfloat_t *mat4_assign(mfloat_t *result, mfloat_t *m0) +{ + result[0] = m0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = m0[5]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + result[9] = m0[9]; + result[10] = m0[10]; + result[11] = m0[11]; + result[12] = m0[12]; + result[13] = m0[13]; + result[14] = m0[14]; + result[15] = m0[15]; + return result; +} + +mfloat_t *mat4_negative(mfloat_t *result, mfloat_t *m0) +{ + result[0] = -m0[0]; + result[1] = -m0[1]; + result[2] = -m0[2]; + result[3] = -m0[3]; + result[4] = -m0[4]; + result[5] = -m0[5]; + result[6] = -m0[6]; + result[7] = -m0[7]; + result[8] = -m0[8]; + result[9] = -m0[9]; + result[10] = -m0[10]; + result[11] = -m0[11]; + result[12] = -m0[12]; + result[13] = -m0[13]; + result[14] = -m0[14]; + result[15] = -m0[15]; + return result; +} + +mfloat_t *mat4_transpose(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t transposed[MAT4_SIZE]; + transposed[0] = m0[0]; + transposed[1] = m0[4]; + transposed[2] = m0[8]; + transposed[3] = m0[12]; + transposed[4] = m0[1]; + transposed[5] = m0[5]; + transposed[6] = m0[9]; + transposed[7] = m0[13]; + transposed[8] = m0[2]; + transposed[9] = m0[6]; + transposed[10] = m0[10]; + transposed[11] = m0[14]; + transposed[12] = m0[3]; + transposed[13] = m0[7]; + transposed[14] = m0[11]; + transposed[15] = m0[15]; + result[0] = transposed[0]; + result[1] = transposed[1]; + result[2] = transposed[2]; + result[3] = transposed[3]; + result[4] = transposed[4]; + result[5] = transposed[5]; + result[6] = transposed[6]; + result[7] = transposed[7]; + result[8] = transposed[8]; + result[9] = transposed[9]; + result[10] = transposed[10]; + result[11] = transposed[11]; + result[12] = transposed[12]; + result[13] = transposed[13]; + result[14] = transposed[14]; + result[15] = transposed[15]; + return result; +} + +mfloat_t *mat4_cofactor(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t cofactor[MAT4_SIZE]; + mfloat_t minor[MAT3_SIZE]; + minor[0] = m0[5]; + minor[1] = m0[6]; + minor[2] = m0[7]; + minor[3] = m0[9]; + minor[4] = m0[10]; + minor[5] = m0[11]; + minor[6] = m0[13]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[0] = mat3_determinant(minor); + minor[0] = m0[4]; + minor[1] = m0[6]; + minor[2] = m0[7]; + minor[3] = m0[8]; + minor[4] = m0[10]; + minor[5] = m0[11]; + minor[6] = m0[12]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[1] = -mat3_determinant(minor); + minor[0] = m0[4]; + minor[1] = m0[5]; + minor[2] = m0[7]; + minor[3] = m0[8]; + minor[4] = m0[9]; + minor[5] = m0[11]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[15]; + cofactor[2] = mat3_determinant(minor); + minor[0] = m0[4]; + minor[1] = m0[5]; + minor[2] = m0[6]; + minor[3] = m0[8]; + minor[4] = m0[9]; + minor[5] = m0[10]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[14]; + cofactor[3] = -mat3_determinant(minor); + minor[0] = m0[1]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[9]; + minor[4] = m0[10]; + minor[5] = m0[11]; + minor[6] = m0[13]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[4] = -mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[8]; + minor[4] = m0[10]; + minor[5] = m0[11]; + minor[6] = m0[12]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[5] = mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[3]; + minor[3] = m0[8]; + minor[4] = m0[9]; + minor[5] = m0[11]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[15]; + cofactor[6] = -mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[2]; + minor[3] = m0[8]; + minor[4] = m0[9]; + minor[5] = m0[10]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[14]; + cofactor[7] = mat3_determinant(minor); + minor[0] = m0[1]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[5]; + minor[4] = m0[6]; + minor[5] = m0[7]; + minor[6] = m0[13]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[8] = mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[4]; + minor[4] = m0[6]; + minor[5] = m0[7]; + minor[6] = m0[12]; + minor[7] = m0[14]; + minor[8] = m0[15]; + cofactor[9] = -mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[3]; + minor[3] = m0[4]; + minor[4] = m0[5]; + minor[5] = m0[7]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[15]; + cofactor[10] = mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[2]; + minor[3] = m0[4]; + minor[4] = m0[5]; + minor[5] = m0[6]; + minor[6] = m0[12]; + minor[7] = m0[13]; + minor[8] = m0[14]; + cofactor[11] = -mat3_determinant(minor); + minor[0] = m0[1]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[5]; + minor[4] = m0[6]; + minor[5] = m0[7]; + minor[6] = m0[9]; + minor[7] = m0[10]; + minor[8] = m0[11]; + cofactor[12] = -mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[2]; + minor[2] = m0[3]; + minor[3] = m0[4]; + minor[4] = m0[6]; + minor[5] = m0[7]; + minor[6] = m0[8]; + minor[7] = m0[10]; + minor[8] = m0[11]; + cofactor[13] = mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[3]; + minor[3] = m0[4]; + minor[4] = m0[5]; + minor[5] = m0[7]; + minor[6] = m0[8]; + minor[7] = m0[9]; + minor[8] = m0[11]; + cofactor[14] = -mat3_determinant(minor); + minor[0] = m0[0]; + minor[1] = m0[1]; + minor[2] = m0[2]; + minor[3] = m0[4]; + minor[4] = m0[5]; + minor[5] = m0[6]; + minor[6] = m0[8]; + minor[7] = m0[9]; + minor[8] = m0[10]; + cofactor[15] = mat3_determinant(minor); + result[0] = cofactor[0]; + result[1] = cofactor[1]; + result[2] = cofactor[2]; + result[3] = cofactor[3]; + result[4] = cofactor[4]; + result[5] = cofactor[5]; + result[6] = cofactor[6]; + result[7] = cofactor[7]; + result[8] = cofactor[8]; + result[9] = cofactor[9]; + result[10] = cofactor[10]; + result[11] = cofactor[11]; + result[12] = cofactor[12]; + result[13] = cofactor[13]; + result[14] = cofactor[14]; + result[15] = cofactor[15]; + return result; +} + +mfloat_t *mat4_rotation_x(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[5] = c; + result[6] = s; + result[9] = -s; + result[10] = c; + return result; +} + +mfloat_t *mat4_rotation_y(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[0] = c; + result[2] = -s; + result[8] = s; + result[10] = c; + return result; +} + +mfloat_t *mat4_rotation_z(mfloat_t *result, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + result[0] = c; + result[1] = s; + result[4] = -s; + result[5] = c; + return result; +} + +mfloat_t *mat4_rotation_axis(mfloat_t *result, mfloat_t *v0, mfloat_t f) +{ + mfloat_t c = MCOS(f); + mfloat_t s = MSIN(f); + mfloat_t one_c = MFLOAT_C(1.0) - c; + mfloat_t x = v0[0]; + mfloat_t y = v0[1]; + mfloat_t z = v0[2]; + mfloat_t xx = x * x; + mfloat_t xy = x * y; + mfloat_t xz = x * z; + mfloat_t yy = y * y; + mfloat_t yz = y * z; + mfloat_t zz = z * z; + mfloat_t l = xx + yy + zz; + mfloat_t sqrt_l = MSQRT(l); + result[0] = (xx + (yy + zz) * c) / l; + result[1] = (xy * one_c + v0[2] * sqrt_l * s) / l; + result[2] = (xz * one_c - v0[1] * sqrt_l * s) / l; + result[3] = MFLOAT_C(0.0); + result[4] = (xy * one_c - v0[2] * sqrt_l * s) / l; + result[5] = (yy + (xx + zz) * c) / l; + result[6] = (yz * one_c + v0[0] * sqrt_l * s) / l; + result[7] = MFLOAT_C(0.0); + result[8] = (xz * one_c + v0[1] * sqrt_l * s) / l; + result[9] = (yz * one_c - v0[0] * sqrt_l * s) / l; + result[10] = (zz + (xx + yy) * c) / l; + result[11] = MFLOAT_C(0.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = MFLOAT_C(0.0); + result[15] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *mat4_rotation_quat(mfloat_t *result, mfloat_t *q0) +{ + mfloat_t xx = q0[0] * q0[0]; + mfloat_t yy = q0[1] * q0[1]; + mfloat_t zz = q0[2] * q0[2]; + mfloat_t xy = q0[0] * q0[1]; + mfloat_t zw = q0[2] * q0[3]; + mfloat_t xz = q0[0] * q0[2]; + mfloat_t yw = q0[1] * q0[3]; + mfloat_t yz = q0[1] * q0[2]; + mfloat_t xw = q0[0] * q0[3]; + result[0] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (yy + zz); + result[1] = MFLOAT_C(2.0) * (xy + zw); + result[2] = MFLOAT_C(2.0) * (xz - yw); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(2.0) * (xy - zw); + result[5] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (xx + zz); + result[6] = MFLOAT_C(2.0) * (yz + xw); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(2.0) * (xz + yw); + result[9] = MFLOAT_C(2.0) * (yz - xw); + result[10] = MFLOAT_C(1.0) - MFLOAT_C(2.0) * (xx + yy); + result[11] = MFLOAT_C(0.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = MFLOAT_C(0.0); + result[15] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *mat4_translation(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = m0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = m0[5]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + result[9] = m0[9]; + result[10] = m0[10]; + result[11] = m0[11]; + result[12] = v0[0]; + result[13] = v0[1]; + result[14] = v0[2]; + result[15] = m0[15]; + return result; +} + +mfloat_t *mat4_translate(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = m0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = m0[5]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + result[9] = m0[9]; + result[10] = m0[10]; + result[11] = m0[11]; + result[12] = m0[12] + v0[0]; + result[13] = m0[13] + v0[1]; + result[14] = m0[14] + v0[2]; + result[15] = m0[15]; + return result; +} + +mfloat_t *mat4_scaling(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = v0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = v0[1]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + result[9] = m0[9]; + result[10] = v0[2]; + result[11] = m0[11]; + result[12] = m0[12]; + result[13] = m0[13]; + result[14] = m0[14]; + result[15] = m0[15]; + return result; +} + +mfloat_t *mat4_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0) +{ + result[0] = m0[0] * v0[0]; + result[1] = m0[1]; + result[2] = m0[2]; + result[3] = m0[3]; + result[4] = m0[4]; + result[5] = m0[5] * v0[1]; + result[6] = m0[6]; + result[7] = m0[7]; + result[8] = m0[8]; + result[9] = m0[9]; + result[10] = m0[10] * v0[2]; + result[11] = m0[11]; + result[12] = m0[12]; + result[13] = m0[13]; + result[14] = m0[14]; + result[15] = m0[15]; + return result; +} + +mfloat_t *mat4_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1) +{ + mfloat_t multiplied[MAT4_SIZE]; + multiplied[0] = m0[0] * m1[0] + m0[4] * m1[1] + m0[8] * m1[2] + m0[12] * m1[3]; + multiplied[1] = m0[1] * m1[0] + m0[5] * m1[1] + m0[9] * m1[2] + m0[13] * m1[3]; + multiplied[2] = m0[2] * m1[0] + m0[6] * m1[1] + m0[10] * m1[2] + m0[14] * m1[3]; + multiplied[3] = m0[3] * m1[0] + m0[7] * m1[1] + m0[11] * m1[2] + m0[15] * m1[3]; + multiplied[4] = m0[0] * m1[4] + m0[4] * m1[5] + m0[8] * m1[6] + m0[12] * m1[7]; + multiplied[5] = m0[1] * m1[4] + m0[5] * m1[5] + m0[9] * m1[6] + m0[13] * m1[7]; + multiplied[6] = m0[2] * m1[4] + m0[6] * m1[5] + m0[10] * m1[6] + m0[14] * m1[7]; + multiplied[7] = m0[3] * m1[4] + m0[7] * m1[5] + m0[11] * m1[6] + m0[15] * m1[7]; + multiplied[8] = m0[0] * m1[8] + m0[4] * m1[9] + m0[8] * m1[10] + m0[12] * m1[11]; + multiplied[9] = m0[1] * m1[8] + m0[5] * m1[9] + m0[9] * m1[10] + m0[13] * m1[11]; + multiplied[10] = m0[2] * m1[8] + m0[6] * m1[9] + m0[10] * m1[10] + m0[14] * m1[11]; + multiplied[11] = m0[3] * m1[8] + m0[7] * m1[9] + m0[11] * m1[10] + m0[15] * m1[11]; + multiplied[12] = m0[0] * m1[12] + m0[4] * m1[13] + m0[8] * m1[14] + m0[12] * m1[15]; + multiplied[13] = m0[1] * m1[12] + m0[5] * m1[13] + m0[9] * m1[14] + m0[13] * m1[15]; + multiplied[14] = m0[2] * m1[12] + m0[6] * m1[13] + m0[10] * m1[14] + m0[14] * m1[15]; + multiplied[15] = m0[3] * m1[12] + m0[7] * m1[13] + m0[11] * m1[14] + m0[15] * m1[15]; + result[0] = multiplied[0]; + result[1] = multiplied[1]; + result[2] = multiplied[2]; + result[3] = multiplied[3]; + result[4] = multiplied[4]; + result[5] = multiplied[5]; + result[6] = multiplied[6]; + result[7] = multiplied[7]; + result[8] = multiplied[8]; + result[9] = multiplied[9]; + result[10] = multiplied[10]; + result[11] = multiplied[11]; + result[12] = multiplied[12]; + result[13] = multiplied[13]; + result[14] = multiplied[14]; + result[15] = multiplied[15]; + return result; +} + +mfloat_t *mat4_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f) +{ + result[0] = m0[0] * f; + result[1] = m0[1] * f; + result[2] = m0[2] * f; + result[3] = m0[3] * f; + result[4] = m0[4] * f; + result[5] = m0[5] * f; + result[6] = m0[6] * f; + result[7] = m0[7] * f; + result[8] = m0[8] * f; + result[9] = m0[9] * f; + result[10] = m0[10] * f; + result[11] = m0[11] * f; + result[12] = m0[12] * f; + result[13] = m0[13] * f; + result[14] = m0[14] * f; + result[15] = m0[15] * f; + return result; +} + +mfloat_t *mat4_inverse(mfloat_t *result, mfloat_t *m0) +{ + mfloat_t inverse[MAT4_SIZE]; + mfloat_t inverted_determinant; + mfloat_t m11 = m0[0]; + mfloat_t m21 = m0[1]; + mfloat_t m31 = m0[2]; + mfloat_t m41 = m0[3]; + mfloat_t m12 = m0[4]; + mfloat_t m22 = m0[5]; + mfloat_t m32 = m0[6]; + mfloat_t m42 = m0[7]; + mfloat_t m13 = m0[8]; + mfloat_t m23 = m0[9]; + mfloat_t m33 = m0[10]; + mfloat_t m43 = m0[11]; + mfloat_t m14 = m0[12]; + mfloat_t m24 = m0[13]; + mfloat_t m34 = m0[14]; + mfloat_t m44 = m0[15]; + inverse[0] = m22 * m33 * m44 + - m22 * m43 * m34 + - m23 * m32 * m44 + + m23 * m42 * m34 + + m24 * m32 * m43 + - m24 * m42 * m33; + inverse[4] = -m12 * m33 * m44 + + m12 * m43 * m34 + + m13 * m32 * m44 + - m13 * m42 * m34 + - m14 * m32 * m43 + + m14 * m42 * m33; + inverse[8] = m12 * m23 * m44 + - m12 * m43 * m24 + - m13 * m22 * m44 + + m13 * m42 * m24 + + m14 * m22 * m43 + - m14 * m42 * m23; + inverse[12] = -m12 * m23 * m34 + + m12 * m33 * m24 + + m13 * m22 * m34 + - m13 * m32 * m24 + - m14 * m22 * m33 + + m14 * m32 * m23; + inverse[1] = -m21 * m33 * m44 + + m21 * m43 * m34 + + m23 * m31 * m44 + - m23 * m41 * m34 + - m24 * m31 * m43 + + m24 * m41 * m33; + inverse[5] =m11 * m33 * m44 + -m11 * m43 * m34 + - m13 * m31 * m44 + + m13 * m41 * m34 + + m14 * m31 * m43 + - m14 * m41 * m33; + inverse[9] = -m11 * m23 * m44 + +m11 * m43 * m24 + + m13 * m21 * m44 + - m13 * m41 * m24 + - m14 * m21 * m43 + + m14 * m41 * m23; + inverse[13] =m11 * m23 * m34 + -m11 * m33 * m24 + - m13 * m21 * m34 + + m13 * m31 * m24 + + m14 * m21 * m33 + - m14 * m31 * m23; + inverse[2] = m21 * m32 * m44 + - m21 * m42 * m34 + - m22 * m31 * m44 + + m22 * m41 * m34 + + m24 * m31 * m42 + - m24 * m41 * m32; + inverse[6] = -m11 * m32 * m44 + +m11 * m42 * m34 + + m12 * m31 * m44 + - m12 * m41 * m34 + - m14 * m31 * m42 + + m14 * m41 * m32; + inverse[10] =m11 * m22 * m44 + -m11 * m42 * m24 + - m12 * m21 * m44 + + m12 * m41 * m24 + + m14 * m21 * m42 + - m14 * m41 * m22; + inverse[14] = -m11 * m22 * m34 + +m11 * m32 * m24 + + m12 * m21 * m34 + - m12 * m31 * m24 + - m14 * m21 * m32 + + m14 * m31 * m22; + inverse[3] = -m21 * m32 * m43 + + m21 * m42 * m33 + + m22 * m31 * m43 + - m22 * m41 * m33 + - m23 * m31 * m42 + + m23 * m41 * m32; + inverse[7] =m11 * m32 * m43 + -m11 * m42 * m33 + - m12 * m31 * m43 + + m12 * m41 * m33 + + m13 * m31 * m42 + - m13 * m41 * m32; + inverse[11] = -m11 * m22 * m43 + +m11 * m42 * m23 + + m12 * m21 * m43 + - m12 * m41 * m23 + - m13 * m21 * m42 + + m13 * m41 * m22; + inverse[15] =m11 * m22 * m33 + -m11 * m32 * m23 + - m12 * m21 * m33 + + m12 * m31 * m23 + + m13 * m21 * m32 + - m13 * m31 * m22; + inverted_determinant = MFLOAT_C(1.0) / (m11 * inverse[0] + m21 * inverse[4] + m31 * inverse[8] + m41 * inverse[12]); + result[0] = inverse[0] * inverted_determinant; + result[1] = inverse[1] * inverted_determinant; + result[2] = inverse[2] * inverted_determinant; + result[3] = inverse[3] * inverted_determinant; + result[4] = inverse[4] * inverted_determinant; + result[5] = inverse[5] * inverted_determinant; + result[6] = inverse[6] * inverted_determinant; + result[7] = inverse[7] * inverted_determinant; + result[8] = inverse[8] * inverted_determinant; + result[9] = inverse[9] * inverted_determinant; + result[10] = inverse[10] * inverted_determinant; + result[11] = inverse[11] * inverted_determinant; + result[12] = inverse[12] * inverted_determinant; + result[13] = inverse[13] * inverted_determinant; + result[14] = inverse[14] * inverted_determinant; + result[15] = inverse[15] * inverted_determinant; + return result; +} + +mfloat_t *mat4_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f) +{ + result[0] = m0[0] + (m1[0] - m0[0]) * f; + result[1] = m0[1] + (m1[1] - m0[1]) * f; + result[2] = m0[2] + (m1[2] - m0[2]) * f; + result[3] = m0[3] + (m1[3] - m0[3]) * f; + result[4] = m0[4] + (m1[4] - m0[4]) * f; + result[5] = m0[5] + (m1[5] - m0[5]) * f; + result[6] = m0[6] + (m1[6] - m0[6]) * f; + result[7] = m0[7] + (m1[7] - m0[7]) * f; + result[8] = m0[8] + (m1[8] - m0[8]) * f; + result[9] = m0[9] + (m1[9] - m0[9]) * f; + result[10] = m0[10] + (m1[10] - m0[10]) * f; + result[11] = m0[11] + (m1[11] - m0[11]) * f; + result[12] = m0[12] + (m1[12] - m0[12]) * f; + result[13] = m0[13] + (m1[13] - m0[13]) * f; + result[14] = m0[14] + (m1[14] - m0[14]) * f; + result[15] = m0[15] + (m1[15] - m0[15]) * f; + return result; +} + +mfloat_t *mat4_look_at(mfloat_t *result, mfloat_t *position, mfloat_t *target, mfloat_t *up) +{ + mfloat_t tmp_forward[VEC3_SIZE]; + mfloat_t tmp_side[VEC3_SIZE]; + mfloat_t tmp_up[VEC3_SIZE]; + vec3_subtract(tmp_forward, target, position); + vec3_normalize(tmp_forward, tmp_forward); + vec3_cross(tmp_side, tmp_forward, up); + vec3_normalize(tmp_side, tmp_side); + vec3_cross(tmp_up, tmp_side, tmp_forward); + result[0] = tmp_side[0]; + result[1] = tmp_up[0]; + result[2] = -tmp_forward[0]; + result[3] = MFLOAT_C(0.0); + result[4] = tmp_side[1]; + result[5] = tmp_up[1]; + result[6] = -tmp_forward[1]; + result[7] = MFLOAT_C(0.0); + result[8] = tmp_side[2]; + result[9] = tmp_up[2]; + result[10] = -tmp_forward[2]; + result[11] = MFLOAT_C(0.0); + result[12] = -vec3_dot(tmp_side, position); + result[13] = -vec3_dot(tmp_up, position); + result[14] = vec3_dot(tmp_forward, position); + result[15] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *mat4_ortho(mfloat_t *result, mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f) +{ + result[0] = MFLOAT_C(2.0) / (r - l); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(2.0) / (t - b); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = -MFLOAT_C(2.0) / (f - n); + result[11] = MFLOAT_C(0.0); + result[12] = -((r + l) / (r - l)); + result[13] = -((t + b) / (t - b)); + result[14] = -((f + n) / (f - n)); + result[15] = MFLOAT_C(1.0); + return result; +} + +mfloat_t *mat4_perspective(mfloat_t *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f) +{ + mfloat_t tan_half_fov_y = MFLOAT_C(1.0) / MTAN(fov_y * MFLOAT_C(0.5)); + result[0] = MFLOAT_C(1.0) / aspect * tan_half_fov_y; + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(1.0) / tan_half_fov_y; + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = f / (n - f); + result[11] = -MFLOAT_C(1.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = -(f * n) / (f - n); + result[15] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *mat4_perspective_fov(mfloat_t *result, mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f) +{ + mfloat_t h2 = MCOS(fov * MFLOAT_C(0.5)) / MSIN(fov * MFLOAT_C(0.5)); + mfloat_t w2 = h2 * h / w; + result[0] = w2; + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = h2; + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = f / (n - f); + result[11] = -MFLOAT_C(1.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = -(f * n) / (f - n); + result[15] = MFLOAT_C(0.0); + return result; +} + +mfloat_t *mat4_perspective_infinite(mfloat_t *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n) +{ + mfloat_t range = MTAN(fov_y * MFLOAT_C(0.5)) * n; + mfloat_t left = -range * aspect; + mfloat_t right = range * aspect; + mfloat_t top = range; + mfloat_t bottom = -range; + result[0] = MFLOAT_C(2.0) * n / (right - left); + result[1] = MFLOAT_C(0.0); + result[2] = MFLOAT_C(0.0); + result[3] = MFLOAT_C(0.0); + result[4] = MFLOAT_C(0.0); + result[5] = MFLOAT_C(2.0) * n / (top - bottom); + result[6] = MFLOAT_C(0.0); + result[7] = MFLOAT_C(0.0); + result[8] = MFLOAT_C(0.0); + result[9] = MFLOAT_C(0.0); + result[10] = -MFLOAT_C(1.0); + result[11] = -MFLOAT_C(1.0); + result[12] = MFLOAT_C(0.0); + result[13] = MFLOAT_C(0.0); + result[14] = -MFLOAT_C(2.0) * n; + result[15] = MFLOAT_C(0.0); + return result; +} +#endif + +#if defined(MATHC_USE_STRUCT_FUNCTIONS) +#if defined(MATHC_USE_INT) +bool svec2i_is_zero(struct vec2i v0) +{ + return vec2i_is_zero((mint_t *)&v0); +} + +bool svec2i_is_equal(struct vec2i v0, struct vec2i v1) +{ + return vec2i_is_equal((mint_t *)&v0, (mint_t *)&v1); +} + +struct vec2i svec2i(mint_t x, mint_t y) +{ + struct vec2i result; + vec2i((mint_t *)&result, x, y); + return result; +} + +struct vec2i svec2i_assign(struct vec2i v0) +{ + struct vec2i result; + vec2i_assign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec2i svec2i_assign_vec2(struct vec2 v0) +{ + struct vec2i result; + vec2i_assign_vec2((mint_t *)&result, (mfloat_t *)&v0); + return result; +} +#endif + +struct vec2i svec2i_zero(void) +{ + struct vec2i result; + vec2i_zero((mint_t *)&result); + return result; +} + +struct vec2i svec2i_one(void) +{ + struct vec2i result; + vec2i_one((mint_t *)&result); + return result; +} + +struct vec2i svec2i_sign(struct vec2i v0) +{ + struct vec2i result; + vec2i_sign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec2i svec2i_add(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_add((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_add_i(struct vec2i v0, mint_t i) +{ + struct vec2i result; + vec2i_add_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec2i svec2i_subtract(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_subtract((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_subtract_i(struct vec2i v0, mint_t i) +{ + struct vec2i result; + vec2i_subtract_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec2i svec2i_multiply(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_multiply((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_multiply_i(struct vec2i v0, mint_t i) +{ + struct vec2i result; + vec2i_multiply_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec2i svec2i_divide(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_divide((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_divide_i(struct vec2i v0, mint_t i) +{ + struct vec2i result; + vec2i_divide_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec2i svec2i_snap(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_snap((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_snap_i(struct vec2i v0, mint_t i) +{ + struct vec2i result; + vec2i_snap_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec2i svec2i_negative(struct vec2i v0) +{ + struct vec2i result; + vec2i_negative((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec2i svec2i_abs(struct vec2i v0) +{ + struct vec2i result; + vec2i_abs((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec2i svec2i_max(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_max((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_min(struct vec2i v0, struct vec2i v1) +{ + struct vec2i result; + vec2i_min((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec2i svec2i_clamp(struct vec2i v0, struct vec2i v1, struct vec2i v2) +{ + struct vec2i result; + vec2i_clamp((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1, (mint_t *)&v2); + return result; +} + +struct vec2i svec2i_tangent(struct vec2i v0) +{ + struct vec2i result; + vec2i_tangent((mint_t *)&result, (mint_t *)&v0); + return result; +} + +bool svec3i_is_zero(struct vec3i v0) +{ + return vec3i_is_zero((mint_t *)&v0); +} + +bool svec3i_is_equal(struct vec3i v0, struct vec3i v1) +{ + return vec3i_is_equal((mint_t *)&v0, (mint_t *)&v1); +} + +struct vec3i svec3i(mint_t x, mint_t y, mint_t z) +{ + struct vec3i result; + vec3i((mint_t *)&result, x, y, z); + return result; +} + +struct vec3i svec3i_assign(struct vec3i v0) +{ + struct vec3i result; + vec3i_assign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec3i svec3i_assign_vec3(struct vec3 v0) +{ + struct vec3i result; + vec3i_assign_vec3((mint_t *)&result, (mfloat_t *)&v0); + return result; +} +#endif + +struct vec3i svec3i_zero(void) +{ + struct vec3i result; + vec3i_zero((mint_t *)&result); + return result; +} + +struct vec3i svec3i_one(void) +{ + struct vec3i result; + vec3i_one((mint_t *)&result); + return result; +} + +struct vec3i svec3i_sign(struct vec3i v0) +{ + struct vec3i result; + vec3i_sign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec3i svec3i_add(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_add((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_add_i(struct vec3i v0, mint_t i) +{ + struct vec3i result; + vec3i_add_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec3i svec3i_subtract(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_subtract((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_subtract_i(struct vec3i v0, mint_t i) +{ + struct vec3i result; + vec3i_subtract_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec3i svec3i_multiply(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_multiply((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_multiply_i(struct vec3i v0, mint_t i) +{ + struct vec3i result; + vec3i_multiply_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec3i svec3i_divide(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_divide((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_divide_i(struct vec3i v0, mint_t i) +{ + struct vec3i result; + vec3i_divide_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec3i svec3i_snap(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_snap((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_snap_i(struct vec3i v0, mint_t i) +{ + struct vec3i result; + vec3i_snap_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec3i svec3i_cross(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_cross((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_negative(struct vec3i v0) +{ + struct vec3i result; + vec3i_negative((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec3i svec3i_abs(struct vec3i v0) +{ + struct vec3i result; + vec3i_abs((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec3i svec3i_max(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_max((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_min(struct vec3i v0, struct vec3i v1) +{ + struct vec3i result; + vec3i_min((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec3i svec3i_clamp(struct vec3i v0, struct vec3i v1, struct vec3i v2) +{ + struct vec3i result; + vec3i_clamp((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1, (mint_t *)&v2); + return result; +} + +bool svec4i_is_zero(struct vec4i v0) +{ + return vec4i_is_zero((mint_t *)&v0); +} + +bool svec4i_is_equal(struct vec4i v0, struct vec4i v1) +{ + return vec4i_is_equal((mint_t *)&v0, (mint_t *)&v1); +} + +struct vec4i svec4i(mint_t x, mint_t y, mint_t z, mint_t w) +{ + struct vec4i result; + vec4i((mint_t *)&result, x, y, z, w); + return result; +} + +struct vec4i svec4i_assign(struct vec4i v0) +{ + struct vec4i result; + vec4i_assign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec4i svec4i_assign_vec4(struct vec4 v0) +{ + struct vec4i result; + vec4i_assign_vec4((mint_t *)&result, (mfloat_t *)&v0); + return result; +} +#endif + +struct vec4i svec4i_zero(void) +{ + struct vec4i result; + vec4i_zero((mint_t *)&result); + return result; +} + +struct vec4i svec4i_one(void) +{ + struct vec4i result; + vec4i_one((mint_t *)&result); + return result; +} + +struct vec4i svec4i_sign(struct vec4i v0) +{ + struct vec4i result; + vec4i_sign((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec4i svec4i_add(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_add((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_add_i(struct vec4i v0, mint_t i) +{ + struct vec4i result; + vec4i_add_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec4i svec4i_subtract(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_subtract((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_subtract_i(struct vec4i v0, mint_t i) +{ + struct vec4i result; + vec4i_subtract_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec4i svec4i_multiply(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_multiply((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_multiply_i(struct vec4i v0, mint_t i) +{ + struct vec4i result; + vec4i_multiply_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec4i svec4i_divide(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_divide((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_divide_i(struct vec4i v0, mint_t i) +{ + struct vec4i result; + vec4i_divide_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec4i svec4i_snap(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_snap((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_snap_i(struct vec4i v0, mint_t i) +{ + struct vec4i result; + vec4i_snap_i((mint_t *)&result, (mint_t *)&v0, i); + return result; +} + +struct vec4i svec4i_negative(struct vec4i v0) +{ + struct vec4i result; + vec4i_negative((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec4i svec4i_abs(struct vec4i v0) +{ + struct vec4i result; + vec4i_abs((mint_t *)&result, (mint_t *)&v0); + return result; +} + +struct vec4i svec4i_max(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_max((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_min(struct vec4i v0, struct vec4i v1) +{ + struct vec4i result; + vec4i_min((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1); + return result; +} + +struct vec4i svec4i_clamp(struct vec4i v0, struct vec4i v1, struct vec4i v2) +{ + struct vec4i result; + vec4i_clamp((mint_t *)&result, (mint_t *)&v0, (mint_t *)&v1, (mint_t *)&v2); + return result; +} +#endif + +#if defined(MATHC_USE_FLOATING_POINT) +bool svec2_is_zero(struct vec2 v0) +{ + return vec2_is_zero((mfloat_t *)&v0); +} + +bool svec2_is_equal(struct vec2 v0, struct vec2 v1) +{ + return vec2_is_equal((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +struct vec2 svec2(mfloat_t x, mfloat_t y) +{ + struct vec2 result; + vec2((mfloat_t *)&result, x, y); + return result; +} + +struct vec2 svec2_assign(struct vec2 v0) +{ + struct vec2 result; + vec2_assign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +#if defined(MATHC_USE_INT) +struct vec2 svec2_assign_vec2i(struct vec2i v0) +{ + struct vec2 result; + vec2_assign_vec2i((mfloat_t *)&result, (mint_t *)&v0); + return result; +} +#endif + +struct vec2 svec2_zero(void) +{ + struct vec2 result; + vec2_zero((mfloat_t *)&result); + return result; +} + +struct vec2 svec2_one(void) +{ + struct vec2 result; + vec2_one((mfloat_t *)&result); + return result; +} + +struct vec2 svec2_sign(struct vec2 v0) +{ + struct vec2 result; + vec2_sign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_add(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_add((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_add_f(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_add_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_subtract(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_subtract((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_subtract_f(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_subtract_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_multiply(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_multiply((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_multiply_f(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_multiply_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_multiply_mat2(struct vec2 v0, struct mat2 m0) +{ + struct vec2 result; + vec2_multiply_mat2((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&m0); + return result; +} + +struct vec2 svec2_divide(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_divide((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_divide_f(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_divide_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_snap(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_snap((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_snap_f(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_snap_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_negative(struct vec2 v0) +{ + struct vec2 result; + vec2_negative((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_abs(struct vec2 v0) +{ + struct vec2 result; + vec2_abs((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_floor(struct vec2 v0) +{ + struct vec2 result; + vec2_floor((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_ceil(struct vec2 v0) +{ + struct vec2 result; + vec2_ceil((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_round(struct vec2 v0) +{ + struct vec2 result; + vec2_round((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_max(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_max((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_min(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_min((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_clamp(struct vec2 v0, struct vec2 v1, struct vec2 v2) +{ + struct vec2 result; + vec2_clamp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2); + return result; +} + +struct vec2 svec2_normalize(struct vec2 v0) +{ + struct vec2 result; + vec2_normalize((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +mfloat_t svec2_dot(struct vec2 v0, struct vec2 v1) +{ + return vec2_dot((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +struct vec2 svec2_project(struct vec2 v0, struct vec2 v1) +{ + struct vec2 result; + vec2_project((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec2 svec2_slide(struct vec2 v0, struct vec2 normal) +{ + struct vec2 result; + vec2_slide((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&normal); + return result; +} + +struct vec2 svec2_reflect(struct vec2 v0, struct vec2 normal) +{ + struct vec2 result; + vec2_reflect((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&normal); + return result; +} + +struct vec2 svec2_tangent(struct vec2 v0) +{ + struct vec2 result; + vec2_tangent((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec2 svec2_rotate(struct vec2 v0, mfloat_t f) +{ + struct vec2 result; + vec2_rotate((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec2 svec2_lerp(struct vec2 v0, struct vec2 v1, mfloat_t f) +{ + struct vec2 result; + vec2_lerp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, f); + return result; +} + +struct vec2 svec2_bezier3(struct vec2 v0, struct vec2 v1, struct vec2 v2, mfloat_t f) +{ + struct vec2 result; + vec2_bezier3((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2, f); + return result; +} + +struct vec2 svec2_bezier4(struct vec2 v0, struct vec2 v1, struct vec2 v2, struct vec2 v3, mfloat_t f) +{ + struct vec2 result; + vec2_bezier4((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2, (mfloat_t *)&v3, f); + return result; +} + +mfloat_t svec2_angle(struct vec2 v0) +{ + return vec2_angle((mfloat_t *)&v0); +} + +mfloat_t svec2_length(struct vec2 v0) +{ + return vec2_length((mfloat_t *)&v0); +} + +mfloat_t svec2_length_squared(struct vec2 v0) +{ + return vec2_length_squared((mfloat_t *)&v0); +} + +mfloat_t svec2_distance(struct vec2 v0, struct vec2 v1) +{ + return vec2_distance((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +mfloat_t svec2_distance_squared(struct vec2 v0, struct vec2 v1) +{ + return vec2_distance_squared((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +bool svec3_is_zero(struct vec3 v0) +{ + return vec3_is_zero((mfloat_t *)&v0); +} + +bool svec3_is_equal(struct vec3 v0, struct vec3 v1) +{ + return vec3_is_equal((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +struct vec3 svec3(mfloat_t x, mfloat_t y, mfloat_t z) +{ + struct vec3 result; + vec3((mfloat_t *)&result, x, y, z); + return result; +} + +struct vec3 svec3_assign(struct vec3 v0) +{ + struct vec3 result; + vec3_assign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +#if defined(MATHC_USE_INT) +struct vec3 svec3_assign_vec3i(struct vec3i v0) +{ + struct vec3 result; + vec3_assign_vec3i((mfloat_t *)&result, (mint_t *)&v0); + return result; +} +#endif + +struct vec3 svec3_zero(void) +{ + struct vec3 result; + vec3_zero((mfloat_t *)&result); + return result; +} + +struct vec3 svec3_one(void) +{ + struct vec3 result; + vec3_one((mfloat_t *)&result); + return result; +} + +struct vec3 svec3_sign(struct vec3 v0) +{ + struct vec3 result; + vec3_sign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_add(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_add((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_add_f(struct vec3 v0, mfloat_t f) +{ + struct vec3 result; + vec3_add_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec3 svec3_subtract(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_subtract((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_subtract_f(struct vec3 v0, mfloat_t f) +{ + struct vec3 result; + vec3_subtract_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec3 svec3_multiply(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_multiply((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_multiply_f(struct vec3 v0, mfloat_t f) +{ + struct vec3 result; + vec3_multiply_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec3 svec3_multiply_mat3(struct vec3 v0, struct mat3 m0) +{ + struct vec3 result; + vec3_multiply_mat3((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&m0); + return result; +} + +struct vec3 svec3_divide(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_divide((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_divide_f(struct vec3 v0, mfloat_t f) +{ + struct vec3 result; + vec3_divide_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec3 svec3_snap(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_snap((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_snap_f(struct vec3 v0, mfloat_t f) +{ + struct vec3 result; + vec3_snap_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec3 svec3_negative(struct vec3 v0) +{ + struct vec3 result; + vec3_negative((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_abs(struct vec3 v0) +{ + struct vec3 result; + vec3_abs((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_floor(struct vec3 v0) +{ + struct vec3 result; + vec3_floor((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_ceil(struct vec3 v0) +{ + struct vec3 result; + vec3_ceil((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_round(struct vec3 v0) +{ + struct vec3 result; + vec3_round((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec3 svec3_max(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_max((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_min(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_min((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_clamp(struct vec3 v0, struct vec3 v1, struct vec3 v2) +{ + struct vec3 result; + vec3_clamp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2); + return result; +} + +struct vec3 svec3_cross(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_cross((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_normalize(struct vec3 v0) +{ + struct vec3 result; + vec3_normalize((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +mfloat_t svec3_dot(struct vec3 v0, struct vec3 v1) +{ + return vec3_dot((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +struct vec3 svec3_project(struct vec3 v0, struct vec3 v1) +{ + struct vec3 result; + vec3_project((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec3 svec3_slide(struct vec3 v0, struct vec3 normal) +{ + struct vec3 result; + vec3_slide((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&normal); + return result; +} + +struct vec3 svec3_reflect(struct vec3 v0, struct vec3 normal) +{ + struct vec3 result; + vec3_reflect((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&normal); + return result; +} + +struct vec3 svec3_rotate(struct vec3 v0, struct vec3 ra, mfloat_t f) +{ + struct vec3 result; + vec3_lerp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&ra, f); + return result; +} + +struct vec3 svec3_lerp(struct vec3 v0, struct vec3 v1, mfloat_t f) +{ + struct vec3 result; + vec3_lerp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, f); + return result; +} + +struct vec3 svec3_bezier3(struct vec3 v0, struct vec3 v1, struct vec3 v2, mfloat_t f) +{ + struct vec3 result; + vec3_bezier3((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2, f); + return result; +} + +struct vec3 svec3_bezier4(struct vec3 v0, struct vec3 v1, struct vec3 v2, struct vec3 v3, mfloat_t f) +{ + struct vec3 result; + vec3_bezier4((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2, (mfloat_t *)&v3, f); + return result; +} + +mfloat_t svec3_length(struct vec3 v0) +{ + return vec3_length((mfloat_t *)&v0); +} + +mfloat_t svec3_length_squared(struct vec3 v0) +{ + return vec3_length_squared((mfloat_t *)&v0); +} + +mfloat_t svec3_distance(struct vec3 v0, struct vec3 v1) +{ + return vec3_distance((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +mfloat_t svec3_distance_squared(struct vec3 v0, struct vec3 v1) +{ + return vec3_distance_squared((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +bool svec4_is_zero(struct vec4 v0) +{ + return vec4_is_zero((mfloat_t *)&v0); +} + +bool svec4_is_equal(struct vec4 v0, struct vec4 v1) +{ + return vec4_is_equal((mfloat_t *)&v0, (mfloat_t *)&v1); +} + +struct vec4 svec4(mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) +{ + struct vec4 result; + vec4((mfloat_t *)&result, x, y, z, w); + return result; +} + +struct vec4 svec4_assign(struct vec4 v0) +{ + struct vec4 result; + vec4_assign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +#if defined(MATHC_USE_INT) +struct vec4 svec4_assign_vec4i(struct vec4i v0) +{ + struct vec4 result; + vec4_assign_vec4i((mfloat_t *)&result, (mint_t *)&v0); + return result; +} +#endif + +struct vec4 svec4_zero(void) +{ + struct vec4 result; + vec4_zero((mfloat_t *)&result); + return result; +} + +struct vec4 svec4_one(void) +{ + struct vec4 result; + vec4_one((mfloat_t *)&result); + return result; +} + +struct vec4 svec4_sign(struct vec4 v0) +{ + struct vec4 result; + vec4_sign((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_add(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_add((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_add_f(struct vec4 v0, mfloat_t f) +{ + struct vec4 result; + vec4_add_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec4 svec4_subtract(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_subtract((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_subtract_f(struct vec4 v0, mfloat_t f) +{ + struct vec4 result; + vec4_subtract_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec4 svec4_multiply(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_multiply((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_multiply_f(struct vec4 v0, mfloat_t f) +{ + struct vec4 result; + vec4_multiply_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec4 svec4_multiply_mat4(struct vec4 v0, struct mat4 m0) +{ + struct vec4 result; + vec4_multiply_mat4((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&m0); + return result; +} + +struct vec4 svec4_divide(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_divide((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_divide_f(struct vec4 v0, mfloat_t f) +{ + struct vec4 result; + vec4_divide_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec4 svec4_snap(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_snap((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_snap_f(struct vec4 v0, mfloat_t f) +{ + struct vec4 result; + vec4_snap_f((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct vec4 svec4_negative(struct vec4 v0) +{ + struct vec4 result; + vec4_negative((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_abs(struct vec4 v0) +{ + struct vec4 result; + vec4_abs((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_floor(struct vec4 v0) +{ + struct vec4 result; + vec4_floor((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_ceil(struct vec4 v0) +{ + struct vec4 result; + vec4_ceil((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_round(struct vec4 v0) +{ + struct vec4 result; + vec4_round((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_max(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_max((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_min(struct vec4 v0, struct vec4 v1) +{ + struct vec4 result; + vec4_min((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct vec4 svec4_clamp(struct vec4 v0, struct vec4 v1, struct vec4 v2) +{ + struct vec4 result; + vec4_clamp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, (mfloat_t *)&v2); + return result; +} + +struct vec4 svec4_normalize(struct vec4 v0) +{ + struct vec4 result; + vec4_normalize((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct vec4 svec4_lerp(struct vec4 v0, struct vec4 v1, mfloat_t f) +{ + struct vec4 result; + vec4_lerp((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1, f); + return result; +} + +bool squat_is_zero(struct quat q0) +{ + return quat_is_zero((mfloat_t *)&q0); +} + +bool squat_is_equal(struct quat q0, struct quat q1) +{ + return quat_is_equal((mfloat_t *)&q0, (mfloat_t *)&q1); +} + +struct quat squat(mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) +{ + struct quat result; + quat((mfloat_t *)&result, x, y, z, w); + return result; +} + +struct quat squat_assign(struct quat q0) +{ + struct quat result; + quat_assign((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct quat squat_zero(void) +{ + struct quat result; + quat_zero((mfloat_t *)&result); + return result; +} + +struct quat squat_null(void) +{ + struct quat result; + quat_null((mfloat_t *)&result); + return result; +} + +struct quat squat_multiply(struct quat q0, struct quat q1) +{ + struct quat result; + quat_multiply((mfloat_t *)&result, (mfloat_t *)&q0, (mfloat_t *)&q1); + return result; +} + +struct quat squat_multiply_f(struct quat q0, mfloat_t f) +{ + struct quat result; + quat_multiply_f((mfloat_t *)&result, (mfloat_t *)&q0, f); + return result; +} + +struct quat squat_divide(struct quat q0, struct quat q1) +{ + struct quat result; + quat_divide((mfloat_t *)&result, (mfloat_t *)&q0, (mfloat_t *)&q1); + return result; +} + +struct quat squat_divide_f(struct quat q0, mfloat_t f) +{ + struct quat result; + quat_divide_f((mfloat_t *)&result, (mfloat_t *)&q0, f); + return result; +} + +struct quat squat_negative(struct quat q0) +{ + struct quat result; + quat_negative((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct quat squat_conjugate(struct quat q0) +{ + struct quat result; + quat_conjugate((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct quat squat_inverse(struct quat q0) +{ + struct quat result; + quat_inverse((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct quat squat_normalize(struct quat q0) +{ + struct quat result; + quat_normalize((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +mfloat_t squat_dot(struct quat q0, struct quat q1) +{ + return quat_dot((mfloat_t *)&q0, (mfloat_t *)&q1); +} + +struct quat squat_power(struct quat q0, mfloat_t exponent) +{ + struct quat result; + quat_power((mfloat_t *)&result, (mfloat_t *)&q0, exponent); + return result; +} + +struct quat squat_from_axis_angle(struct vec3 v0, mfloat_t angle) +{ + struct quat result; + quat_from_axis_angle((mfloat_t *)&result, (mfloat_t *)&v0, angle); + return result; +} + +struct quat squat_from_vec3(struct vec3 v0, struct vec3 v1) +{ + struct quat result; + quat_from_vec3((mfloat_t *)&result, (mfloat_t *)&v0, (mfloat_t *)&v1); + return result; +} + +struct quat squat_from_mat4(struct mat4 m0) +{ + struct quat result; + quat_from_mat4((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct quat squat_lerp(struct quat q0, struct quat q1, mfloat_t f) +{ + struct quat result; + quat_lerp((mfloat_t *)&result, (mfloat_t *)&q0, (mfloat_t *)&q1, f); + return result; +} + +struct quat squat_slerp(struct quat q0, struct quat q1, mfloat_t f) +{ + struct quat result; + quat_slerp((mfloat_t *)&result, (mfloat_t *)&q0, (mfloat_t *)&q1, f); + return result; +} + +mfloat_t squat_length(struct quat q0) +{ + return quat_length((mfloat_t *)&q0); +} + +mfloat_t squat_length_squared(struct quat q0) +{ + return quat_length_squared((mfloat_t *)&q0); +} + +mfloat_t squat_angle(struct quat q0, struct quat q1) +{ + return quat_angle((mfloat_t *)&q0, (mfloat_t *)&q1); +} + +struct mat2 smat2(mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22) +{ + struct mat2 result; + mat2((mfloat_t *)&result, m11, m12, m21, m22); + return result; +} + +struct mat2 smat2_zero(void) +{ + struct mat2 result; + mat2_zero((mfloat_t *)&result); + return result; +} + +struct mat2 smat2_identity(void) +{ + struct mat2 result; + mat2_identity((mfloat_t *)&result); + return result; +} + +mfloat_t smat2_determinant(struct mat2 m0) +{ + return mat2_determinant((mfloat_t *)&m0); +} + +struct mat2 smat2_assign(struct mat2 m0) +{ + struct mat2 result; + mat2_assign((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_negative(struct mat2 m0) +{ + struct mat2 result; + mat2_negative((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_transpose(struct mat2 m0) +{ + struct mat2 result; + mat2_transpose((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_cofactor(struct mat2 m0) +{ + struct mat2 result; + mat2_cofactor((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_adjugate(struct mat2 m0) +{ + struct mat2 result; + mat2_adjugate((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_multiply(struct mat2 m0, struct mat2 m1) +{ + struct mat2 result; + mat2_multiply((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1); + return result; +} + +struct mat2 smat2_multiply_f(struct mat2 m0, mfloat_t f) +{ + struct mat2 result; + mat2_multiply_f((mfloat_t *)&result, (mfloat_t *)&m0, f); + return result; +} + +struct mat2 smat2_inverse(struct mat2 m0) +{ + struct mat2 result; + mat2_inverse((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat2 smat2_scaling(struct vec2 v0) +{ + struct mat2 result; + mat2_scaling((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct mat2 smat2_scale(struct mat2 m0, struct vec2 v0) +{ + struct mat2 result; + mat2_scale((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat2 smat2_rotation_z(mfloat_t f) +{ + struct mat2 result; + mat2_rotation_z((mfloat_t *)&result, f); + return result; +} + +struct mat2 smat2_lerp(struct mat2 m0, struct mat2 m1, mfloat_t f) +{ + struct mat2 result; + mat2_lerp((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1, f); + return result; +} + +struct mat3 smat3(mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33) +{ + struct mat3 result; + mat3((mfloat_t *)&result, m11, m12, m13, m21, m22, m23, m31, m32, m33); + return result; +} + +struct mat3 smat3_zero(void) +{ + struct mat3 result; + mat3_zero((mfloat_t *)&result); + return result; +} + +struct mat3 smat3_identity(void) +{ + struct mat3 result; + mat3_identity((mfloat_t *)&result); + return result; +} + +mfloat_t smat3_determinant(struct mat3 m0) +{ + return mat3_determinant((mfloat_t *)&m0); +} + +struct mat3 smat3_assign(struct mat3 m0) +{ + struct mat3 result; + mat3_assign((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat3 smat3_negative(struct mat3 m0) +{ + struct mat3 result; + mat3_negative((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat3 smat3_transpose(struct mat3 m0) +{ + struct mat3 result; + mat3_transpose((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat3 smat3_cofactor(struct mat3 m0) +{ + struct mat3 result; + mat3_cofactor((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat3 smat3_multiply(struct mat3 m0, struct mat3 m1) +{ + struct mat3 result; + mat3_multiply((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1); + return result; +} + +struct mat3 smat3_multiply_f(struct mat3 m0, mfloat_t f) +{ + struct mat3 result; + mat3_multiply_f((mfloat_t *)&result, (mfloat_t *)&m0, f); + return result; +} + +struct mat3 smat3_inverse(struct mat3 m0) +{ + struct mat3 result; + mat3_inverse((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat3 smat3_scaling(struct vec3 v0) +{ + struct mat3 result; + mat3_scaling((mfloat_t *)&result, (mfloat_t *)&v0); + return result; +} + +struct mat3 smat3_scale(struct mat3 m0, struct vec3 v0) +{ + struct mat3 result; + mat3_scale((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat3 smat3_rotation_x(mfloat_t f) +{ + struct mat3 result; + mat3_rotation_x((mfloat_t *)&result, f); + return result; +} + +struct mat3 smat3_rotation_y(mfloat_t f) +{ + struct mat3 result; + mat3_rotation_y((mfloat_t *)&result, f); + return result; +} + +struct mat3 smat3_rotation_z(mfloat_t f) +{ + struct mat3 result; + mat3_rotation_z((mfloat_t *)&result, f); + return result; +} + +struct mat3 smat3_rotation_axis(struct vec3 v0, mfloat_t f) +{ + struct mat3 result; + mat3_rotation_axis((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct mat3 smat3_rotation_quat(struct quat q0) +{ + struct mat3 result; + mat3_rotation_quat((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct mat3 smat3_lerp(struct mat3 m0, struct mat3 m1, mfloat_t f) +{ + struct mat3 result; + mat3_lerp((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1, f); + return result; +} + +struct mat4 smat4(mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44) +{ + struct mat4 result; + mat4((mfloat_t *)&result, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); + return result; +} + +struct mat4 smat4_zero(void) +{ + struct mat4 result; + mat4_zero((mfloat_t *)&result); + return result; +} + +struct mat4 smat4_identity(void) +{ + struct mat4 result; + mat4_identity((mfloat_t *)&result); + return result; +} + +mfloat_t smat4_determinant(struct mat4 m0) +{ + return mat4_determinant((mfloat_t *)&m0); +} + +struct mat4 smat4_assign(struct mat4 m0) +{ + struct mat4 result; + mat4_assign((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat4 smat4_negative(struct mat4 m0) +{ + struct mat4 result; + mat4_negative((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat4 smat4_transpose(struct mat4 m0) +{ + struct mat4 result; + mat4_transpose((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat4 smat4_cofactor(struct mat4 m0) +{ + struct mat4 result; + mat4_cofactor((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat4 smat4_rotation_x(mfloat_t f) +{ + struct mat4 result; + mat4_rotation_x((mfloat_t *)&result, f); + return result; +} + +struct mat4 smat4_rotation_y(mfloat_t f) +{ + struct mat4 result; + mat4_rotation_y((mfloat_t *)&result, f); + return result; +} + +struct mat4 smat4_rotation_z(mfloat_t f) +{ + struct mat4 result; + mat4_rotation_z((mfloat_t *)&result, f); + return result; +} + +struct mat4 smat4_rotation_axis(struct vec3 v0, mfloat_t f) +{ + struct mat4 result; + mat4_rotation_axis((mfloat_t *)&result, (mfloat_t *)&v0, f); + return result; +} + +struct mat4 smat4_rotation_quat(struct quat q0) +{ + struct mat4 result; + mat4_rotation_quat((mfloat_t *)&result, (mfloat_t *)&q0); + return result; +} + +struct mat4 smat4_translation(struct mat4 m0, struct vec3 v0) +{ + struct mat4 result; + mat4_translation((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat4 smat4_translate(struct mat4 m0, struct vec3 v0) +{ + struct mat4 result; + mat4_translate((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat4 smat4_scaling(struct mat4 m0, struct vec3 v0) +{ + struct mat4 result; + mat4_scaling((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat4 smat4_scale(struct mat4 m0, struct vec3 v0) +{ + struct mat4 result; + mat4_scale((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&v0); + return result; +} + +struct mat4 smat4_multiply(struct mat4 m0, struct mat4 m1) +{ + struct mat4 result; + mat4_multiply((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1); + return result; +} + +struct mat4 smat4_multiply_f(struct mat4 m0, mfloat_t f) +{ + struct mat4 result; + mat4_multiply_f((mfloat_t *)&result, (mfloat_t *)&m0, f); + return result; +} + +struct mat4 smat4_inverse(struct mat4 m0) +{ + struct mat4 result; + mat4_inverse((mfloat_t *)&result, (mfloat_t *)&m0); + return result; +} + +struct mat4 smat4_lerp(struct mat4 m0, struct mat4 m1, mfloat_t f) +{ + struct mat4 result; + mat4_lerp((mfloat_t *)&result, (mfloat_t *)&m0, (mfloat_t *)&m1, f); + return result; +} + +struct mat4 smat4_look_at(struct vec3 position, struct vec3 target, struct vec3 up) +{ + struct mat4 result; + mat4_look_at((mfloat_t *)&result, (mfloat_t *)&position, (mfloat_t *)&target, (mfloat_t *)&up); + return result; +} + +struct mat4 smat4_ortho(mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f) +{ + struct mat4 result; + mat4_ortho((mfloat_t *)&result, l, r, b, t, n, f); + return result; +} + +struct mat4 smat4_perspective(mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f) +{ + struct mat4 result; + mat4_perspective((mfloat_t *)&result, fov_y, aspect, n, f); + return result; +} + +struct mat4 smat4_perspective_fov(mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f) +{ + struct mat4 result; + mat4_perspective_fov((mfloat_t *)&result, fov, w, h, n, f); + return result; +} + +struct mat4 smat4_perspective_infinite(mfloat_t fov_y, mfloat_t aspect, mfloat_t n) +{ + struct mat4 result; + mat4_perspective_infinite((mfloat_t *)&result, fov_y, aspect, n); + return result; +} +#endif +#endif + +#if defined(MATHC_USE_POINTER_STRUCT_FUNCTIONS) +#if defined(MATHC_USE_INT) +bool psvec2i_is_zero(struct vec2i *v0) +{ + return vec2i_is_zero((mint_t *)v0); +} + +bool psvec2i_is_equal(struct vec2i *v0, struct vec2i *v1) +{ + return vec2i_is_equal((mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i(struct vec2i *result, mint_t x, mint_t y) +{ + return (struct vec2i *)vec2i((mint_t *)result, x, y); +} + +struct vec2i *psvec2i_assign(struct vec2i *result, struct vec2i *v0) +{ + return (struct vec2i *)vec2i_assign((mint_t *)result, (mint_t *)v0); +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec2i *psvec2i_assign_vec2(struct vec2i *result, struct vec2 *v0) +{ + return (struct vec2i *)vec2i_assign_vec2((mint_t *)result, (mfloat_t *)v0); +} #endif -/* Use `extern inline` for C99 or later */ -#ifdef PREDEF_STANDARD_C99 -#define MATHC_EXTERN_INLINE extern inline -#else -#define MATHC_EXTERN_INLINE +struct vec2i *psvec2i_zero(struct vec2i *result) +{ + return (struct vec2i *)vec2i_zero((mint_t *)result); +} + +struct vec2i *psvec2i_one(struct vec2i *result) +{ + return (struct vec2i *)vec2i_one((mint_t *)result); +} + +struct vec2i *psvec2i_sign(struct vec2i *result, struct vec2i *v0) +{ + return (struct vec2i *)vec2i_sign((mint_t *)result, (mint_t *)v0); +} + +struct vec2i *psvec2i_add(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_add((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_add_i(struct vec2i *result, struct vec2i *v0, mint_t i) +{ + return (struct vec2i *)vec2i_add_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec2i *psvec2i_subtract(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_subtract((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_subtract_i(struct vec2i *result, struct vec2i *v0, mint_t i) +{ + return (struct vec2i *)vec2i_subtract_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec2i *psvec2i_multiply(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_multiply((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_multiply_i(struct vec2i *result, struct vec2i *v0, mint_t i) +{ + return (struct vec2i *)vec2i_multiply_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec2i *psvec2i_divide(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_divide((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_divide_i(struct vec2i *result, struct vec2i *v0, mint_t i) +{ + return (struct vec2i *)vec2i_divide_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec2i *psvec2i_snap(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_snap((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_snap_i(struct vec2i *result, struct vec2i *v0, mint_t i) +{ + return (struct vec2i *)vec2i_snap_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec2i *psvec2i_negative(struct vec2i *result, struct vec2i *v0) +{ + return (struct vec2i *)vec2i_negative((mint_t *)result, (mint_t *)v0); +} + +struct vec2i *psvec2i_abs(struct vec2i *result, struct vec2i *v0) +{ + return (struct vec2i *)vec2i_abs((mint_t *)result, (mint_t *)v0); +} + +struct vec2i *psvec2i_max(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_max((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_min(struct vec2i *result, struct vec2i *v0, struct vec2i *v1) +{ + return (struct vec2i *)vec2i_min((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec2i *psvec2i_clamp(struct vec2i *result, struct vec2i *v0, struct vec2i *v1, struct vec2i *v2) +{ + return (struct vec2i *)vec2i_clamp((mint_t *)result, (mint_t *)v0, (mint_t *)v1, (mint_t *)v2); +} + +struct vec2i *psvec2i_tangent(struct vec2i *result, struct vec2i *v0) +{ + return (struct vec2i *)vec2i_tangent((mint_t *)result, (mint_t *)v0); +} + +bool psvec3i_is_zero(struct vec3i *v0) +{ + return vec3i_is_zero((mint_t *)v0); +} + +bool psvec3i_is_equal(struct vec3i *v0, struct vec3i *v1) +{ + return vec3i_is_equal((mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i(struct vec3i *result, mint_t x, mint_t y, mint_t z) +{ + return (struct vec3i *)vec3i((mint_t *)result, x, y, z); +} + +struct vec3i *psvec3i_assign(struct vec3i *result, struct vec3i *v0) +{ + return (struct vec3i *)vec3i_assign((mint_t *)result, (mint_t *)v0); +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec3i *psvec3i_assign_vec3(struct vec3i *result, struct vec3 *v0) +{ + return (struct vec3i *)vec3i_assign_vec3((mint_t *)result, (mfloat_t *)v0); +} #endif -#ifndef TRUE -#define TRUE 1 +struct vec3i *psvec3i_zero(struct vec3i *result) +{ + return (struct vec3i *)vec3i_zero((mint_t *)result); +} + +struct vec3i *psvec3i_one(struct vec3i *result) +{ + return (struct vec3i *)vec3i_one((mint_t *)result); +} + +struct vec3i *psvec3i_sign(struct vec3i *result, struct vec3i *v0) +{ + return (struct vec3i *)vec3i_sign((mint_t *)result, (mint_t *)v0); +} + +struct vec3i *psvec3i_add(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_add((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_add_i(struct vec3i *result, struct vec3i *v0, mint_t i) +{ + return (struct vec3i *)vec3i_add_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec3i *psvec3i_subtract(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_subtract((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_subtract_i(struct vec3i *result, struct vec3i *v0, mint_t i) +{ + return (struct vec3i *)vec3i_subtract_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec3i *psvec3i_multiply(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_multiply((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_multiply_i(struct vec3i *result, struct vec3i *v0, mint_t i) +{ + return (struct vec3i *)vec3i_multiply_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec3i *psvec3i_divide(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_divide((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_divide_i(struct vec3i *result, struct vec3i *v0, mint_t i) +{ + return (struct vec3i *)vec3i_divide_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec3i *psvec3i_snap(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_snap((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_snap_i(struct vec3i *result, struct vec3i *v0, mint_t i) +{ + return (struct vec3i *)vec3i_snap_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec3i *psvec3i_cross(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_cross((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_negative(struct vec3i *result, struct vec3i *v0) +{ + return (struct vec3i *)vec3i_negative((mint_t *)result, (mint_t *)v0); +} + +struct vec3i *psvec3i_abs(struct vec3i *result, struct vec3i *v0) +{ + return (struct vec3i *)vec3i_abs((mint_t *)result, (mint_t *)v0); +} + +struct vec3i *psvec3i_max(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_max((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_min(struct vec3i *result, struct vec3i *v0, struct vec3i *v1) +{ + return (struct vec3i *)vec3i_min((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec3i *psvec3i_clamp(struct vec3i *result, struct vec3i *v0, struct vec3i *v1, struct vec3i *v2) +{ + return (struct vec3i *)vec3i_clamp((mint_t *)result, (mint_t *)v0, (mint_t *)v1, (mint_t *)v2); +} + +bool psvec4i_is_zero(struct vec4i *v0) +{ + return vec4i_is_zero((mint_t *)v0); +} + +bool psvec4i_is_equal(struct vec4i *v0, struct vec4i *v1) +{ + return vec4i_is_equal((mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i(struct vec4i *result, mint_t x, mint_t y, mint_t z, mint_t w) +{ + return (struct vec4i *)vec4i((mint_t *)result, x, y, z, w); +} + +struct vec4i *psvec4i_assign(struct vec4i *result, struct vec4i *v0) +{ + return (struct vec4i *)vec4i_assign((mint_t *)result, (mint_t *)v0); +} + +#if defined(MATHC_USE_FLOATING_POINT) +struct vec4i *psvec4i_assign_vec4(struct vec4i *result, struct vec4 *v0) +{ + return (struct vec4i *)vec4i_assign_vec4((mint_t *)result, (mfloat_t *)v0); +} #endif -#ifndef FALSE -#define FALSE 0 + +struct vec4i *psvec4i_zero(struct vec4i *result) +{ + return (struct vec4i *)vec4i_zero((mint_t *)result); +} + +struct vec4i *psvec4i_one(struct vec4i *result) +{ + return (struct vec4i *)vec4i_one((mint_t *)result); +} + +struct vec4i *psvec4i_sign(struct vec4i *result, struct vec4i *v0) +{ + return (struct vec4i *)vec4i_sign((mint_t *)result, (mint_t *)v0); +} + +struct vec4i *psvec4i_add(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_add((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_add_i(struct vec4i *result, struct vec4i *v0, mint_t i) +{ + return (struct vec4i *)vec4i_add_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec4i *psvec4i_subtract(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_subtract((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_subtract_i(struct vec4i *result, struct vec4i *v0, mint_t i) +{ + return (struct vec4i *)vec4i_subtract_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec4i *psvec4i_multiply(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_multiply((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_multiply_i(struct vec4i *result, struct vec4i *v0, mint_t i) +{ + return (struct vec4i *)vec4i_multiply_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec4i *psvec4i_divide(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_divide((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_divide_i(struct vec4i *result, struct vec4i *v0, mint_t i) +{ + return (struct vec4i *)vec4i_divide_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec4i *psvec4i_snap(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_snap((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_snap_i(struct vec4i *result, struct vec4i *v0, mint_t i) +{ + return (struct vec4i *)vec4i_snap_i((mint_t *)result, (mint_t *)v0, i); +} + +struct vec4i *psvec4i_negative(struct vec4i *result, struct vec4i *v0) +{ + return (struct vec4i *)vec4i_negative((mint_t *)result, (mint_t *)v0); +} + +struct vec4i *psvec4i_abs(struct vec4i *result, struct vec4i *v0) +{ + return (struct vec4i *)vec4i_abs((mint_t *)result, (mint_t *)v0); +} + +struct vec4i *psvec4i_max(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_max((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_min(struct vec4i *result, struct vec4i *v0, struct vec4i *v1) +{ + return (struct vec4i *)vec4i_min((mint_t *)result, (mint_t *)v0, (mint_t *)v1); +} + +struct vec4i *psvec4i_clamp(struct vec4i *result, struct vec4i *v0, struct vec4i *v1, struct vec4i *v2) +{ + return (struct vec4i *)vec4i_clamp((mint_t *)result, (mint_t *)v0, (mint_t *)v1, (mint_t *)v2); +} #endif -/* Utils */ -int nearly_equal(float a, float b, float epsilon) +#if defined(MATHC_USE_FLOATING_POINT) +bool psvec2_is_zero(struct vec2 *v0) { - int result = FALSE; - float abs_a = fabsf(a); - float abs_b = fabsf(b); - float diff = fabsf(a - b); - if (a == b) { - result = TRUE; - } else if (a == 0.0f || b == 0.0f || diff < FLT_EPSILON) { - result = diff < epsilon; - } else { - result = diff / fminf(abs_a + abs_b, FLT_MAX) < epsilon; - } - return result; + return vec2_is_zero((mfloat_t *)v0); } -float to_radians(float degrees) +bool psvec2_is_equal(struct vec2 *v0, struct vec2 *v1) { - return degrees * M_PIF / 180.0f; + return vec2_is_equal((mfloat_t *)v0, (mfloat_t *)v1); } -float to_degrees(float radians) +struct vec2 *psvec2(struct vec2 *result, mfloat_t x, mfloat_t y) { - return radians * 180.0f / M_PIF; + return (struct vec2 *)vec2((mfloat_t *)result, x, y); } -/* Vector 2D */ -void to_pvector2(float x, float y, struct vec *result) +struct vec2 *psvec2_assign(struct vec2 *result, struct vec2 *v0) { - result->x = x; - result->y = y; - result->z = 0.0f; - result->w = 1.0f; + return (struct vec2 *)vec2_assign((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec to_vector2(float x, float y) +#if defined(MATHC_USE_INT) +struct vec2 *psvec2_assign_vec2i(struct vec2 *result, struct vec2i *v0) { - struct vec result; - to_pvector2(x, y, &result); - return result; + return (struct vec2 *)vec2_assign_vec2i((mfloat_t *)result, (mint_t *)v0); } +#endif -void pvector2_add(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_zero(struct vec2 *result) { - result->x = a->x + b->x; - result->y = a->y + b->y; - result->w = 1.0f; + return (struct vec2 *)vec2_zero((mfloat_t *)result); } -MATHC_EXTERN_INLINE struct vec vector2_add(struct vec a, struct vec b) +struct vec2 *psvec2_one(struct vec2 *result) { - struct vec result; - pvector2_add(&a, &b, &result); - return result; + return (struct vec2 *)vec2_one((mfloat_t *)result); } -void pvector2_subtract(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_sign(struct vec2 *result, struct vec2 *v0) { - result->x = a->x - b->x; - result->y = a->y - b->y; - result->w = 1.0f; + return (struct vec2 *)vec2_sign((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_subtract(struct vec a, struct vec b) +struct vec2 *psvec2_add(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_subtract(&a, &b, &result); - return result; + return (struct vec2 *)vec2_add((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_scale(struct vec *a, float scale, struct vec *result) +struct vec2 *psvec2_add_f(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - result->x = a->x * scale; - result->y = a->y * scale; - result->w = 1.0f; + return (struct vec2 *)vec2_add_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec vector2_scale(struct vec a, float scale) +struct vec2 *psvec2_subtract(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_scale(&a, scale, &result); - return result; + return (struct vec2 *)vec2_subtract((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_multiply(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_subtract_f(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - result->x = a->x * b->x; - result->y = a->y * b->y; - result->w = 1.0f; + return (struct vec2 *)vec2_subtract_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec vector2_multiply(struct vec a, struct vec b) +struct vec2 *psvec2_multiply(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_multiply(&a, &b, &result); - return result; + return (struct vec2 *)vec2_multiply((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_divide(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_multiply_f(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - result->x = a->x / b->x; - result->y = a->y / b->y; - result->w = 1.0f; + return (struct vec2 *)vec2_multiply_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec vector2_divide(struct vec a, struct vec b) +struct vec2 *psvec2_multiply_mat2(struct vec2 *result, struct vec2 *v0, struct mat2 *m0) { - struct vec result; - pvector2_divide(&a, &b, &result); - return result; + return (struct vec2 *)vec2_multiply_mat2((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)m0); } -void pvector2_negative(struct vec *a, struct vec *result) +struct vec2 *psvec2_divide(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - result->x = -a->x; - result->y = -a->y; - result->w = 1.0f; + return (struct vec2 *)vec2_divide((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_negative(struct vec a) +struct vec2 *psvec2_divide_f(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - struct vec result; - pvector2_negative(&a, &result); - return result; + return (struct vec2 *)vec2_divide_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector2_inverse(struct vec *a, struct vec *result) +struct vec2 *psvec2_snap(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - if (a->x != 0.0f) { - result->x = 1.0f / a->x; - } else { - result->x = 0.0f; - } - if (a->y != 0.0f) { - result->y = 1.0f / a->y; - } else { - result->y = 0.0f; - } - result->w = 1.0f; + return (struct vec2 *)vec2_snap((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_inverse(struct vec a) +struct vec2 *psvec2_snap_f(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - struct vec result; - pvector2_inverse(&a, &result); - return result; + return (struct vec2 *)vec2_snap_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector2_abs(struct vec *a, struct vec *result) +struct vec2 *psvec2_negative(struct vec2 *result, struct vec2 *v0) { - result->x = fabsf(a->x); - result->y = fabsf(a->y); - result->w = 1.0f; + return (struct vec2 *)vec2_negative((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_abs(struct vec a) +struct vec2 *psvec2_abs(struct vec2 *result, struct vec2 *v0) { - struct vec result; - pvector2_abs(&a, &result); - return result; + return (struct vec2 *)vec2_abs((mfloat_t *)result, (mfloat_t *)v0); } -void pvector2_floor(struct vec *a, struct vec *result) +struct vec2 *psvec2_floor(struct vec2 *result, struct vec2 *v0) { - result->x = floorf(a->x); - result->y = floorf(a->y); - result->w = 1.0f; + return (struct vec2 *)vec2_floor((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_floor(struct vec a) +struct vec2 *psvec2_ceil(struct vec2 *result, struct vec2 *v0) { - struct vec result; - pvector2_floor(&a, &result); - return result; + return (struct vec2 *)vec2_ceil((mfloat_t *)result, (mfloat_t *)v0); } -void pvector2_ceil(struct vec *a, struct vec *result) +struct vec2 *psvec2_round(struct vec2 *result, struct vec2 *v0) { - result->x = ceilf(a->x); - result->y = ceilf(a->y); - result->w = 1.0f; + return (struct vec2 *)vec2_round((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_ceil(struct vec a) +struct vec2 *psvec2_max(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_ceil(&a, &result); - return result; + return (struct vec2 *)vec2_max((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_round(struct vec *a, struct vec *result) +struct vec2 *psvec2_min(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - result->x = roundf(a->x); - result->y = roundf(a->y); - result->w = 1.0f; + return (struct vec2 *)vec2_min((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_round(struct vec a) +struct vec2 *psvec2_clamp(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2) { - struct vec result; - pvector2_round(&a, &result); - return result; + return (struct vec2 *)vec2_clamp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2); } -void pvector2_max(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_normalize(struct vec2 *result, struct vec2 *v0) { - result->x = fmaxf(a->x, b->x); - result->y = fmaxf(a->y, b->y); - result->w = 1.0f; + return (struct vec2 *)vec2_normalize((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_max(struct vec a, struct vec b) +mfloat_t psvec2_dot(struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_max(&a, &b, &result); - return result; + return vec2_dot((mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_min(struct vec *a, struct vec *b, struct vec *result) +struct vec2 *psvec2_project(struct vec2 *result, struct vec2 *v0, struct vec2 *v1) { - result->x = fminf(a->x, b->x); - result->y = fminf(a->y, b->y); - result->w = 1.0f; + return (struct vec2 *)vec2_project((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_min(struct vec a, struct vec b) +struct vec2 *psvec2_slide(struct vec2 *result, struct vec2 *v0, struct vec2 *normal) { - struct vec result; - pvector2_min(&a, &b, &result); - return result; + return (struct vec2 *)vec2_slide((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)normal); } -float pvector2_dot(struct vec *a, struct vec *b) +struct vec2 *psvec2_reflect(struct vec2 *result, struct vec2 *v0, struct vec2 *normal) { - return a->x * b->x + a->y * b->y; + return (struct vec2 *)vec2_reflect((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)normal); } -MATHC_EXTERN_INLINE float vector2_dot(struct vec a, struct vec b) +struct vec2 *psvec2_tangent(struct vec2 *result, struct vec2 *v0) { - return pvector2_dot(&a, &b); + return (struct vec2 *)vec2_tangent((mfloat_t *)result, (mfloat_t *)v0); } -float pvector2_angle(struct vec *a) +struct vec2 *psvec2_rotate(struct vec2 *result, struct vec2 *v0, mfloat_t f) { - return atan2f(a->y, a->x); + return (struct vec2 *)vec2_rotate((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE float vector2_angle(struct vec a) +struct vec2 *psvec2_lerp(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, mfloat_t f) { - return pvector2_angle(&a); + return (struct vec2 *)vec2_lerp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, f); } -float pvector2_length_squared(struct vec *a) +struct vec2 *psvec2_bezier3(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2, mfloat_t f) { - return a->x * a->x + a->y * a->y; + return (struct vec2 *)vec2_bezier3((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2, f); } -MATHC_EXTERN_INLINE float vector2_length_squared(struct vec a) +struct vec2 *psvec2_bezier4(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2, struct vec2 *v3, mfloat_t f) { - return pvector2_length_squared(&a); + return (struct vec2 *)vec2_bezier4((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2, (mfloat_t *)v3, f); } -float pvector2_length(struct vec *a) +mfloat_t psvec2_angle(struct vec2 *v0) { - return sqrtf(a->x * a->x + a->y * a->y); + return vec2_angle((mfloat_t *)v0); } -MATHC_EXTERN_INLINE float vector2_length(struct vec a) +mfloat_t psvec2_length(struct vec2 *v0) { - return pvector2_length(&a); + return vec2_length((mfloat_t *)v0); } -void pvector2_normalize(struct vec *a, struct vec *result) +mfloat_t psvec2_length_squared(struct vec2 *v0) { - float length = a->x * a->x + a->y * a->y; - if (length != 0.0f) { - length = sqrtf(length); - result->x = a->x / length; - result->y = a->y / length; - } else { - result->x = 0.0f; - result->y = 0.0f; - } - result->w = 1.0f; + return vec2_length_squared((mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_normalize(struct vec a) +mfloat_t psvec2_distance(struct vec2 *v0, struct vec2 *v1) { - struct vec result; - pvector2_normalize(&a, &result); - return result; + return vec2_distance((mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_slide(struct vec *a, struct vec *normal, struct vec *result) +mfloat_t psvec2_distance_squared(struct vec2 *v0, struct vec2 *v1) { - float d = pvector2_dot(a, normal); - result->x = a->x - normal->x * d; - result->y = a->y - normal->y * d; - result->w = 1.0f; + return vec2_distance_squared((mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_slide(struct vec a, struct vec normal) +bool psvec3_is_zero(struct vec3 *v0) { - struct vec result; - pvector2_slide(&a, &normal, &result); - return result; + return vec3_is_zero((mfloat_t *)v0); } -void pvector2_reflect(struct vec *a, struct vec *normal, struct vec *result) +bool psvec3_is_equal(struct vec3 *v0, struct vec3 *v1) { - float d = 2.0f * pvector2_dot(a, normal); - result->x = a->x - normal->x * d; - result->y = a->y - normal->y * d; - result->w = 1.0f; + return vec3_is_equal((mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector2_reflect(struct vec a, struct vec normal) +struct vec3 *psvec3(struct vec3 *result, mfloat_t x, mfloat_t y, mfloat_t z) { - struct vec result; - pvector2_reflect(&a, &normal, &result); - return result; + return (struct vec3 *)vec3((mfloat_t *)result, x, y, z); } -void pvector2_tangent(struct vec *a, struct vec *result) +struct vec3 *psvec3_assign(struct vec3 *result, struct vec3 *v0) { - result->x = a->y; - result->y = -a->x; - result->w = 1.0f; + return (struct vec3 *)vec3_assign((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector2_tangent(struct vec a) +#if defined(MATHC_USE_INT) +struct vec3 *psvec3_assign_vec3i(struct vec3 *result, struct vec3i *v0) { - struct vec result; - pvector2_tangent(&a, &result); - return result; + return (struct vec3 *)vec3_assign_vec3i((mfloat_t *)result, (mint_t *)v0); } +#endif -void pvector2_rotate(struct vec *a, float angle, struct vec *result) +struct vec3 *psvec3_zero(struct vec3 *result) { - float cs = cosf(angle); - float sn = sinf(angle); - float x = a->x; - float y = a->y; - result->x = x * cs - y * sn; - result->y = x * sn + y * cs; - result->w = 1.0f; + return (struct vec3 *)vec3_zero((mfloat_t *)result); } -MATHC_EXTERN_INLINE struct vec vector2_rotate(struct vec a, float angle) +struct vec3 *psvec3_one(struct vec3 *result) { - struct vec result; - pvector2_rotate(&a, angle, &result); - return result; + return (struct vec3 *)vec3_one((mfloat_t *)result); } -float pvector2_distance_to(struct vec *a, struct vec *b) +struct vec3 *psvec3_sign(struct vec3 *result, struct vec3 *v0) { - return sqrtf((a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b->y)); + return (struct vec3 *)vec3_sign((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE float vector2_distance_to(struct vec a, struct vec b) +struct vec3 *psvec3_add(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - return pvector2_distance_to(&a, &b); + return (struct vec3 *)vec3_add((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -float pvector2_distance_squared_to(struct vec *a, struct vec *b) +struct vec3 *psvec3_add_f(struct vec3 *result, struct vec3 *v0, mfloat_t f) { - return (a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b->y); + return (struct vec3 *)vec3_add_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE float vector2_distance_squared_to(struct vec a, struct vec b) +struct vec3 *psvec3_subtract(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - return pvector2_distance_squared_to(&a, &b); + return (struct vec3 *)vec3_subtract((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector2_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result) +struct vec3 *psvec3_subtract_f(struct vec3 *result, struct vec3 *v0, mfloat_t f) { - result->x = a->x + (b->x - a->x) * p; - result->y = a->y + (b->y - a->y) * p; - result->w = 1.0f; + return (struct vec3 *)vec3_subtract_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec vector2_linear_interpolation(struct vec a, struct vec b, float p) +struct vec3 *psvec3_multiply(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - struct vec result; - pvector2_linear_interpolation(&a, &b, p, &result); - return result; + return (struct vec3 *)vec3_multiply((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -/* Vector 3D */ -void to_pvector3(float x, float y, float z, struct vec *result) +struct vec3 *psvec3_multiply_f(struct vec3 *result, struct vec3 *v0, mfloat_t f) { - result->x = x; - result->y = y; - result->z = z; - result->w = 1.0f; + return (struct vec3 *)vec3_multiply_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec to_vector3(float x, float y, float z) +struct vec3 *psvec3_multiply_mat3(struct vec3 *result, struct vec3 *v0, struct mat3 *m0) { - struct vec result; - to_pvector3(x, y, z, &result); - return result; + return (struct vec3 *)vec3_multiply_mat3((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)m0); } -void pvector3_add(struct vec *a, struct vec *b, struct vec *result) +struct vec3 *psvec3_divide(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - result->x = a->x + b->x; - result->y = a->y + b->y; - result->z = a->z + b->z; - result->w = 1.0f; + return (struct vec3 *)vec3_divide((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_add(struct vec a, struct vec b) +struct vec3 *psvec3_divide_f(struct vec3 *result, struct vec3 *v0, mfloat_t f) { - struct vec result; - pvector3_add(&a, &b, &result); - return result; + return (struct vec3 *)vec3_divide_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector3_subtract(struct vec *a, struct vec *b, struct vec *result) +struct vec3 *psvec3_snap(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - result->x = a->x - b->x; - result->y = a->y - b->y; - result->z = a->z - b->z; - result->w = 1.0f; + return (struct vec3 *)vec3_snap((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_subtract(struct vec a, struct vec b) +struct vec3 *psvec3_snap_f(struct vec3 *result, struct vec3 *v0, mfloat_t f) { - struct vec result; - pvector3_subtract(&a, &b, &result); - return result; + return (struct vec3 *)vec3_snap_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector3_scale(struct vec *a, float scale, struct vec *result) +struct vec3 *psvec3_negative(struct vec3 *result, struct vec3 *v0) { - result->x = a->x * scale; - result->y = a->y * scale; - result->z = a->z * scale; - result->w = 1.0f; + return (struct vec3 *)vec3_negative((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector3_scale(struct vec a, float scale) +struct vec3 *psvec3_abs(struct vec3 *result, struct vec3 *v0) { - struct vec result; - pvector3_scale(&a, scale, &result); - return result; + return (struct vec3 *)vec3_abs((mfloat_t *)result, (mfloat_t *)v0); } -void pvector3_multiply(struct vec *a, struct vec *b, struct vec *result) +struct vec3 *psvec3_floor(struct vec3 *result, struct vec3 *v0) { - result->x = a->x * b->x; - result->y = a->y * b->y; - result->z = a->z * b->z; - result->w = 1.0f; + return (struct vec3 *)vec3_floor((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector3_multiply(struct vec a, struct vec b) +struct vec3 *psvec3_ceil(struct vec3 *result, struct vec3 *v0) { - struct vec result; - pvector3_multiply(&a, &b, &result); - return result; + return (struct vec3 *)vec3_ceil((mfloat_t *)result, (mfloat_t *)v0); } -void pvector3_divide(struct vec *a, struct vec *b, struct vec *result) +struct vec3 *psvec3_round(struct vec3 *result, struct vec3 *v0) { - result->x = a->x / b->x; - result->y = a->y / b->y; - result->z = a->z / b->z; - result->w = 1.0f; + return (struct vec3 *)vec3_round((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector3_divide(struct vec a, struct vec b) +struct vec3 *psvec3_max(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - struct vec result; - pvector3_divide(&a, &b, &result); - return result; + return (struct vec3 *)vec3_max((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector3_negative(struct vec *a, struct vec *result) +struct vec3 *psvec3_min(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - result->x = -a->x; - result->y = -a->y; - result->z = -a->z; - result->w = 1.0f; + return (struct vec3 *)vec3_min((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_negative(struct vec a) +struct vec3 *psvec3_clamp(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2) { - struct vec result; - pvector3_negative(&a, &result); - return result; + return (struct vec3 *)vec3_clamp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2); } -void pvector3_inverse(struct vec *a, struct vec *result) +struct vec3 *psvec3_cross(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - if (a->x != 0.0f) { - result->x = 1.0f / a->x; - } else { - result->x = 0.0f; - } - if (a->y != 0.0f) { - result->y = 1.0f / a->y; - } else { - result->y = 0.0f; - } - if (a->z != 0.0f) { - result->z = 1.0f / a->z; - } else { - result->z = 0.0f; - } - result->w = 1.0f; + return (struct vec3 *)vec3_cross((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_inverse(struct vec a) +struct vec3 *psvec3_normalize(struct vec3 *result, struct vec3 *v0) { - struct vec result; - pvector3_inverse(&a, &result); - return result; + return (struct vec3 *)vec3_normalize((mfloat_t *)result, (mfloat_t *)v0); } -void pvector3_abs(struct vec *a, struct vec *result) +mfloat_t psvec3_dot(struct vec3 *v0, struct vec3 *v1) { - result->x = fabsf(a->x); - result->y = fabsf(a->y); - result->z = fabsf(a->z); - result->w = 1.0f; + return vec3_dot((mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_abs(struct vec a) +struct vec3 *psvec3_project(struct vec3 *result, struct vec3 *v0, struct vec3 *v1) { - struct vec result; - pvector3_abs(&a, &result); - return result; + return (struct vec3 *)vec3_project((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector3_floor(struct vec *a, struct vec *result) +struct vec3 *psvec3_slide(struct vec3 *result, struct vec3 *v0, struct vec3 *normal) { - result->x = floorf(a->x); - result->y = floorf(a->y); - result->z = floorf(a->z); - result->w = 1.0f; + return (struct vec3 *)vec3_slide((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)normal); } -MATHC_EXTERN_INLINE struct vec vector3_floor(struct vec a) +struct vec3 *psvec3_reflect(struct vec3 *result, struct vec3 *v0, struct vec3 *normal) { - struct vec result; - pvector3_floor(&a, &result); - return result; + return (struct vec3 *)vec3_reflect((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)normal); } -void pvector3_ceil(struct vec *a, struct vec *result) +struct vec3 *psvec3_rotate(struct vec3 *result, struct vec3 *v0, struct vec3 *ra, mfloat_t f) { - result->x = ceilf(a->x); - result->y = ceilf(a->y); - result->z = ceilf(a->z); - result->w = 1.0f; + return (struct vec3 *)vec3_lerp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)ra, f); } -MATHC_EXTERN_INLINE struct vec vector3_ceil(struct vec a) +struct vec3 *psvec3_lerp(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, mfloat_t f) { - struct vec result; - pvector3_ceil(&a, &result); - return result; + return (struct vec3 *)vec3_lerp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, f); } -void pvector3_round(struct vec *a, struct vec *result) +struct vec3 *psvec3_bezier3(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2, mfloat_t f) { - result->x = roundf(a->x); - result->y = roundf(a->y); - result->z = roundf(a->z); - result->w = 1.0f; + return (struct vec3 *)vec3_bezier3((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2, f); } -MATHC_EXTERN_INLINE struct vec vector3_round(struct vec a) +struct vec3 *psvec3_bezier4(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2, struct vec3 *v3, mfloat_t f) { - struct vec result; - pvector3_round(&a, &result); - return result; + return (struct vec3 *)vec3_bezier4((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2, (mfloat_t *)v3, f); } -void pvector3_max(struct vec *a, struct vec *b, struct vec *result) +mfloat_t psvec3_length(struct vec3 *v0) { - result->x = fmaxf(a->x, b->x); - result->y = fmaxf(a->y, b->y); - result->z = fmaxf(a->z, b->z); - result->w = 1.0f; + return vec3_length((mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec vector3_max(struct vec a, struct vec b) +mfloat_t psvec3_length_squared(struct vec3 *v0) { - struct vec result; - pvector3_max(&a, &b, &result); - return result; + return vec3_length_squared((mfloat_t *)v0); } -void pvector3_min(struct vec *a, struct vec *b, struct vec *result) +mfloat_t psvec3_distance(struct vec3 *v0, struct vec3 *v1) { - result->x = fminf(a->x, b->x); - result->y = fminf(a->y, b->y); - result->z = fminf(a->z, b->z); - result->w = 1.0f; + return vec3_distance((mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_min(struct vec a, struct vec b) +mfloat_t psvec3_distance_squared(struct vec3 *v0, struct vec3 *v1) { - struct vec result; - pvector3_min(&a, &b, &result); - return result; + return vec3_distance_squared((mfloat_t *)v0, (mfloat_t *)v1); } -float pvector3_dot(struct vec *a, struct vec *b) +bool psvec4_is_zero(struct vec4 *v0) { - return a->x * b->x + a->y * b->y + a->z * b->z; + return vec4_is_zero((mfloat_t *)v0); } -MATHC_EXTERN_INLINE float vector3_dot(struct vec a, struct vec b) +bool psvec4_is_equal(struct vec4 *v0, struct vec4 *v1) { - return pvector3_dot(&a, &b); + return vec4_is_equal((mfloat_t *)v0, (mfloat_t *)v1); } -void pvector3_cross(struct vec *a, struct vec *b, struct vec *result) +struct vec4 *psvec4(struct vec4 *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) { - result->x = a->y * b->z - a->z * b->y; - result->y = a->z * b->x - a->x * b->z; - result->z = a->x * b->y - a->y * b->x; - result->w = 1.0f; + return (struct vec4 *)vec4((mfloat_t *)result, x, y, z, w); } -MATHC_EXTERN_INLINE struct vec vector3_cross(struct vec a, struct vec b) +struct vec4 *psvec4_assign(struct vec4 *result, struct vec4 *v0) { - struct vec result; - pvector3_cross(&a, &b, &result); - return result; + return (struct vec4 *)vec4_assign((mfloat_t *)result, (mfloat_t *)v0); } -float pvector3_length_squared(struct vec *a) +#if defined(MATHC_USE_INT) +struct vec4 *psvec4_assign_vec4i(struct vec4 *result, struct vec4i *v0) { - return a->x * a->x + a->y * a->y + a->z * a->z; + return (struct vec4 *)vec4_assign_vec4i((mfloat_t *)result, (mint_t *)v0); } +#endif -MATHC_EXTERN_INLINE float vector3_length_squared(struct vec a) +struct vec4 *psvec4_zero(struct vec4 *result) { - return pvector3_length_squared(&a); + return (struct vec4 *)vec4_zero((mfloat_t *)result); } -float pvector3_length(struct vec *a) +struct vec4 *psvec4_one(struct vec4 *result) { - return sqrtf(a->x * a->x + a->y * a->y + a->z * a->z); + return (struct vec4 *)vec4_one((mfloat_t *)result); } -MATHC_EXTERN_INLINE float vector3_length(struct vec a) +struct vec4 *psvec4_sign(struct vec4 *result, struct vec4 *v0) { - return pvector3_length(&a); + return (struct vec4 *)vec4_sign((mfloat_t *)result, (mfloat_t *)v0); } -void pvector3_normalize(struct vec *a, struct vec *result) +struct vec4 *psvec4_add(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - float length = a->x * a->x + a->y * a->y + a->z * a->z; - if (length != 0.0f) { - length = sqrtf(length); - result->x = a->x / length; - result->y = a->y / length; - result->z = a->z / length; - } else { - result->x = 0.0f; - result->y = 0.0f; - result->z = 0.0f; - } - result->w = 1.0f; + return (struct vec4 *)vec4_add((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_normalize(struct vec a) +struct vec4 *psvec4_add_f(struct vec4 *result, struct vec4 *v0, mfloat_t f) { - struct vec result; - pvector3_normalize(&a, &result); - return result; + return (struct vec4 *)vec4_add_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector3_slide(struct vec *a, struct vec *normal, struct vec *result) +struct vec4 *psvec4_subtract(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - float d = pvector3_dot(a, normal); - result->x = a->x - normal->x * d; - result->y = a->y - normal->y * d; - result->y = a->z - normal->z * d; - result->w = 1.0f; + return (struct vec4 *)vec4_subtract((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_slide(struct vec a, struct vec normal) +struct vec4 *psvec4_subtract_f(struct vec4 *result, struct vec4 *v0, mfloat_t f) { - struct vec result; - pvector3_slide(&a, &normal, &result); - return result; + return (struct vec4 *)vec4_subtract_f((mfloat_t *)result, (mfloat_t *)v0, f); } -void pvector3_reflect(struct vec *a, struct vec *normal, struct vec *result) +struct vec4 *psvec4_multiply(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - float d = 2.0f * pvector3_dot(a, normal); - result->x = a->x - normal->x * d; - result->y = a->y - normal->y * d; - result->z = a->z - normal->z * d; - result->w = 1.0f; + return (struct vec4 *)vec4_multiply((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec vector3_reflect(struct vec a, struct vec normal) +struct vec4 *psvec4_multiply_f(struct vec4 *result, struct vec4 *v0, mfloat_t f) { - struct vec result; - pvector3_reflect(&a, &normal, &result); - return result; + return (struct vec4 *)vec4_multiply_f((mfloat_t *)result, (mfloat_t *)v0, f); } -float pvector3_distance_to(struct vec *a, struct vec *b) +struct vec4 *psvec4_multiply_mat4(struct vec4 *result, struct vec4 *v0, struct mat4 *m0) { - return sqrtf((a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b->y) + (a->z - b->z) * (a->z - b->z)); + return (struct vec4 *)vec4_multiply_mat4((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE float vector3_distance_to(struct vec a, struct vec b) +struct vec4 *psvec4_divide(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - return pvector3_distance_to(&a, &b); + return (struct vec4 *)vec4_divide((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -float pvector3_distance_squared_to(struct vec *a, struct vec *b) +struct vec4 *psvec4_divide_f(struct vec4 *result, struct vec4 *v0, mfloat_t f) { - return (a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b->y) + (a->z - b->z) * (a->z - b->z); + return (struct vec4 *)vec4_divide_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE float vector3_distance_squared_to(struct vec a, struct vec b) +struct vec4 *psvec4_snap(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - return pvector3_distance_squared_to(&a, &b); + return (struct vec4 *)vec4_snap((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pvector3_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result) +struct vec4 *psvec4_snap_f(struct vec4 *result, struct vec4 *v0, mfloat_t f) { - result->x = a->x + (b->x - a->x) * p; - result->y = a->y + (b->y - a->y) * p; - result->z = a->z + (b->z - a->z) * p; - result->w = 1.0f; + return (struct vec4 *)vec4_snap_f((mfloat_t *)result, (mfloat_t *)v0, f); } -MATHC_EXTERN_INLINE struct vec vector3_linear_interpolation(struct vec a, struct vec b, float p) +struct vec4 *psvec4_negative(struct vec4 *result, struct vec4 *v0) { - struct vec result; - pvector3_linear_interpolation(&a, &b, p, &result); - return result; + return (struct vec4 *)vec4_negative((mfloat_t *)result, (mfloat_t *)v0); } -/* Quaternion */ -void to_pquaternion(float x, float y, float z, float w, struct vec *result) +struct vec4 *psvec4_abs(struct vec4 *result, struct vec4 *v0) { - result->x = x; - result->y = y; - result->z = z; - result->w = w; + return (struct vec4 *)vec4_abs((mfloat_t *)result, (mfloat_t *)v0); } -struct vec to_quaternion(float x, float y, float z, float w) +struct vec4 *psvec4_floor(struct vec4 *result, struct vec4 *v0) { - struct vec result; - to_pquaternion(x, y, z, w, &result); - return result; + return (struct vec4 *)vec4_floor((mfloat_t *)result, (mfloat_t *)v0); } -void pquaternion_add(struct vec *a, struct vec *b, struct vec *result) +struct vec4 *psvec4_ceil(struct vec4 *result, struct vec4 *v0) { - result->x = a->x + b->x; - result->y = a->y + b->y; - result->z = a->z + b->z; - result->w = a->w + b->w; + return (struct vec4 *)vec4_ceil((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec quaternion_add(struct vec a, struct vec b) +struct vec4 *psvec4_round(struct vec4 *result, struct vec4 *v0) { - struct vec result; - pquaternion_add(&a, &b, &result); - return result; + return (struct vec4 *)vec4_round((mfloat_t *)result, (mfloat_t *)v0); } -void pquaternion_subtract(struct vec *a, struct vec *b, struct vec *result) +struct vec4 *psvec4_max(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - result->x = a->x - b->x; - result->y = a->y - b->y; - result->y = a->z - b->z; - result->w = a->w - b->w; + return (struct vec4 *)vec4_max((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec quaternion_subtract(struct vec a, struct vec b) +struct vec4 *psvec4_min(struct vec4 *result, struct vec4 *v0, struct vec4 *v1) { - struct vec result; - pquaternion_subtract(&a, &b, &result); - return result; + return (struct vec4 *)vec4_min((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -void pquaternion_scale(struct vec *a, float scale, struct vec *result) +struct vec4 *psvec4_clamp(struct vec4 *result, struct vec4 *v0, struct vec4 *v1, struct vec4 *v2) { - result->x = a->x * scale; - result->y = a->y * scale; - result->z = a->z * scale; - result->w = a->w * scale; + return (struct vec4 *)vec4_clamp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, (mfloat_t *)v2); } -MATHC_EXTERN_INLINE struct vec quaternion_scale(struct vec a, float scale) +struct vec4 *psvec4_normalize(struct vec4 *result, struct vec4 *v0) { - struct vec result; - pquaternion_scale(&a, scale, &result); - return result; + return (struct vec4 *)vec4_normalize((mfloat_t *)result, (mfloat_t *)v0); } -void pquaternion_multiply(struct vec *a, struct vec *b, struct vec *result) +struct vec4 *psvec4_lerp(struct vec4 *result, struct vec4 *v0, struct vec4 *v1, mfloat_t f) { - result->x = a->w * b->x + a->x * b->w + a->y * b->z - a->z * b->y; - result->y = a->w * b->y + a->y * b->w + a->z * b->x - a->x * b->z; - result->z = a->w * b->z + a->z * b->w + a->x * b->y - a->y * b->x; - result->w = a->w * b->w - a->x * b->x - a->y * b->y - a->z * b->z; + return (struct vec4 *)vec4_lerp((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1, f); } -MATHC_EXTERN_INLINE struct vec quaternion_multiply(struct vec a, struct vec b) +bool psquat_is_zero(struct quat *q0) { - struct vec result; - pquaternion_multiply(&a, &b, &result); - return result; + return quat_is_zero((mfloat_t *)q0); } -void pquaternion_divide(struct vec *a, struct vec *b, struct vec *result) +bool psquat_is_equal(struct quat *q0, struct quat *q1) { - float x = a->x; - float y = a->y; - float z = a->z; - float w = a->w; - float n1 = b->x * b->x + b->y * b->y + b->z * b->z + b->w * b->w; - float n2 = 1.0f / n1; - float n3 = -b->x * n2; - float n4 = -b->y * n2; - float n5 = -b->z * n2; - float n6 = b->w * n2; - float n7 = y * n5 - z * n4; - float n8 = z * n3 - x * n5; - float n9 = x * n4 - y * n3; - float n10 = x * n3 + y * n4 + z * n5; - result->x = x * n6 + n3 * w + n7; - result->y = y * n6 + n4 * w + n8; - result->z = z * n6 + n5 * w + n9; - result->w = w * n6 - n10; + return quat_is_equal((mfloat_t *)q0, (mfloat_t *)q1); } -MATHC_EXTERN_INLINE struct vec quaternion_divide(struct vec a, struct vec b) +struct quat *psquat(struct quat *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w) { - struct vec result; - pquaternion_divide(&a, &b, &result); - return result; + return (struct quat *)quat((mfloat_t *)result, x, y, z, w); } -void pquaternion_negative(struct vec *a, struct vec *result) +struct quat *psquat_assign(struct quat *result, struct quat *q0) { - result->x = -a->x; - result->y = -a->y; - result->z = -a->z; - result->w = -a->w; + return (struct quat *)quat_assign((mfloat_t *)result, (mfloat_t *)q0); } -MATHC_EXTERN_INLINE struct vec quaternion_negative(struct vec a) +struct quat *psquat_zero(struct quat *result) { - struct vec result; - pquaternion_negative(&a, &result); - return result; + return (struct quat *)quat_zero((mfloat_t *)result); } -void pquaternion_conjugate(struct vec *a, struct vec *result) +struct quat *psquat_null(struct quat *result) { - result->x = -a->x; - result->y = -a->y; - result->z = -a->z; - result->w = a->w; + return (struct quat *)quat_null((mfloat_t *)result); } -MATHC_EXTERN_INLINE struct vec quaternion_conjugate(struct vec a) +struct quat *psquat_multiply(struct quat *result, struct quat *q0, struct quat *q1) { - struct vec result; - pquaternion_conjugate(&a, &result); - return result; + return (struct quat *)quat_multiply((mfloat_t *)result, (mfloat_t *)q0, (mfloat_t *)q1); } -void pquaternion_inverse(struct vec *a, struct vec *result) +struct quat *psquat_multiply_f(struct quat *result, struct quat *q0, mfloat_t f) { - float n1 = sqrtf(a->x * a->x + a->y * a->y + a->z * a->z + a->w * a->w); - float n2 = 1.0f / n1; - result->x = -a->x * n2; - result->y = -a->y * n2; - result->z = -a->z * n2; - result->w = a->w * n2; + return (struct quat *)quat_multiply_f((mfloat_t *)result, (mfloat_t *)q0, f); } -MATHC_EXTERN_INLINE struct vec quaternion_inverse(struct vec a) +struct quat *psquat_divide(struct quat *result, struct quat *q0, struct quat *q1) { - struct vec result; - pquaternion_inverse(&a, &result); - return result; + return (struct quat *)quat_divide((mfloat_t *)result, (mfloat_t *)q0, (mfloat_t *)q1); } -void pquaternion_abs(struct vec *a, struct vec *result) +struct quat *psquat_divide_f(struct quat *result, struct quat *q0, mfloat_t f) { - result->x = fabsf(a->x); - result->y = fabsf(a->y); - result->z = fabsf(a->z); - result->w = fabsf(a->w); + return (struct quat *)quat_divide_f((mfloat_t *)result, (mfloat_t *)q0, f); } -MATHC_EXTERN_INLINE struct vec quaternion_abs(struct vec a) +struct quat *psquat_negative(struct quat *result, struct quat *q0) { - struct vec result; - pquaternion_abs(&a, &result); - return result; + return (struct quat *)quat_negative((mfloat_t *)result, (mfloat_t *)q0); } -void pquaternion_floor(struct vec *a, struct vec *result) +struct quat *psquat_conjugate(struct quat *result, struct quat *q0) { - result->x = floorf(a->x); - result->y = floorf(a->y); - result->z = floorf(a->z); - result->w = floorf(a->w); + return (struct quat *)quat_conjugate((mfloat_t *)result, (mfloat_t *)q0); } -MATHC_EXTERN_INLINE struct vec quaternion_floor(struct vec a) +struct quat *psquat_inverse(struct quat *result, struct quat *q0) { - struct vec result; - pquaternion_floor(&a, &result); - return result; + return (struct quat *)quat_inverse((mfloat_t *)result, (mfloat_t *)q0); } -void pquaternion_ceil(struct vec *a, struct vec *result) +struct quat *psquat_normalize(struct quat *result, struct quat *q0) { - result->x = ceilf(a->x); - result->y = ceilf(a->y); - result->z = ceilf(a->z); - result->w = ceilf(a->w); + return (struct quat *)quat_normalize((mfloat_t *)result, (mfloat_t *)q0); } -MATHC_EXTERN_INLINE struct vec quaternion_ceil(struct vec a) +mfloat_t psquat_dot(struct quat *q0, struct quat *q1) { - struct vec result; - pquaternion_ceil(&a, &result); - return result; + return quat_dot((mfloat_t *)q0, (mfloat_t *)q1); } -void pquaternion_round(struct vec *a, struct vec *result) +struct quat *psquat_power(struct quat *result, struct quat *q0, mfloat_t exponent) { - result->x = roundf(a->x); - result->y = roundf(a->y); - result->z = roundf(a->z); - result->w = roundf(a->w); + return (struct quat *)quat_power((mfloat_t *)result, (mfloat_t *)q0, exponent); } -MATHC_EXTERN_INLINE struct vec quaternion_round(struct vec a) +struct quat *psquat_from_axis_angle(struct quat *result, struct vec3 *v0, mfloat_t angle) { - struct vec result; - pquaternion_round(&a, &result); - return result; + return (struct quat *)quat_from_axis_angle((mfloat_t *)result, (mfloat_t *)v0, angle); } -void pquaternion_max(struct vec *a, struct vec *b, struct vec *result) +struct quat *psquat_from_vec3(struct quat *result, struct vec3 *v0, struct vec3 *v1) { - result->x = fmaxf(a->x, b->x); - result->y = fmaxf(a->y, b->y); - result->z = fmaxf(a->z, b->z); - result->w = fmaxf(a->w, b->w); + return (struct quat *)quat_from_vec3((mfloat_t *)result, (mfloat_t *)v0, (mfloat_t *)v1); } -MATHC_EXTERN_INLINE struct vec quaternion_max(struct vec a, struct vec b) +struct quat *psquat_from_mat4(struct quat *result, struct mat4 *m0) { - struct vec result; - pquaternion_max(&a, &b, &result); - return result; + return (struct quat *)quat_from_mat4((mfloat_t *)result, (mfloat_t *)m0); } -void pquaternion_min(struct vec *a, struct vec *b, struct vec *result) +struct quat *psquat_lerp(struct quat *result, struct quat *q0, struct quat *q1, mfloat_t f) { - result->x = fminf(a->x, b->x); - result->y = fminf(a->y, b->y); - result->z = fminf(a->z, b->z); - result->w = fminf(a->w, b->w); + return (struct quat *)quat_lerp((mfloat_t *)result, (mfloat_t *)q0, (mfloat_t *)q1, f); } -MATHC_EXTERN_INLINE struct vec quaternion_min(struct vec a, struct vec b) +struct quat *psquat_slerp(struct quat *result, struct quat *q0, struct quat *q1, mfloat_t f) { - struct vec result; - pquaternion_min(&a, &b, &result); - return result; + return (struct quat *)quat_slerp((mfloat_t *)result, (mfloat_t *)q0, (mfloat_t *)q1, f); } -float pquaternion_dot(struct vec *a, struct vec *b) +mfloat_t psquat_length(struct quat *q0) { - return a->x * b->x + a->y * b->y + a->z * b->z + a->w * b->w; + return quat_length((mfloat_t *)q0); } -MATHC_EXTERN_INLINE float quaternion_dot(struct vec a, struct vec b) +mfloat_t psquat_length_squared(struct quat *q0) { - return pquaternion_dot(&a, &b); + return quat_length_squared((mfloat_t *)q0); } -float pquaternion_angle(struct vec *a, struct vec *b) +mfloat_t psquat_angle(struct quat *q0, struct quat *q1) { - float s = sqrtf(pquaternion_length_squared(a) * pquaternion_length_squared(b)); - return acosf(pquaternion_dot(a, b) / s); + return quat_angle((mfloat_t *)q0, (mfloat_t *)q1); } -MATHC_EXTERN_INLINE float quaternion_angle(struct vec a, struct vec b) +struct mat2 *psmat2(struct mat2 *result, mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22) { - return pquaternion_angle(&a, &b); + return (struct mat2 *)mat2((mfloat_t *)result, m11, m12, m21, m22); } -float pquaternion_length_squared(struct vec *a) +struct mat2 *psmat2_zero(struct mat2 *result) { - return a->x * a->x + a->y * a->y + a->z * a->z + a->w * a->w; + return (struct mat2 *)mat2_zero((mfloat_t *)result); } -MATHC_EXTERN_INLINE float quaternion_length_squared(struct vec a) +struct mat2 *psmat2_identity(struct mat2 *result) { - return pquaternion_length_squared(&a); + return (struct mat2 *)mat2_identity((mfloat_t *)result); } -float pquaternion_length(struct vec *a) +mfloat_t psmat2_determinant(struct mat2 *m0) { - return sqrtf(a->x * a->x + a->y * a->y + a->z * a->z + a->w * a->w); + return mat2_determinant((mfloat_t *)m0); } -MATHC_EXTERN_INLINE float quaternion_length(struct vec a) +struct mat2 *psmat2_assign(struct mat2 *result, struct mat2 *m0) { - return pquaternion_length(&a); + return (struct mat2 *)mat2_assign((mfloat_t *)result, (mfloat_t *)m0); } -void pquaternion_normalize(struct vec *a, struct vec *result) +struct mat2 *psmat2_negative(struct mat2 *result, struct mat2 *m0) { - float n = 1.0f / sqrtf(a->x * a->x + a->y * a->y + a->z * a->z + a->w * a->w); - result->x = a->x * n; - result->y = a->y * n; - result->z = a->z * n; - result->w = a->w * n; + return (struct mat2 *)mat2_negative((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct vec quaternion_normalize(struct vec a) +struct mat2 *psmat2_transpose(struct mat2 *result, struct mat2 *m0) { - struct vec result; - pquaternion_normalize(&a, &result); - return result; + return (struct mat2 *)mat2_transpose((mfloat_t *)result, (mfloat_t *)m0); } -void pquaternion_power(struct vec *a, float exponent, struct vec *result) +struct mat2 *psmat2_cofactor(struct mat2 *result, struct mat2 *m0) { - if (fabsf(a->w) < 0.9999f) { - float alpha = acosf(a->w); - float new_alpha = alpha * exponent; - float s = sinf(new_alpha) / sinf(alpha); - result->x = result->x * s; - result->y = result->y * s; - result->z = result->z * s; - result->w = cosf(new_alpha); - } else { - result->x = a->x; - result->y = a->y; - result->z = a->z; - result->w = a->w; - } + return (struct mat2 *)mat2_cofactor((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct vec quaternion_power(struct vec a, float exponent) +struct mat2 *psmat2_adjugate(struct mat2 *result, struct mat2 *m0) { - struct vec result; - pquaternion_power(&a, exponent, &result); - return result; + return (struct mat2 *)mat2_adjugate((mfloat_t *)result, (mfloat_t *)m0); } -void pquaternion_from_axis_angle(struct vec *a, float angle, struct vec *result) +struct mat2 *psmat2_multiply(struct mat2 *result, struct mat2 *m0, struct mat2 *m1) { - float half = angle * 0.5f; - float s = sinf(half); - result->x = a->x * s; - result->y = a->y * s; - result->z = a->z * s; - result->w = cosf(half); + return (struct mat2 *)mat2_multiply((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1); } -MATHC_EXTERN_INLINE struct vec quaternion_from_axis_angle(struct vec a, float angle) +struct mat2 *psmat2_multiply_f(struct mat2 *result, struct mat2 *m0, mfloat_t f) { - struct vec result; - pquaternion_from_axis_angle(&a, angle, &result); - return result; + return (struct mat2 *)mat2_multiply_f((mfloat_t *)result, (mfloat_t *)m0, f); } -void pquaternion_to_axis_angle(struct vec *a, struct vec *result) +struct mat2 *psmat2_inverse(struct mat2 *result, struct mat2 *m0) { - double sa; - struct vec tmp; - pquaternion_normalize(a, &tmp); - sa = sqrt(1.0f - tmp.w * tmp.w); - if (fabs(sa) <= FLT_EPSILON) { - sa = 1.0f; - } - result->x = tmp.x / sa; - result->y = tmp.y / sa; - result->z = tmp.z / sa; - result->w = acosf(tmp.w) * 2.0f; + return (struct mat2 *)mat2_inverse((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct vec quaternion_to_axis_angle(struct vec a) +struct mat2 *psmat2_scaling(struct mat2 *result, struct vec2 *v0) { - struct vec result; - pquaternion_to_axis_angle(&a, &result); - return result; + return (struct mat2 *)mat2_scaling((mfloat_t *)result, (mfloat_t *)v0); } -void pquaternion_rotation_matrix(struct mat *m, struct vec *result) +struct mat2 *psmat2_scale(struct mat2 *result, struct mat2 *m0, struct vec2 *v0) { - float sr; - float half; - float scale = m->m11 + m->m22 + m->m33; - if (scale > 0.0f) { - sr = sqrtf(scale + 1.0f); - result->w = sr * 0.5f; - sr = 0.5f / sr; - result->x = (m->m23 - m->m32) * sr; - result->y = (m->m31 - m->m13) * sr; - result->z = (m->m12 - m->m21) * sr; - } else if ((m->m11 >= m->m22) && (m->m11 >= m->m33)) { - sr = sqrtf(1.0f + m->m11 - m->m22 - m->m33); - half = 0.5f / sr; - result->x = 0.5f * sr; - result->y = (m->m12 + m->m21) * half; - result->z = (m->m13 + m->m31) * half; - result->w = (m->m23 - m->m32) * half; - } else if (m->m22 > m->m33) { - sr = sqrtf(1.0f + m->m22 - m->m11 - m->m33); - half = 0.5f / sr; - result->x = (m->m21 + m->m12) * half; - result->y = 0.5f * sr; - result->z = (m->m32 + m->m23) * half; - result->w = (m->m31 - m->m13) * half; - } else { - sr = sqrtf(1.0f + m->m33 - m->m11 - m->m22); - half = 0.5f / sr; - result->x = (m->m31 + m->m13) * half; - result->y = (m->m32 + m->m23) * half; - result->z = 0.5f * sr; - result->w = (m->m12 - m->m21) * half; - } + return (struct mat2 *)mat2_scale((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct vec quaternion_rotation_matrix(struct mat m) +struct mat2 *psmat2_rotation_z(struct mat2 *result, mfloat_t f) { - struct vec result; - pquaternion_rotation_matrix(&m, &result); - return result; + return (struct mat2 *)mat2_rotation_z((mfloat_t *)result, f); } -void pquaternion_yaw_pitch_roll(float yaw, float pitch, float roll, struct vec *result) +struct mat2 *psmat2_lerp(struct mat2 *result, struct mat2 *m0, struct mat2 *m1, mfloat_t f) { - float half_roll = roll * 0.5f; - float half_pitch = pitch * 0.5f; - float half_yaw = yaw * 0.5f; - float sin_roll = sinf(half_roll); - float cos_roll = cosf(half_roll); - float sin_pitch = sinf(half_pitch); - float cos_pitch = cosf(half_pitch); - float sin_yaw = sinf(half_yaw); - float cos_yaw = cosf(half_yaw); - result->x = (cos_yaw * sin_pitch * cos_roll) + (sin_yaw * cos_pitch * sin_roll); - result->y = (sin_yaw * cos_pitch * cos_roll) - (cos_yaw * sin_pitch * sin_roll); - result->z = (cos_yaw * cos_pitch * sin_roll) - (sin_yaw * sin_pitch * cos_roll); - result->w = (cos_yaw * cos_pitch * cos_roll) + (sin_yaw * sin_pitch * sin_roll); + return (struct mat2 *)mat2_lerp((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1, f); } -MATHC_EXTERN_INLINE struct vec quaternion_yaw_pitch_roll(float yaw, float pitch, float roll) +struct mat3 *psmat3(struct mat3 *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33) { - struct vec result; - pquaternion_yaw_pitch_roll(yaw, pitch, roll, &result); - return result; + return (struct mat3 *)mat3((mfloat_t *)result, m11, m12, m13, m21, m22, m23, m31, m32, m33); } -void pquaternion_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result) +struct mat3 *psmat3_zero(struct mat3 *result) { - result->x = a->x + (b->x - a->x) * p; - result->y = a->y + (b->y - a->y) * p; - result->z = a->z + (b->z - a->z) * p; - result->w = a->w + (b->w - a->w) * p; + return (struct mat3 *)mat3_zero((mfloat_t *)result); } -MATHC_EXTERN_INLINE struct vec quaternion_linear_interpolation(struct vec a, struct vec b, float p) +struct mat3 *psmat3_identity(struct mat3 *result) { - struct vec result; - pquaternion_linear_interpolation(&a, &b, p, &result); - return result; + return (struct mat3 *)mat3_identity((mfloat_t *)result); } -void pquaternion_spherical_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result) +mfloat_t psmat3_determinant(struct mat3 *m0) { - struct vec tmp_a = *a; - struct vec tmp_b = *b; - float cos_theta = pquaternion_dot(a, b); - float k0; - float k1; - /* Take shortest arc */ - if (cos_theta < 0.0f) { - pquaternion_negative(&tmp_b, &tmp_b); - cos_theta = -cos_theta; - } - /* Check if quaternions are close */ - if (cos_theta > 0.9999f) { - /* Use linear interpolation */ - k0 = 1.0f - p; - k1 = p; - } else { - float theta = acosf(cos_theta); - float sin_theta = sinf(theta); - k0 = sinf((1.f - p) * theta) / sin_theta; - k1 = sinf(p * theta) / sin_theta; - } - result->x = tmp_a.x * k0 + tmp_b.x * k1; - result->y = tmp_a.y * k0 + tmp_b.y * k1; - result->z = tmp_a.z * k0 + tmp_b.z * k1; - result->w = tmp_a.w * k0 + tmp_b.w * k1; + return mat3_determinant((mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct vec quaternion_spherical_linear_interpolation(struct vec a, struct vec b, float p) +struct mat3 *psmat3_assign(struct mat3 *result, struct mat3 *m0) { - struct vec result; - pquaternion_spherical_linear_interpolation(&a, &b, p, &result); - return result; + return (struct mat3 *)mat3_assign((mfloat_t *)result, (mfloat_t *)m0); } -/* Matrix */ -void pmatrix_identity(struct mat *result) +struct mat3 *psmat3_negative(struct mat3 *result, struct mat3 *m0) { - result->m11 = 1.0f; - result->m12 = 0.0f; - result->m13 = 0.0f; - result->m14 = 0.0f; - result->m21 = 0.0f; - result->m22 = 1.0f; - result->m23 = 0.0f; - result->m24 = 0.0f; - result->m31 = 0.0f; - result->m32 = 0.0f; - result->m33 = 1.0f; - result->m34 = 0.0f; - result->m41 = 0.0f; - result->m42 = 0.0f; - result->m43 = 0.0f; - result->m44 = 1.0f; + return (struct mat3 *)mat3_negative((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct mat matrix_identity(void) +struct mat3 *psmat3_transpose(struct mat3 *result, struct mat3 *m0) { - struct mat result; - pmatrix_identity(&result); - return result; + return (struct mat3 *)mat3_transpose((mfloat_t *)result, (mfloat_t *)m0); } -void pmatrix_ortho(float l, float r, float b, float t, float n, float f, struct mat *result) +struct mat3 *psmat3_cofactor(struct mat3 *result, struct mat3 *m0) { - pmatrix_identity(result); - result->m11 = 2.0f / (r - l); - result->m22 = 2.0f / (b - t); - result->m33 = 1.0f / (n - f); - result->m41 = (l + r) / (l - r); - result->m42 = (t + b) / (b - t); - result->m43 = n / (n - f); + return (struct mat3 *)mat3_cofactor((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct mat matrix_ortho(float l, float r, float b, float t, float n, float f) +struct mat3 *psmat3_multiply(struct mat3 *result, struct mat3 *m0, struct mat3 *m1) { - struct mat result; - pmatrix_ortho(l, r, b, t, n, f, &result); - return result; + return (struct mat3 *)mat3_multiply((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1); } -void pmatrix_perspective(float y_fov, float aspect, float n, float f, struct mat *result) +struct mat3 *psmat3_multiply_f(struct mat3 *result, struct mat3 *m0, mfloat_t f) { - pmatrix_identity(result); - /* Right-handed */ - float a = 1.0f / tanf(y_fov * 0.5f); - result->m11 = a / aspect; - result->m22 = a; - result->m33 = f / (n - f); - result->m34 = -1.0f; - result->m43 = (n * f) / (n - f); + return (struct mat3 *)mat3_multiply_f((mfloat_t *)result, (mfloat_t *)m0, f); } -MATHC_EXTERN_INLINE struct mat matrix_perspective(float y_fov, float aspect, float n, float f) +struct mat3 *psmat3_inverse(struct mat3 *result, struct mat3 *m0) { - struct mat result; - pmatrix_perspective(y_fov, aspect, n, f, &result); - return result; + return (struct mat3 *)mat3_inverse((mfloat_t *)result, (mfloat_t *)m0); } -void pmatrix_rotation_x(float angle, struct mat *result) +struct mat3 *psmat3_scaling(struct mat3 *result, struct vec3 *v0) { - pmatrix_identity(result); - float c = cosf(angle); - float s = sinf(angle); - result->m22 = c; - result->m23 = -s; - result->m32 = s; - result->m33 = c; + return (struct mat3 *)mat3_scaling((mfloat_t *)result, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct mat matrix_rotation_x(float angle) +struct mat3 *psmat3_scale(struct mat3 *result, struct mat3 *m0, struct vec3 *v0) { - struct mat result; - pmatrix_rotation_x(angle, &result); - return result; + return (struct mat3 *)mat3_scale((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -void pmatrix_rotation_y(float angle, struct mat *result) +struct mat3 *psmat3_rotation_x(struct mat3 *result, mfloat_t f) { - pmatrix_identity(result); - float c = cosf(angle); - float s = sinf(angle); - result->m11 = c; - result->m13 = s; - result->m31 = -s; - result->m33 = c; + return (struct mat3 *)mat3_rotation_x((mfloat_t *)result, f); } -MATHC_EXTERN_INLINE struct mat matrix_rotation_y(float angle) +struct mat3 *psmat3_rotation_y(struct mat3 *result, mfloat_t f) { - struct mat result; - pmatrix_rotation_y(angle, &result); - return result; + return (struct mat3 *)mat3_rotation_y((mfloat_t *)result, f); } -void pmatrix_rotation_z(float angle, struct mat *result) +struct mat3 *psmat3_rotation_z(struct mat3 *result, mfloat_t f) { - pmatrix_identity(result); - float c = cosf(angle); - float s = sinf(angle); - result->m11 = c; - result->m12 = -s; - result->m21 = s; - result->m22 = c; + return (struct mat3 *)mat3_rotation_z((mfloat_t *)result, f); } -MATHC_EXTERN_INLINE struct mat matrix_rotation_z(float angle) +struct mat3 *psmat3_rotation_axis(struct mat3 *result, struct vec3 *v0, mfloat_t f) { - struct mat result; - pmatrix_rotation_z(angle, &result); - return result; + return (struct mat3 *)mat3_rotation_axis((mfloat_t *)result, (mfloat_t *)v0, f); } -void pmatrix_rotation_axis(struct vec *a, float angle, struct mat *result) +struct mat3 *psmat3_rotation_quat(struct mat3 *result, struct quat *q0) { - pmatrix_identity(result); - float c = cosf(angle); - float s = sinf(angle); - float n1 = a->x * a->x; - float n2 = a->y * a->y; - float n3 = a->z * a->z; - float n4 = a->x * a->y; - float n5 = a->x * a->z; - float n6 = a->y * a->z; - result->m11 = n1 + (c * (1.0f - n1)); - result->m12 = (n4 - (c * n4)) + (s * a->z); - result->m13 = (n5 - (c * n5)) - (s * a->y); - result->m21 = (n4 - (c * n4)) - (s * a->z); - result->m22 = n2 + (c * (1.0f - n2)); - result->m23 = (n6 - (c * n6)) + (s * a->x); - result->m31 = (n5 - (c * n5)) + (s * a->y); - result->m32 = (n6 - (c * n6)) - (s * a->x); - result->m33 = n3 + (c * (1.0f - n3)); + return (struct mat3 *)mat3_rotation_quat((mfloat_t *)result, (mfloat_t *)q0); } -MATHC_EXTERN_INLINE struct mat matrix_rotation_axis(struct vec a, float angle) +struct mat3 *psmat3_lerp(struct mat3 *result, struct mat3 *m0, struct mat3 *m1, mfloat_t f) { - struct mat result; - pmatrix_rotation_axis(&a, angle, &result); - return result; + return (struct mat3 *)mat3_lerp((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1, f); } -void pmatrix_rotation_quaternion(struct vec *q, struct mat *result) +struct mat4 *psmat4(struct mat4 *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44) { - pmatrix_identity(result); - float n9 = q->x * q->x; - float n8 = q->y * q->y; - float n7 = q->z * q->z; - float n6 = q->x * q->y; - float n5 = q->z * q->w; - float n4 = q->z * q->x; - float n3 = q->y * q->w; - float n2 = q->y * q->z; - float n1 = q->x * q->w; - result->m11 = 1.0f - 2.0f * (n8 + n7); - result->m12 = 2.0f * (n6 + n5); - result->m13 = 2.0f * (n4 - n3); - result->m21 = 2.0f * (n6 - n5); - result->m22 = 1.0f - 2.0f * (n7 + n9); - result->m23 = 2.0f * (n2 + n1); - result->m31 = 2.0f * (n4 + n3); - result->m32 = 2.0f * (n2 - n1); - result->m33 = 1.0f - 2.0f * (n8 + n9); + return (struct mat4 *)mat4((mfloat_t *)result, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); } -MATHC_EXTERN_INLINE struct mat matrix_rotation_quaternion(struct vec q) +struct mat4 *psmat4_zero(struct mat4 *result) { - struct mat result; - pmatrix_rotation_quaternion(&q, &result); - return result; + return (struct mat4 *)mat4_zero((mfloat_t *)result); } -void pmatrix_look_at(struct vec *pos, struct vec *target, struct vec *up, struct mat *result) +struct mat4 *psmat4_identity(struct mat4 *result) { - struct vec v1; - struct vec v2; - struct vec v3; - pmatrix_identity(result); - pvector3_subtract(pos, target, &v1); - pvector3_normalize(&v1, &v1); - pvector3_cross(up, &v1, &v2); - pvector3_normalize(&v2, &v2); - pvector3_cross(&v1, &v2, &v3); - result->m11 = v2.x; - result->m12 = v3.x; - result->m13 = v1.x; - result->m21 = v2.y; - result->m22 = v3.y; - result->m23 = v1.y; - result->m31 = v2.z; - result->m32 = v3.z; - result->m33 = v1.z; - result->m41 = -pvector3_dot(&v2, pos); - result->m42 = -pvector3_dot(&v3, pos); - result->m43 = -pvector3_dot(&v1, pos); + return (struct mat4 *)mat4_identity((mfloat_t *)result); } -MATHC_EXTERN_INLINE struct mat matrix_look_at(struct vec pos, struct vec target, struct vec up) +mfloat_t psmat4_determinant(struct mat4 *m0) { - struct mat result; - pmatrix_look_at(&pos, &target, &up, &result); - return result; + return mat4_determinant((mfloat_t *)m0); } -void pmatrix_scale(struct vec *v, struct mat *result) +struct mat4 *psmat4_assign(struct mat4 *result, struct mat4 *m0) { - pmatrix_identity(result); - result->m11 = v->x; - result->m22 = v->y; - result->m33 = v->z; + return (struct mat4 *)mat4_assign((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct mat matrix_scale(struct vec v) +struct mat4 *psmat4_negative(struct mat4 *result, struct mat4 *m0) { - struct mat result; - pmatrix_scale(&v, &result); - return result; + return (struct mat4 *)mat4_negative((mfloat_t *)result, (mfloat_t *)m0); } -void pmatrix_get_scale(struct mat *m, struct vec *result) +struct mat4 *psmat4_transpose(struct mat4 *result, struct mat4 *m0) { - result->x = m->m11; - result->y = m->m22; - result->z = m->m33; + return (struct mat4 *)mat4_transpose((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE struct vec matrix_get_scale(struct mat m) +struct mat4 *psmat4_cofactor(struct mat4 *result, struct mat4 *m0) { - struct vec result; - pmatrix_get_scale(&m, &result); - return result; + return (struct mat4 *)mat4_cofactor((mfloat_t *)result, (mfloat_t *)m0); } -void pmatrix_translation(struct vec *v, struct mat *result) +struct mat4 *psmat4_rotation_x(struct mat4 *result, mfloat_t f) { - pmatrix_identity(result); - result->m14 = v->x; - result->m24 = v->y; - result->m34 = v->z; + return (struct mat4 *)mat4_rotation_x((mfloat_t *)result, f); } -MATHC_EXTERN_INLINE struct mat matrix_translation(struct vec v) +struct mat4 *psmat4_rotation_y(struct mat4 *result, mfloat_t f) { - struct mat result; - pmatrix_translation(&v, &result); - return result; + return (struct mat4 *)mat4_rotation_y((mfloat_t *)result, f); } -void pmatrix_get_translation(struct mat *m, struct vec *result) +struct mat4 *psmat4_rotation_z(struct mat4 *result, mfloat_t f) { - result->x = m->m14; - result->y = m->m24; - result->z = m->m34; - result->w = 1.0f; + return (struct mat4 *)mat4_rotation_z((mfloat_t *)result, f); } -MATHC_EXTERN_INLINE struct vec matrix_get_translation(struct mat m) +struct mat4 *psmat4_rotation_axis(struct mat4 *result, struct vec3 *v0, mfloat_t f) { - struct vec result; - pmatrix_get_translation(&m, &result); - return result; + return (struct mat4 *)mat4_rotation_axis((mfloat_t *)result, (mfloat_t *)v0, f); } -void pmatrix_negative(struct mat *m, struct mat *result) +struct mat4 *psmat4_rotation_quat(struct mat4 *result, struct quat *q0) { - result->m11 = -m->m11; - result->m12 = -m->m12; - result->m13 = -m->m13; - result->m14 = -m->m14; - result->m21 = -m->m21; - result->m22 = -m->m22; - result->m23 = -m->m23; - result->m24 = -m->m24; - result->m31 = -m->m31; - result->m32 = -m->m32; - result->m33 = -m->m33; - result->m34 = -m->m34; - result->m41 = -m->m41; - result->m42 = -m->m42; - result->m43 = -m->m43; - result->m44 = -m->m44; + return (struct mat4 *)mat4_rotation_quat((mfloat_t *)result, (mfloat_t *)q0); } -MATHC_EXTERN_INLINE struct mat matrix_negative(struct mat m) +struct mat4 *psmat4_translation(struct mat4 *result, struct mat4 *m0, struct vec3 *v0) { - struct mat result; - pmatrix_negative(&m, &result); - return result; + return (struct mat4 *)mat4_translation((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -void pmatrix_multiply(struct mat *m, float s, struct mat *result) +struct mat4 *psmat4_translate(struct mat4 *result, struct mat4 *m0, struct vec3 *v0) { - result->m11 = m->m11 * s; - result->m12 = m->m12 * s; - result->m13 = m->m13 * s; - result->m14 = m->m14 * s; - result->m21 = m->m21 * s; - result->m22 = m->m22 * s; - result->m23 = m->m23 * s; - result->m24 = m->m24 * s; - result->m31 = m->m31 * s; - result->m32 = m->m32 * s; - result->m33 = m->m33 * s; - result->m34 = m->m34 * s; - result->m41 = m->m41 * s; - result->m42 = m->m42 * s; - result->m43 = m->m43 * s; - result->m44 = m->m44 * s; + return (struct mat4 *)mat4_translate((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct mat matrix_multiply(struct mat m, float s) +struct mat4 *psmat4_scaling(struct mat4 *result, struct mat4 *m0, struct vec3 *v0) { - struct mat result; - pmatrix_multiply(&m, s, &result); - return result; + return (struct mat4 *)mat4_scaling((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -void pmatrix_multiply_matrix(struct mat *a, struct mat *b, struct mat *result) +struct mat4 *psmat4_scale(struct mat4 *result, struct mat4 *m0, struct vec3 *v0) { - result->m11 = a->m11 * b->m11 + a->m12 * b->m21 + a->m13 * b->m31 + a->m14 * b->m41; - result->m12 = a->m11 * b->m12 + a->m12 * b->m22 + a->m13 * b->m32 + a->m14 * b->m42; - result->m13 = a->m11 * b->m13 + a->m12 * b->m23 + a->m13 * b->m33 + a->m14 * b->m43; - result->m14 = a->m11 * b->m14 + a->m12 * b->m24 + a->m13 * b->m34 + a->m14 * b->m44; - result->m21 = a->m21 * b->m11 + a->m22 * b->m21 + a->m23 * b->m31 + a->m24 * b->m41; - result->m22 = a->m21 * b->m12 + a->m22 * b->m22 + a->m23 * b->m32 + a->m24 * b->m42; - result->m23 = a->m21 * b->m13 + a->m22 * b->m23 + a->m23 * b->m33 + a->m24 * b->m43; - result->m24 = a->m21 * b->m14 + a->m22 * b->m24 + a->m23 * b->m34 + a->m24 * b->m44; - result->m31 = a->m31 * b->m11 + a->m32 * b->m21 + a->m33 * b->m31 + a->m34 * b->m41; - result->m32 = a->m31 * b->m12 + a->m32 * b->m22 + a->m33 * b->m32 + a->m34 * b->m42; - result->m33 = a->m31 * b->m13 + a->m32 * b->m23 + a->m33 * b->m33 + a->m34 * b->m43; - result->m34 = a->m31 * b->m14 + a->m32 * b->m24 + a->m33 * b->m34 + a->m34 * b->m44; - result->m41 = a->m41 * b->m11 + a->m42 * b->m21 + a->m43 * b->m31 + a->m44 * b->m41; - result->m42 = a->m41 * b->m12 + a->m42 * b->m22 + a->m43 * b->m32 + a->m44 * b->m42; - result->m43 = a->m41 * b->m13 + a->m42 * b->m23 + a->m43 * b->m33 + a->m44 * b->m43; - result->m44 = a->m41 * b->m14 + a->m42 * b->m24 + a->m43 * b->m34 + a->m44 * b->m44; + return (struct mat4 *)mat4_scale((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)v0); } -MATHC_EXTERN_INLINE struct mat matrix_multiply_matrix(struct mat a, struct mat b) +struct mat4 *psmat4_multiply(struct mat4 *result, struct mat4 *m0, struct mat4 *m1) { - struct mat result; - pmatrix_multiply_matrix(&a, &b, &result); - return result; + return (struct mat4 *)mat4_multiply((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1); +} + +struct mat4 *psmat4_multiply_f(struct mat4 *result, struct mat4 *m0, mfloat_t f) +{ + return (struct mat4 *)mat4_multiply_f((mfloat_t *)result, (mfloat_t *)m0, f); } -void pmatrix_multiply_f4(struct mat *m, float *result) +struct mat4 *psmat4_inverse(struct mat4 *result, struct mat4 *m0) { - float v0 = result[0]; - float v1 = result[1]; - float v2 = result[2]; - float v3 = result[3]; - result[0] = (m->m11 * v0) + (m->m12 * v1) + (m->m13 * v2) + (m->m14 * v3); - result[1] = (m->m21 * v0) + (m->m22 * v1) + (m->m23 * v2) + (m->m24 * v3); - result[2] = (m->m31 * v0) + (m->m32 * v1) + (m->m33 * v2) + (m->m34 * v3); - result[3] = (m->m41 * v0) + (m->m42 * v1) + (m->m43 * v2) + (m->m44 * v3); + return (struct mat4 *)mat4_inverse((mfloat_t *)result, (mfloat_t *)m0); } -MATHC_EXTERN_INLINE void matrix_multiply_f4(struct mat m, float *result) +struct mat4 *psmat4_lerp(struct mat4 *result, struct mat4 *m0, struct mat4 *m1, mfloat_t f) { - pmatrix_multiply_f4(&m, result); + return (struct mat4 *)mat4_lerp((mfloat_t *)result, (mfloat_t *)m0, (mfloat_t *)m1, f); } -void pmatrix_to_array(struct mat *m, float *result) +struct mat4 *psmat4_look_at(struct mat4 *result, struct vec3 *position, struct vec3 *target, struct vec3 *up) { - result[0] = m->m11; - result[1] = m->m12; - result[2] = m->m13; - result[3] = m->m14; - result[4] = m->m21; - result[5] = m->m22; - result[6] = m->m23; - result[7] = m->m24; - result[8] = m->m31; - result[9] = m->m32; - result[10] = m->m33; - result[11] = m->m34; - result[12] = m->m41; - result[13] = m->m42; - result[14] = m->m43; - result[15] = m->m44; + return (struct mat4 *)mat4_look_at((mfloat_t *)result, (mfloat_t *)position, (mfloat_t *)target, (mfloat_t *)up); } -MATHC_EXTERN_INLINE void matrix_to_array(struct mat m, float *result) +struct mat4 *psmat4_ortho(struct mat4 *result, mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f) { - pmatrix_to_array(&m, result); + return (struct mat4 *)mat4_ortho((mfloat_t *)result, l, r, b, t, n, f); } -/* Easing functions */ -float quadratic_ease_in(float p) +struct mat4 *psmat4_perspective(struct mat4 *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f) { - return p * p; + return (struct mat4 *)mat4_perspective((mfloat_t *)result, fov_y, aspect, n, f); } -float quadratic_ease_out(float p) +struct mat4 *psmat4_perspective_fov(struct mat4 *result, mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f) { - return -(p * (p - 2.0f)); + return (struct mat4 *)mat4_perspective_fov((mfloat_t *)result, fov, w, h, n, f); } -float quadratic_ease_in_out(float p) +struct mat4 *psmat4_perspective_infinite(struct mat4 *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n) { - float f = 0.0f; - if (p < 0.5f) { - f = 2.0f * p * p; + return (struct mat4 *)mat4_perspective_infinite((mfloat_t *)result, fov_y, aspect, n); +} +#endif +#endif + +#if defined(MATHC_USE_FLOATING_POINT) && defined(MATHC_USE_EASING_FUNCTIONS) +mfloat_t quadratic_ease_out(mfloat_t f) +{ + return -f * (f - MFLOAT_C(2.0)); +} + +mfloat_t quadratic_ease_in(mfloat_t f) +{ + return f * f; +} + +mfloat_t quadratic_ease_in_out(mfloat_t f) +{ + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(2.0) * f * f; } else { - f = (-2.0f * p * p) + (4.0f * p) - 1.0f; + a = -MFLOAT_C(2.0) * f * f + MFLOAT_C(4.0) * f - MFLOAT_C(1.0); } - return f; + return a; } -float cubic_ease_in(float p) +mfloat_t cubic_ease_out(mfloat_t f) { - return p * p * p; + mfloat_t a = f - MFLOAT_C(1.0); + return a * a * a + MFLOAT_C(1.0); } -float cubic_ease_out(float p) +mfloat_t cubic_ease_in(mfloat_t f) { - float f = (p - 1.0f); - return f * f * f + 1.0f; + return f * f * f; } -float cubic_ease_in_out(float p) +mfloat_t cubic_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 4.0f * p * p * p; + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(4.0) * f * f * f; } else { - f = ((2.0f * p) - 2.0f); - f = 0.5f * f * f * f + 1.0f; + a = MFLOAT_C(2.0) * f - MFLOAT_C(2.0); + a = MFLOAT_C(0.5) * a * a * a + MFLOAT_C(1.0); } - return f; + return a; } -float quartic_ease_in(float p) +mfloat_t quartic_ease_out(mfloat_t f) { - return p * p * p * p; + mfloat_t a = f - MFLOAT_C(1.0); + return a * a * a * (MFLOAT_C(1.0) - f) + MFLOAT_C(1.0); } -float quartic_ease_out(float p) +mfloat_t quartic_ease_in(mfloat_t f) { - float f = (p - 1.0f); - return f * f * f * (1.0f - p) + 1.0f; + return f * f * f * f; } -float quartic_ease_in_out(float p) +mfloat_t quartic_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 8.0f * p * p * p * p; + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(8.0) * f * f * f * f; } else { - f = (p - 1.0f); - f = -8.0f * f * f * f * f + 1.0f; + a = f - MFLOAT_C(1.0); + a = -MFLOAT_C(8.0) * a * a * a * a + MFLOAT_C(1.0); } - return f; + return a; } -float quintic_ease_in(float p) +mfloat_t quintic_ease_out(mfloat_t f) { - return p * p * p * p * p; + mfloat_t a = f - MFLOAT_C(1.0); + return a * a * a * a * a + MFLOAT_C(1.0); } -float quintic_ease_out(float p) +mfloat_t quintic_ease_in(mfloat_t f) { - float f = (p - 1.0f); - return f * f * f * f * f + 1.0f; + return f * f * f * f * f; } -float quintic_ease_in_out(float p) +mfloat_t quintic_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 16.0f * p * p * p * p * p; + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(16.0) * f * f * f * f * f; } else { - f = ((2.0f * p) - 2.0f); - f = 0.5f * f * f * f * f * f + 1.0f; + a = MFLOAT_C(2.0) * f - MFLOAT_C(2.0); + a = MFLOAT_C(0.5) * a * a * a * a * a + MFLOAT_C(1.0); } - return f; + return a; } -float sine_ease_in(float p) +mfloat_t sine_ease_out(mfloat_t f) { - return sinf((p - 1.0f) * M_PIF_2) + 1.0f; + return MSIN(f * MPI_2); } -float sine_ease_out(float p) +mfloat_t sine_ease_in(mfloat_t f) { - return sinf(p * M_PIF_2); + return MSIN((f - MFLOAT_C(1.0)) * MPI_2) + MFLOAT_C(1.0); } -float sine_ease_in_out(float p) +mfloat_t sine_ease_in_out(mfloat_t f) { - return 0.5f * (1.0f - cosf(p * M_PIF)); + return MFLOAT_C(0.5) * (MFLOAT_C(1.0) - MCOS(f * MPI)); } -float circular_ease_in(float p) +mfloat_t circular_ease_out(mfloat_t f) { - return 1.0f - sqrtf(1.0f - (p * p)); + return MSQRT((MFLOAT_C(2.0) - f) * f); } -float circular_ease_out(float p) +mfloat_t circular_ease_in(mfloat_t f) { - return sqrtf((2.0f - p) * p); + return MFLOAT_C(1.0) - MSQRT(MFLOAT_C(1.0) - (f * f)); } -float circular_ease_in_out(float p) +mfloat_t circular_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 0.5f * (1.0f - sqrtf(1.0f - 4.0f * (p * p))); + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(0.5) * (MFLOAT_C(1.0) - MSQRT(MFLOAT_C(1.0) - MFLOAT_C(4.0) * f * f)); } else { - f = 0.5f * (sqrtf(-((2.0f * p) - 3.0f) * ((2.0f * p) - 1.0f)) + 1.0f); + a = MFLOAT_C(0.5) * (MSQRT(-(MFLOAT_C(2.0) * f - MFLOAT_C(3.0)) * (MFLOAT_C(2.0) * f - MFLOAT_C(1.0))) + MFLOAT_C(1.0)); } - return f; + return a; } -float exponential_ease_in(float p) +mfloat_t exponential_ease_out(mfloat_t f) { - float f = p; - if (p != 0.0f) { - f = powf(2.0f, 10.0f * (p - 1.0f)); + mfloat_t a = f; + if (MFABS(a) > MFLT_EPSILON) { + a = MFLOAT_C(1.0) - MPOW(MFLOAT_C(2.0), -MFLOAT_C(10.0) * f); } - return f; + return a; } -float exponential_ease_out(float p) +mfloat_t exponential_ease_in(mfloat_t f) { - float f = p; - if (p != 1.0f) { - f = 1 - powf(2.0f, -10.0f * p); + mfloat_t a = f; + if (MFABS(a) > MFLT_EPSILON) { + a = MPOW(MFLOAT_C(2.0), MFLOAT_C(10.0) * (f - MFLOAT_C(1.0))); } - return f; + return a; } -float exponential_ease_in_out(float p) +mfloat_t exponential_ease_in_out(mfloat_t f) { - float f = p; - if (p == 0.0f || p == 1.0f) { - f = p; - } else if (p < 0.5f) { - f = 0.5f * powf(2.0f, (20.0f * p) - 10.0f); + mfloat_t a = f; + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(0.5) * MPOW(MFLOAT_C(2.0), (MFLOAT_C(20.0) * f) - MFLOAT_C(10.0)); } else { - f = -0.5f * powf(2.0f, (-20.0f * p) + 10.0f) + 1.0f; + a = -MFLOAT_C(0.5) * MPOW(MFLOAT_C(2.0), -MFLOAT_C(20.0) * f + MFLOAT_C(10.0)) + MFLOAT_C(1.0); } - return f; + return a; } -float elastic_ease_in(float p) +mfloat_t elastic_ease_out(mfloat_t f) { - return sinf(13.0f * M_PIF_2 * p) * powf(2.0f, 10.0f * (p - 1.0f)); + return MSIN(-MFLOAT_C(13.0) * MPI_2 * (f + MFLOAT_C(1.0))) * MPOW(MFLOAT_C(2.0), -MFLOAT_C(10.0) * f) + MFLOAT_C(1.0); } -float elastic_ease_out(float p) +mfloat_t elastic_ease_in(mfloat_t f) { - return sinf(-13.0f * M_PIF_2 * (p + 1.0f)) * powf(2.0f, -10.0f * p) + 1.0f; + return MSIN(MFLOAT_C(13.0) * MPI_2 * f) * MPOW(MFLOAT_C(2.0), MFLOAT_C(10.0) * (f - MFLOAT_C(1.0))); } -float elastic_ease_in_out(float p) +mfloat_t elastic_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 0.5f * sinf(13.0f * M_PIF_2 * (2.0f * p)) * powf(2.0f, 10.0f * ((2.0f * p) - 1.0f)); + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(0.5) * MSIN(MFLOAT_C(13.0) * MPI_2 * (MFLOAT_C(2.0) * f)) * MPOW(MFLOAT_C(2.0), MFLOAT_C(10.0) * ((MFLOAT_C(2.0) * f) - MFLOAT_C(1.0))); } else { - f = 0.5f * (sinf(-13.0f * M_PIF_2 * ((2.0f * p - 1.0f) + 1.0f)) * powf(2.0f, -10.0f * (2.0f * p - 1.0f)) + 2.0f); + a = MFLOAT_C(0.5) * (MSIN(-MFLOAT_C(13.0) * MPI_2 * ((MFLOAT_C(2.0) * f - MFLOAT_C(1.0)) + MFLOAT_C(1.0))) * MPOW(MFLOAT_C(2.0), -MFLOAT_C(10.0) * (MFLOAT_C(2.0) * f - MFLOAT_C(1.0))) + MFLOAT_C(2.0)); } - return f; + return a; } -float back_ease_in(float p) +mfloat_t back_ease_out(mfloat_t f) { - return p * p * p - p * sinf(p * M_PIF); + mfloat_t a = MFLOAT_C(1.0) - f; + return MFLOAT_C(1.0) - (a * a * a - a * MSIN(a * MPI)); } -float back_ease_out(float p) +mfloat_t back_ease_in(mfloat_t f) { - float f = (1.0f - p); - return 1.0f - (f * f * f - f * sinf(f * M_PIF)); + return f * f * f - f * MSIN(f * MPI); } -float back_ease_in_out(float p) +mfloat_t back_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 2.0f * p; - f = 0.5f * (f * f * f - f * sinf(f * M_PIF)); + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(2.0) * f; + a = MFLOAT_C(0.5) * (a * a * a - a * MSIN(a * MPI)); } else { - f = (1.0f - (2.0f * p - 1.0f)); - f = 0.5f * (1.0f - (f * f * f - f * sinf(f * M_PIF))) + 0.5f; + a = (MFLOAT_C(1.0) - (MFLOAT_C(2.0) * f - MFLOAT_C(1.0))); + a = MFLOAT_C(0.5) * (MFLOAT_C(1.0) - (a * a * a - a * MSIN(f * MPI))) + MFLOAT_C(0.5); } - return f; + return a; } -float bounce_ease_in(float p) +mfloat_t bounce_ease_out(mfloat_t f) { - return 1.0f - bounce_ease_out(1.0f - p); + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(4.0) / MFLOAT_C(11.0)) { + a = (MFLOAT_C(121.0) * f * f) / MFLOAT_C(16.0); + } else if (f < MFLOAT_C(8.0) / MFLOAT_C(11.0)) { + a = (MFLOAT_C(363.0) / MFLOAT_C(40.0) * f * f) - (MFLOAT_C(99.0) / MFLOAT_C(10.0) * f) + MFLOAT_C(17.0) / MFLOAT_C(5.0); + } else if (f < MFLOAT_C(9.0) / MFLOAT_C(10.0)) { + a = (MFLOAT_C(4356.0) / MFLOAT_C(361.0) * f * f) - (MFLOAT_C(35442.0) / MFLOAT_C(1805.0) * f) + MFLOAT_C(16061.0) / MFLOAT_C(1805.0); + } else { + a = (MFLOAT_C(54.0) / MFLOAT_C(5.0) * f * f) - (MFLOAT_C(513.0) / MFLOAT_C(25.0) * f) + MFLOAT_C(268.0) / MFLOAT_C(25.0); + } + return a; } -float bounce_ease_out(float p) +mfloat_t bounce_ease_in(mfloat_t f) { - float f = 0.0f; - if (p < 4 / 11.0f) { - f = (121 * p * p) / 16.0f; - } else if (p < 8 / 11.0f) { - f = (363 / 40.0f * p * p) - (99 / 10.0f * p) + 17 / 5.0f; - } else if (p < 9 / 10.0f) { - f = (4356 / 361.0f * p * p) - (35442 / 1805.0f * p) + 16061 / 1805.0f; - } else { - f = (54 / 5.0f * p * p) - (513 / 25.0f * p) + 268 / 25.0f; - } - return f; + return MFLOAT_C(1.0) - bounce_ease_out(MFLOAT_C(1.0) - f); } -float bounce_ease_in_out(float p) +mfloat_t bounce_ease_in_out(mfloat_t f) { - float f = 0.0f; - if (p < 0.5f) { - f = 0.5f * bounce_ease_in(p * 2.0f); + mfloat_t a = MFLOAT_C(0.0); + if (f < MFLOAT_C(0.5)) { + a = MFLOAT_C(0.5) * bounce_ease_in(f * MFLOAT_C(2.0)); } else { - f = 0.5f * bounce_ease_out(p * 2.0f - 1.0f) + 0.5f; + a = MFLOAT_C(0.5) * bounce_ease_out(f * MFLOAT_C(2.0) - MFLOAT_C(1.0)) + MFLOAT_C(0.5); } - return f; + return a; } +#endif diff --git a/mathc.h b/mathc.h index cfc7dce..4f9f5e1 100644 --- a/mathc.h +++ b/mathc.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2016 Felipe Ferreira da Silva +Copyright © 2018 Felipe Ferreira da Silva This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of @@ -21,273 +21,1282 @@ the following restrictions: #ifndef MATHC_H #define MATHC_H -#define M_PIF 3.1415926536f -#define M_PIF_2 1.5707963268f +#include +#include -struct vec { - float x; - float y; - float z; - float w; +#define MATHC_VERSION_YYYY 2019 +#define MATHC_VERSION_MM 02 +#define MATHC_VERSION_DD 16 +#define MATHC_VERSION_MICRO 0 + +#if !defined(MATHC_NO_INT) +#define MATHC_USE_INT +#endif +#if !defined(MATHC_NO_FLOATING_POINT) +#define MATHC_USE_FLOATING_POINT +#endif +#if !defined(MATHC_NO_POINTER_STRUCT_FUNCTIONS) +#define MATHC_USE_POINTER_STRUCT_FUNCTIONS +#endif +#if !defined(MATHC_NO_STRUCT_FUNCTIONS) +#define MATHC_USE_STRUCT_FUNCTIONS +#endif +#if !defined(MATHC_NO_EASING_FUNCTIONS) +#define MATHC_USE_EASING_FUNCTIONS +#endif + +#if defined(MATHC_USE_INT) +#include +#endif +#if defined(MATHC_USE_FLOATING_POINT) +#include +#endif + +#define VEC2_SIZE 2 +#define VEC3_SIZE 3 +#define VEC4_SIZE 4 +#define QUAT_SIZE 4 +#define MAT2_SIZE 4 +#define MAT3_SIZE 9 +#define MAT4_SIZE 16 + +#if defined(MATHC_USE_INT) +#if defined(MATHC_INT_TYPE) +typedef MATHC_INT_TYPE mint_t; +#endif +#if !defined(MATHC_USE_INT8) && !defined(MATHC_USE_INT16) && !defined(MATHC_USE_INT32) && !defined(MATHC_USE_INT64) +#define MATHC_USE_INT32 +#endif +#if defined(MATHC_USE_INT8) +#if !defined(MATHC_INT_TYPE) +typedef int8_t mint_t; +#endif +#define MINT_MAX INT8_MAX +#define MINT_MIN INT8_MIN +#endif +#if defined(MATHC_USE_INT16) +#if !defined(MATHC_INT_TYPE) +typedef int16_t mint_t; +#endif +#define MINT_MAX INT16_MAX +#define MINT_MIN INT16_MIN +#endif +#if defined(MATHC_USE_INT32) +#if !defined(MATHC_INT_TYPE) +typedef int32_t mint_t; +#endif +#define MINT_MAX INT32_MAX +#define MINT_MIN INT32_MIN +#endif +#if defined(MATHC_USE_INT64) +#if !defined(MATHC_INT_TYPE) +typedef int64_t mint_t; +#endif +#define MINT_MAX INT64_MAX +#define MINT_MIN INT64_MIN +#endif +#endif + +#if defined(MATHC_USE_FLOATING_POINT) +#if defined(MATHC_FLOATING_POINT_TYPE) +typedef MATHC_FLOATING_POINT_TYPE mfloat_t; +#endif +#if !defined(MATHC_USE_SINGLE_FLOATING_POINT) && !defined(MATHC_USE_DOUBLE_FLOATING_POINT) +#define MATHC_USE_SINGLE_FLOATING_POINT +#endif +#if defined(MATHC_USE_SINGLE_FLOATING_POINT) +#if !defined(MATHC_FLOATING_POINT_TYPE) +typedef float mfloat_t; +#endif +#define MPI 3.1415926536f +#define MPI_2 1.5707963268f +#define MPI_4 0.7853981634f +#define MFLT_EPSILON FLT_EPSILON +#define MFABS fabsf +#define MFMIN fminf +#define MFMAX fmaxf +#define MSQRT sqrtf +#define MSIN sinf +#define MCOS cosf +#define MACOS acosf +#define MASIN asinf +#define MTAN tanf +#define MATAN2 atan2f +#define MPOW powf +#define MFLOOR floorf +#define MCEIL ceilf +#define MROUND roundf +#define MFLOAT_C(c) c ## f +#endif +#if defined(MATHC_USE_DOUBLE_FLOATING_POINT) +#if !defined(MATHC_FLOATING_POINT_TYPE) +typedef double mfloat_t; +#endif +#define MPI 3.14159265358979323846 +#define MPI_2 1.57079632679489661923 +#define MPI_4 0.78539816339744830962 +#define MFLT_EPSILON DBL_EPSILON +#define MFABS fabs +#define MFMIN fmin +#define MFMAX fmax +#define MSQRT sqrt +#define MSIN sin +#define MCOS cos +#define MACOS acos +#define MASIN asin +#define MTAN tan +#define MATAN2 atan2 +#define MPOW pow +#define MFLOOR floor +#define MCEIL ceil +#define MROUND round +#define MFLOAT_C(c) c +#endif +#endif + +#if defined(MATHC_USE_STRUCT_FUNCTIONS) || defined(MATHC_USE_POINTER_STRUCT_FUNCTIONS) +#if defined(MATHC_USE_INT) +struct vec2i { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mint_t x; + mint_t y; + }; + mint_t v[VEC2_SIZE]; + }; +#else + mint_t x; + mint_t y; +#endif }; -struct mat { - /* Row x Column */ - float m11; - float m21; - float m31; - float m41; - float m12; - float m22; - float m32; - float m42; - float m13; - float m23; - float m33; - float m43; - float m14; - float m24; - float m34; - float m44; +struct vec3i { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mint_t x; + mint_t y; + mint_t z; + }; + mint_t v[VEC3_SIZE]; + }; +#else + mint_t x; + mint_t y; + mint_t z; +#endif }; -/* Utils */ -int nearly_equal(float a, float b, float epsilon); -float to_radians(float degrees); -float to_degrees(float radians); +struct vec4i { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mint_t x; + mint_t y; + mint_t z; + mint_t w; + }; + mint_t v[VEC4_SIZE]; + }; +#else + mint_t x; + mint_t y; + mint_t z; + mint_t w; +#endif +}; +#endif -/* Vector 2D */ -void to_pvector2(float x, float y, struct vec *result); -void pvector2_add(struct vec *a, struct vec *b, struct vec *result); -void pvector2_subtract(struct vec *a, struct vec *b, struct vec *result); -void pvector2_scale(struct vec *a, float scale, struct vec *result); -void pvector2_multiply(struct vec *a, struct vec *b, struct vec *result); -void pvector2_divide(struct vec *a, struct vec *b, struct vec *result); -void pvector2_negative(struct vec *a, struct vec *result); -void pvector2_inverse(struct vec *a, struct vec *result); -void pvector2_abs(struct vec *a, struct vec *result); -void pvector2_floor(struct vec *a, struct vec *result); -void pvector2_ceil(struct vec *a, struct vec *result); -void pvector2_round(struct vec *a, struct vec *result); -void pvector2_max(struct vec *a, struct vec *b, struct vec *result); -void pvector2_min(struct vec *a, struct vec *b, struct vec *result); -float pvector2_dot(struct vec *a, struct vec *b); -float pvector2_angle(struct vec *a); -float pvector2_length_squared(struct vec *a); -float pvector2_length(struct vec *a); -void pvector2_normalize(struct vec *a, struct vec *result); -void pvector2_slide(struct vec *a, struct vec *b, struct vec *result); -void pvector2_reflect(struct vec *a, struct vec *b, struct vec *result); -void pvector2_tangent(struct vec *a, struct vec *result); -void pvector2_rotate(struct vec *a, float angle, struct vec *result); -float pvector2_distance_to(struct vec *a, struct vec *b); -float pvector2_distance_squared_to(struct vec *a, struct vec *b); -void pvector2_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec2 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t x; + mfloat_t y; + }; + mfloat_t v[VEC2_SIZE]; + }; +#else + mfloat_t x; + mfloat_t y; +#endif +}; -struct vec to_vector2(float x, float y); -struct vec vector2_add(struct vec a, struct vec b); -struct vec vector2_subtract(struct vec a, struct vec b); -struct vec vector2_scale(struct vec a, float scale); -struct vec vector2_multiply(struct vec a, struct vec b); -struct vec vector2_divide(struct vec a, struct vec b); -struct vec vector2_negative(struct vec a); -struct vec vector2_inverse(struct vec a); -struct vec vector2_abs(struct vec a); -struct vec vector2_floor(struct vec a); -struct vec vector2_ceil(struct vec a); -struct vec vector2_round(struct vec a); -struct vec vector2_max(struct vec a, struct vec b); -struct vec vector2_min(struct vec a, struct vec b); -float vector2_dot(struct vec a, struct vec b); -float vector2_angle(struct vec a); -float vector2_length_squared(struct vec a); -float vector2_length(struct vec a); -struct vec vector2_normalize(struct vec a); -struct vec vector2_slide(struct vec a, struct vec normal); -struct vec vector2_reflect(struct vec a, struct vec normal); -struct vec vector2_tangent(struct vec a); -struct vec vector2_rotate(struct vec a, float angle); -float vector2_distance_to(struct vec a, struct vec b); -float vector2_distance_squared_to(struct vec a, struct vec b); -struct vec vector2_linear_interpolation(struct vec a, struct vec b, float p); +struct vec3 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t x; + mfloat_t y; + mfloat_t z; + }; + mfloat_t v[VEC3_SIZE]; + }; +#else + mfloat_t x; + mfloat_t y; + mfloat_t z; +#endif +}; -/* Vector 3D */ -void to_pvector3(float x, float y, float z, struct vec *result); -void pvector3_add(struct vec *a, struct vec *b, struct vec *result); -void pvector3_subtract(struct vec *a, struct vec *b, struct vec *result); -void pvector3_scale(struct vec *a, float scale, struct vec *result); -void pvector3_multiply(struct vec *a, struct vec *b, struct vec *result); -void pvector3_divide(struct vec *a, struct vec *b, struct vec *result); -void pvector3_negative(struct vec *a, struct vec *result); -void pvector3_inverse(struct vec *a, struct vec *result); -void pvector3_abs(struct vec *a, struct vec *result); -void pvector3_floor(struct vec *a, struct vec *result); -void pvector3_ceil(struct vec *a, struct vec *result); -void pvector3_round(struct vec *a, struct vec *result); -void pvector3_max(struct vec *a, struct vec *b, struct vec *result); -void pvector3_min(struct vec *a, struct vec *b, struct vec *result); -float pvector3_dot(struct vec *a, struct vec *b); -void pvector3_cross(struct vec *a, struct vec *b, struct vec *result); -float pvector3_length_squared(struct vec *a); -float pvector3_length(struct vec *a); -void pvector3_normalize(struct vec *a, struct vec *result); -void pvector3_slide(struct vec *a, struct vec *b, struct vec *result); -void pvector3_reflect(struct vec *a, struct vec *normal, struct vec *result); -float pvector3_distance_to(struct vec *a, struct vec *b); -float pvector3_distance_squared_to(struct vec *a, struct vec *b); -void pvector3_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result); +struct vec4 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t x; + mfloat_t y; + mfloat_t z; + mfloat_t w; + }; + mfloat_t v[VEC4_SIZE]; + }; +#else + mfloat_t x; + mfloat_t y; + mfloat_t z; + mfloat_t w; +#endif +}; -struct vec to_vector3(float x, float y, float z); -struct vec vector3_add(struct vec a, struct vec b); -struct vec vector3_subtract(struct vec a, struct vec b); -struct vec vector3_scale(struct vec a, float scale); -struct vec vector3_multiply(struct vec a, struct vec b); -struct vec vector3_divide(struct vec a, struct vec b); -struct vec vector3_negative(struct vec a); -struct vec vector3_inverse(struct vec a); -struct vec vector3_abs(struct vec a); -struct vec vector3_floor(struct vec a); -struct vec vector3_ceil(struct vec a); -struct vec vector3_round(struct vec a); -struct vec vector3_max(struct vec a, struct vec b); -struct vec vector3_min(struct vec a, struct vec b); -float vector3_dot(struct vec a, struct vec b); -struct vec vector3_cross(struct vec a, struct vec b); -float vector3_length_squared(struct vec a); -float vector3_length(struct vec a); -struct vec vector3_normalize(struct vec a); -struct vec vector3_slide(struct vec a, struct vec b); -struct vec vector3_reflect(struct vec a, struct vec normal); -float vector3_distance_to(struct vec a, struct vec b); -float vector3_distance_squared_to(struct vec a, struct vec b); -struct vec vector3_linear_interpolation(struct vec a, struct vec b, float p); +struct quat { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t x; + mfloat_t y; + mfloat_t z; + mfloat_t w; + }; + mfloat_t v[QUAT_SIZE]; + }; +#else + mfloat_t x; + mfloat_t y; + mfloat_t z; + mfloat_t w; +#endif +}; -/* Quaternion */ -void to_pquaternion(float x, float y, float z, float w, struct vec *result); -void pquaternion_add(struct vec *a, struct vec *b, struct vec *result); -void pquaternion_subtract(struct vec *a, struct vec *b, struct vec *result); -void pquaternion_scale(struct vec *a, float scale, struct vec *result); -void pquaternion_multiply(struct vec *a, struct vec *b, struct vec *result); -void pquaternion_divide(struct vec *a, struct vec *b, struct vec *result); -void pquaternion_negative(struct vec *a, struct vec *result); -void pquaternion_conjugate(struct vec *a, struct vec *result); -void pquaternion_inverse(struct vec *a, struct vec *result); -void pquaternion_abs(struct vec *a, struct vec *result); -void pquaternion_floor(struct vec *a, struct vec *result); -void pquaternion_ceil(struct vec *a, struct vec *result); -void pquaternion_round(struct vec *a, struct vec *result); -void pquaternion_max(struct vec *a, struct vec *b, struct vec *result); -void pquaternion_min(struct vec *a, struct vec *b, struct vec *result); -float pquaternion_dot(struct vec *a, struct vec *b); -float pquaternion_angle(struct vec *a, struct vec *b); -float pquaternion_length_squared(struct vec *a); -float pquaternion_length(struct vec *a); -void pquaternion_normalize(struct vec *a, struct vec *result); -void pquaternion_power(struct vec *a, float exponent, struct vec *result); -void pquaternion_from_axis_angle(struct vec *a, float angle, struct vec *result); -void pquaternion_to_axis_angle(struct vec *a, struct vec *result); -void pquaternion_rotation_matrix(struct mat *m, struct vec *result); -void pquaternion_yaw_pitch_roll(float yaw, float pitch, float roll, struct vec *result); -void pquaternion_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result); -void pquaternion_spherical_linear_interpolation(struct vec *a, struct vec *b, float p, struct vec *result); +/* +Matrix 2×2 representation: +0/m11 2/m12 +1/m21 3/m22 +*/ +struct mat2 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t m11; + mfloat_t m21; + mfloat_t m12; + mfloat_t m22; + }; + mfloat_t v[MAT2_SIZE]; + }; +#else + mfloat_t m11; + mfloat_t m21; + mfloat_t m12; + mfloat_t m22; +#endif +}; -struct vec to_quaternion(float x, float y, float z, float w); -struct vec quaternion_add(struct vec a, struct vec b); -struct vec quaternion_subtract(struct vec a, struct vec b); -struct vec quaternion_scale(struct vec a, float scale); -struct vec quaternion_multiply(struct vec a, struct vec b); -struct vec quaternion_divide(struct vec a, struct vec b); -struct vec quaternion_negative(struct vec a); -struct vec quaternion_conjugate(struct vec a); -struct vec quaternion_inverse(struct vec a); -struct vec quaternion_abs(struct vec a); -struct vec quaternion_floor(struct vec a); -struct vec quaternion_ceil(struct vec a); -struct vec quaternion_round(struct vec a); -struct vec quaternion_max(struct vec a, struct vec b); -struct vec quaternion_min(struct vec a, struct vec b); -float quaternion_dot(struct vec a, struct vec b); -float quaternion_angle(struct vec a, struct vec b); -float quaternion_length_squared(struct vec a); -float quaternion_length(struct vec a); -struct vec quaternion_normalize(struct vec a); -struct vec quaternion_power(struct vec a, float exponent); -struct vec quaternion_from_axis_angle(struct vec a, float angle); -struct vec quaternion_to_axis_angle(struct vec a); -struct vec quaternion_rotation_matrix(struct mat m); -struct vec quaternion_yaw_pitch_roll(float yaw, float pitch, float roll); -struct vec quaternion_linear_interpolation(struct vec a, struct vec b, float p); -struct vec quaternion_spherical_linear_interpolation(struct vec a, struct vec b, float p); +/* +Matrix 3×3 representation: +0/m11 3/m12 6/m13 +1/m21 4/m22 7/m23 +2/m31 5/m32 8/m33 +*/ +struct mat3 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t m11; + mfloat_t m21; + mfloat_t m31; + mfloat_t m12; + mfloat_t m22; + mfloat_t m32; + mfloat_t m13; + mfloat_t m23; + mfloat_t m33; + }; + mfloat_t v[MAT3_SIZE]; + }; +#else + mfloat_t m11; + mfloat_t m21; + mfloat_t m31; + mfloat_t m12; + mfloat_t m22; + mfloat_t m32; + mfloat_t m13; + mfloat_t m23; + mfloat_t m33; +#endif +}; -/* Matrix */ -void pmatrix_identity(struct mat *result); -void pmatrix_ortho(float l, float r, float b, float t, float n, float f, struct mat *result); -void pmatrix_perspective(float y_fov, float aspect, float n, float f, struct mat *result); -void pmatrix_rotation_x(float angle, struct mat *result); -void pmatrix_rotation_y(float angle, struct mat *result); -void pmatrix_rotation_z(float angle, struct mat *result); -void pmatrix_rotation_axis(struct vec *a, float angle, struct mat *result); -void pmatrix_rotation_quaternion(struct vec *q, struct mat *result); -void pmatrix_look_at(struct vec *pos, struct vec *target, struct vec *up, struct mat *result); -void pmatrix_scale(struct vec *v, struct mat *result); -void pmatrix_get_scale(struct mat *m, struct vec *result); -void pmatrix_translation(struct vec *v, struct mat *result); -void pmatrix_get_translation(struct mat *m, struct vec *result); -void pmatrix_negative(struct mat *m, struct mat *result); -void pmatrix_multiply(struct mat *m, float s, struct mat *result); -void pmatrix_multiply_matrix(struct mat *a, struct mat *b, struct mat *result); -void pmatrix_multiply_f4(struct mat *m, float *result); -void pmatrix_to_array(struct mat *m, float *result); +/* +Matrix 4×4 representation: +0/m11 4/m12 8/m13 12/m14 +1/m21 5/m22 9/m23 13/m24 +2/m31 6/m32 10/m33 14/m34 +3/m41 7/m42 11/m43 15/m44 +*/ +struct mat4 { +#if defined(MATHC_USE_UNIONS) + union { + struct { + mfloat_t m11; + mfloat_t m21; + mfloat_t m31; + mfloat_t m41; + mfloat_t m12; + mfloat_t m22; + mfloat_t m32; + mfloat_t m42; + mfloat_t m13; + mfloat_t m23; + mfloat_t m33; + mfloat_t m43; + mfloat_t m14; + mfloat_t m24; + mfloat_t m34; + mfloat_t m44; + }; + mfloat_t v[MAT4_SIZE]; + }; +#else + mfloat_t m11; + mfloat_t m21; + mfloat_t m31; + mfloat_t m41; + mfloat_t m12; + mfloat_t m22; + mfloat_t m32; + mfloat_t m42; + mfloat_t m13; + mfloat_t m23; + mfloat_t m33; + mfloat_t m43; + mfloat_t m14; + mfloat_t m24; + mfloat_t m34; + mfloat_t m44; +#endif +}; +#endif +#endif -struct mat matrix_identity(void); -struct mat matrix_ortho(float l, float r, float b, float t, float n, float f); -struct mat matrix_perspective(float y_fov, float aspect, float n, float f); -struct mat matrix_rotation_x(float angle); -struct mat matrix_rotation_y(float angle); -struct mat matrix_rotation_z(float angle); -struct mat matrix_rotation_axis(struct vec a, float angle); -struct mat matrix_rotation_quaternion(struct vec q); -struct mat matrix_look_at(struct vec pos, struct vec target, struct vec up); -struct mat matrix_scale(struct vec v); -struct vec matrix_get_scale(struct mat m); -struct mat matrix_translation(struct vec v); -struct vec matrix_get_translation(struct mat m); -struct mat matrix_negative(struct mat m); -struct mat matrix_multiply(struct mat m, float s); -struct mat matrix_multiply_matrix(struct mat a, struct mat b); -void matrix_multiply_f4(struct mat m, float *result); -void matrix_to_array(struct mat m, float *result); +#if defined(MATHC_USE_INT) +mint_t clampi(mint_t value, mint_t min, mint_t max); +#endif + +#if defined(MATHC_USE_FLOATING_POINT) +#define MRADIANS(degrees) (degrees * MPI / MFLOAT_C(180.0)) +#define MDEGREES(radians) (radians * MFLOAT_C(180.0) / MPI) +bool nearly_equal(mfloat_t a, mfloat_t b, mfloat_t epsilon); +mfloat_t to_radians(mfloat_t degrees); +mfloat_t to_degrees(mfloat_t radians); +mfloat_t clampf(mfloat_t value, mfloat_t min, mfloat_t max); +#endif -/* Easing functions */ -float quadratic_ease_in(float p); -float quadratic_ease_out(float p); -float quadratic_ease_in_out(float p); -float cubic_ease_in(float p); -float cubic_ease_out(float p); -float cubic_ease_in_out(float p); -float quartic_ease_in(float p); -float quartic_ease_out(float p); -float quartic_ease_in_out(float p); -float quintic_ease_in(float p); -float quintic_ease_out(float p); -float quintic_ease_in_out(float p); -float sine_ease_in(float p); -float sine_ease_out(float p); -float sine_ease_in_out(float p); -float circular_ease_in(float p); -float circular_ease_out(float p); -float circular_ease_in_out(float p); -float exponential_ease_in(float p); -float exponential_ease_out(float p); -float exponential_ease_in_out(float p); -float elastic_ease_in(float p); -float elastic_ease_out(float p); -float elastic_ease_in_out(float p); -float back_ease_in(float p); -float back_ease_out(float p); -float back_ease_in_out(float p); -float bounce_ease_in(float p); -float bounce_ease_out(float p); -float bounce_ease_in_out(float p); +#if defined(MATHC_USE_INT) +bool vec2i_is_zero(mint_t *v0); +bool vec2i_is_equal(mint_t *v0, mint_t *v1); +mint_t *vec2i(mint_t *result, mint_t x, mint_t y); +mint_t *vec2i_assign(mint_t *result, mint_t *v0); +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec2i_assign_vec2(mint_t *result, mfloat_t *v0); +#endif +mint_t *vec2i_zero(mint_t *result); +mint_t *vec2i_one(mint_t *result); +mint_t *vec2i_sign(mint_t *result, mint_t *v0); +mint_t *vec2i_add(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_add_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec2i_subtract(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_subtract_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec2i_multiply(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_multiply_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec2i_divide(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_divide_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec2i_snap(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_snap_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec2i_negative(mint_t *result, mint_t *v0); +mint_t *vec2i_abs(mint_t *result, mint_t *v0); +mint_t *vec2i_max(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_min(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec2i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2); +mint_t *vec2i_tangent(mint_t *result, mint_t *v0); +bool vec3i_is_zero(mint_t *v0); +bool vec3i_is_equal(mint_t *v0, mint_t *v1); +mint_t *vec3i(mint_t *result, mint_t x, mint_t y, mint_t z); +mint_t *vec3i_assign(mint_t *result, mint_t *v0); +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec3i_assign_vec3(mint_t *result, mfloat_t *v0); +#endif +mint_t *vec3i_zero(mint_t *result); +mint_t *vec3i_one(mint_t *result); +mint_t *vec3i_sign(mint_t *result, mint_t *v0); +mint_t *vec3i_add(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_add_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec3i_subtract(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_subtract_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec3i_multiply(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_multiply_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec3i_divide(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_divide_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec3i_snap(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_snap_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec3i_cross(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_negative(mint_t *result, mint_t *v0); +mint_t *vec3i_abs(mint_t *result, mint_t *v0); +mint_t *vec3i_max(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_min(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec3i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2); +bool vec4i_is_zero(mint_t *v0); +bool vec4i_is_equal(mint_t *v0, mint_t *v1); +mint_t *vec4i(mint_t *result, mint_t x, mint_t y, mint_t z, mint_t w); +mint_t *vec4i_assign(mint_t *result, mint_t *v0); +#if defined(MATHC_USE_FLOATING_POINT) +mint_t *vec4i_assign_vec4(mint_t *result, mfloat_t *v0); +#endif +mint_t *vec4i_zero(mint_t *result); +mint_t *vec4i_one(mint_t *result); +mint_t *vec4i_sign(mint_t *result, mint_t *v0); +mint_t *vec4i_add(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_add_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec4i_subtract(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_subtract_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec4i_multiply(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_multiply_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec4i_divide(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_divide_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec4i_snap(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_snap_i(mint_t *result, mint_t *v0, mint_t i); +mint_t *vec4i_negative(mint_t *result, mint_t *v0); +mint_t *vec4i_abs(mint_t *result, mint_t *v0); +mint_t *vec4i_max(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_min(mint_t *result, mint_t *v0, mint_t *v1); +mint_t *vec4i_clamp(mint_t *result, mint_t *v0, mint_t *v1, mint_t *v2); +#endif +#if defined(MATHC_USE_FLOATING_POINT) +bool vec2_is_zero(mfloat_t *v0); +bool vec2_is_equal(mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2(mfloat_t *result, mfloat_t x, mfloat_t y); +mfloat_t *vec2_assign(mfloat_t *result, mfloat_t *v0); +#if defined(MATHC_USE_INT) +mfloat_t *vec2_assign_vec2i(mfloat_t *result, mint_t *v0); +#endif +mfloat_t *vec2_zero(mfloat_t *result); +mfloat_t *vec2_one(mfloat_t *result); +mfloat_t *vec2_sign(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_multiply_mat2(mfloat_t *result, mfloat_t *v0, mfloat_t *m0); +mfloat_t *vec2_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_negative(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_abs(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_floor(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_ceil(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_round(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2); +mfloat_t *vec2_normalize(mfloat_t *result, mfloat_t *v0); +mfloat_t vec2_dot(mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_project(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec2_slide(mfloat_t *result, mfloat_t *v0, mfloat_t *normal); +mfloat_t *vec2_reflect(mfloat_t *result, mfloat_t *v0, mfloat_t *normal); +mfloat_t *vec2_tangent(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec2_rotate(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec2_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f); +mfloat_t *vec2_bezier3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t f); +mfloat_t *vec2_bezier4(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t *v3, mfloat_t f); +mfloat_t vec2_angle(mfloat_t *v0); +mfloat_t vec2_length(mfloat_t *v0); +mfloat_t vec2_length_squared(mfloat_t *v0); +mfloat_t vec2_distance(mfloat_t *v0, mfloat_t *v1); +mfloat_t vec2_distance_squared(mfloat_t *v0, mfloat_t *v1); +bool vec2_linear_independent(mfloat_t *v0, mfloat_t *v1); +mfloat_t** vec2_orthonormalization(mfloat_t result[2][2], mfloat_t basis[2][2]); +bool vec3_is_zero(mfloat_t *v0); +bool vec3_is_equal(mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z); +mfloat_t *vec3_assign(mfloat_t *result, mfloat_t *v0); +#if defined(MATHC_USE_INT) +mfloat_t *vec3_assign_vec3i(mfloat_t *result, mint_t *v0); +#endif +mfloat_t *vec3_zero(mfloat_t *result); +mfloat_t *vec3_one(mfloat_t *result); +mfloat_t *vec3_sign(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec3_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec3_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec3_multiply_mat3(mfloat_t *result, mfloat_t *v0, mfloat_t *m0); +mfloat_t *vec3_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec3_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec3_negative(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_abs(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_floor(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_ceil(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_round(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec3_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2); +mfloat_t *vec3_cross(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_normalize(mfloat_t *result, mfloat_t *v0); +mfloat_t vec3_dot(mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_project(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec3_slide(mfloat_t *result, mfloat_t *v0, mfloat_t *normal); +mfloat_t *vec3_reflect(mfloat_t *result, mfloat_t *v0, mfloat_t *normal); +mfloat_t *vec3_rotate(mfloat_t *result, mfloat_t *v0, mfloat_t *ra, mfloat_t f); +mfloat_t *vec3_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f); +mfloat_t *vec3_bezier3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t f); +mfloat_t *vec3_bezier4(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2, mfloat_t *v3, mfloat_t f); +mfloat_t vec3_length(mfloat_t *v0); +mfloat_t vec3_length_squared(mfloat_t *v0); +mfloat_t vec3_distance(mfloat_t *v0, mfloat_t *v1); +mfloat_t vec3_distance_squared(mfloat_t *v0, mfloat_t *v1); +bool vec3_linear_independent(mfloat_t *v0, mfloat_t *v1, mfloat_t *v2); +mfloat_t** vec3_orthonormalization(mfloat_t result[3][3], mfloat_t basis[3][3]); +bool vec4_is_zero(mfloat_t *v0); +bool vec4_is_equal(mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +mfloat_t *vec4_assign(mfloat_t *result, mfloat_t *v0); +#if defined(MATHC_USE_INT) +mfloat_t *vec4_assign_vec4i(mfloat_t *result, mint_t *v0); +#endif +mfloat_t *vec4_zero(mfloat_t *result); +mfloat_t *vec4_one(mfloat_t *result); +mfloat_t *vec4_sign(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_add(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_add_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec4_subtract(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_subtract_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec4_multiply(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_multiply_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec4_multiply_mat4(mfloat_t *result, mfloat_t *v0, mfloat_t *m0); +mfloat_t *vec4_divide(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_divide_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec4_snap(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_snap_f(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *vec4_negative(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_abs(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_floor(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_ceil(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_round(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_max(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_min(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *vec4_clamp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t *v2); +mfloat_t *vec4_normalize(mfloat_t *result, mfloat_t *v0); +mfloat_t *vec4_lerp(mfloat_t *result, mfloat_t *v0, mfloat_t *v1, mfloat_t f); +bool quat_is_zero(mfloat_t *q0); +bool quat_is_equal(mfloat_t *q0, mfloat_t *q1); +mfloat_t *quat(mfloat_t *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +mfloat_t *quat_assign(mfloat_t *result, mfloat_t *q0); +mfloat_t *quat_zero(mfloat_t *result); +mfloat_t *quat_null(mfloat_t *result); +mfloat_t *quat_multiply(mfloat_t *result, mfloat_t *q0, mfloat_t *q1); +mfloat_t *quat_multiply_f(mfloat_t *result, mfloat_t *q0, mfloat_t f); +mfloat_t *quat_divide(mfloat_t *result, mfloat_t *q0, mfloat_t *q1); +mfloat_t *quat_divide_f(mfloat_t *result, mfloat_t *q0, mfloat_t f); +mfloat_t *quat_negative(mfloat_t *result, mfloat_t *q0); +mfloat_t *quat_conjugate(mfloat_t *result, mfloat_t *q0); +mfloat_t *quat_inverse(mfloat_t *result, mfloat_t *q0); +mfloat_t *quat_normalize(mfloat_t *result, mfloat_t *q0); +mfloat_t quat_dot(mfloat_t *q0, mfloat_t *q1); +mfloat_t *quat_power(mfloat_t *result, mfloat_t *q0, mfloat_t exponent); +mfloat_t *quat_from_axis_angle(mfloat_t *result, mfloat_t *v0, mfloat_t angle); +mfloat_t *quat_from_vec3(mfloat_t *result, mfloat_t *v0, mfloat_t *v1); +mfloat_t *quat_from_mat4(mfloat_t *result, mfloat_t *m0); +mfloat_t *quat_lerp(mfloat_t *result, mfloat_t *q0, mfloat_t *q1, mfloat_t f); +mfloat_t *quat_slerp(mfloat_t *result, mfloat_t *q0, mfloat_t *q1, mfloat_t f); +mfloat_t quat_length(mfloat_t *q0); +mfloat_t quat_length_squared(mfloat_t *q0); +mfloat_t quat_angle(mfloat_t *q0, mfloat_t *q1); +mfloat_t *mat2(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22); +mfloat_t *mat2_zero(mfloat_t *result); +mfloat_t *mat2_identity(mfloat_t *result); +mfloat_t mat2_determinant(mfloat_t *m0); +mfloat_t *mat2_assign(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_negative(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_transpose(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_cofactor(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_adjugate(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1); +mfloat_t *mat2_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f); +mfloat_t *mat2_inverse(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat2_scaling(mfloat_t *result, mfloat_t *v0); +mfloat_t *mat2_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat2_rotation_z(mfloat_t *result, mfloat_t f); +mfloat_t *mat2_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f); +mfloat_t *mat3(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33); +mfloat_t *mat3_zero(mfloat_t *result); +mfloat_t *mat3_identity(mfloat_t *result); +mfloat_t mat3_determinant(mfloat_t *m0); +mfloat_t *mat3_assign(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat3_negative(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat3_transpose(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat3_cofactor(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat3_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1); +mfloat_t *mat3_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f); +mfloat_t *mat3_inverse(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat3_scaling(mfloat_t *result, mfloat_t *v0); +mfloat_t *mat3_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat3_rotation_x(mfloat_t *result, mfloat_t f); +mfloat_t *mat3_rotation_y(mfloat_t *result, mfloat_t f); +mfloat_t *mat3_rotation_z(mfloat_t *result, mfloat_t f); +mfloat_t *mat3_rotation_axis(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *mat3_rotation_quat(mfloat_t *result, mfloat_t *q0); +mfloat_t *mat3_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f); +mfloat_t *mat4(mfloat_t *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44); +mfloat_t *mat4_zero(mfloat_t *result); +mfloat_t *mat4_identity(mfloat_t *result); +mfloat_t mat4_determinant(mfloat_t *m0); +mfloat_t *mat4_assign(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat4_negative(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat4_transpose(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat4_cofactor(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat4_rotation_x(mfloat_t *result, mfloat_t f); +mfloat_t *mat4_rotation_y(mfloat_t *result, mfloat_t f); +mfloat_t *mat4_rotation_z(mfloat_t *result, mfloat_t f); +mfloat_t *mat4_rotation_axis(mfloat_t *result, mfloat_t *v0, mfloat_t f); +mfloat_t *mat4_rotation_quat(mfloat_t *result, mfloat_t *q0); +mfloat_t *mat4_translation(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat4_translate(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat4_scaling(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat4_scale(mfloat_t *result, mfloat_t *m0, mfloat_t *v0); +mfloat_t *mat4_multiply(mfloat_t *result, mfloat_t *m0, mfloat_t *m1); +mfloat_t *mat4_multiply_f(mfloat_t *result, mfloat_t *m0, mfloat_t f); +mfloat_t *mat4_inverse(mfloat_t *result, mfloat_t *m0); +mfloat_t *mat4_lerp(mfloat_t *result, mfloat_t *m0, mfloat_t *m1, mfloat_t f); +mfloat_t *mat4_look_at(mfloat_t *result, mfloat_t *position, mfloat_t *target, mfloat_t *up); +mfloat_t *mat4_ortho(mfloat_t *result, mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f); +mfloat_t *mat4_perspective(mfloat_t *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f); +mfloat_t *mat4_perspective_fov(mfloat_t *result, mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f); +mfloat_t *mat4_perspective_infinite(mfloat_t *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n); +#endif + +#if defined(MATHC_USE_STRUCT_FUNCTIONS) +#if defined(MATHC_USE_INT) +bool svec2i_is_zero(struct vec2i v0); +bool svec2i_is_equal(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i(mint_t x, mint_t y); +struct vec2i svec2i_assign(struct vec2i v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec2i svec2i_assign_vec2(struct vec2 v0); +#endif +struct vec2i svec2i_zero(void); +struct vec2i svec2i_one(void); +struct vec2i svec2i_sign(struct vec2i v0); +struct vec2i svec2i_add(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_add_i(struct vec2i v0, mint_t i); +struct vec2i svec2i_subtract(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_subtract_i(struct vec2i v0, mint_t i); +struct vec2i svec2i_multiply(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_multiply_i(struct vec2i v0, mint_t i); +struct vec2i svec2i_divide(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_divide_i(struct vec2i v0, mint_t i); +struct vec2i svec2i_snap(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_snap_i(struct vec2i v0, mint_t i); +struct vec2i svec2i_negative(struct vec2i v0); +struct vec2i svec2i_abs(struct vec2i v0); +struct vec2i svec2i_max(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_min(struct vec2i v0, struct vec2i v1); +struct vec2i svec2i_clamp(struct vec2i v0, struct vec2i v1, struct vec2i v2); +struct vec2i svec2i_tangent(struct vec2i v0); +bool svec3i_is_zero(struct vec3i v0); +bool svec3i_is_equal(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i(mint_t x, mint_t y, mint_t z); +struct vec3i svec3i_assign(struct vec3i v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec3i svec3i_assign_vec3(struct vec3 v0); +#endif +struct vec3i svec3i_zero(void); +struct vec3i svec3i_one(void); +struct vec3i svec3i_sign(struct vec3i v0); +struct vec3i svec3i_add(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_add_i(struct vec3i v0, mint_t i); +struct vec3i svec3i_subtract(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_subtract_i(struct vec3i v0, mint_t i); +struct vec3i svec3i_multiply(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_multiply_i(struct vec3i v0, mint_t i); +struct vec3i svec3i_divide(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_divide_i(struct vec3i v0, mint_t i); +struct vec3i svec3i_snap(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_snap_i(struct vec3i v0, mint_t i); +struct vec3i svec3i_cross(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_negative(struct vec3i v0); +struct vec3i svec3i_abs(struct vec3i v0); +struct vec3i svec3i_max(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_min(struct vec3i v0, struct vec3i v1); +struct vec3i svec3i_clamp(struct vec3i v0, struct vec3i v1, struct vec3i v2); +bool svec4i_is_zero(struct vec4i v0); +bool svec4i_is_equal(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i(mint_t x, mint_t y, mint_t z, mint_t w); +struct vec4i svec4i_assign(struct vec4i v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec4i svec4i_assign_vec4(struct vec4 v0); +#endif +struct vec4i svec4i_zero(void); +struct vec4i svec4i_one(void); +struct vec4i svec4i_sign(struct vec4i v0); +struct vec4i svec4i_add(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_add_i(struct vec4i v0, mint_t i); +struct vec4i svec4i_subtract(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_subtract_i(struct vec4i v0, mint_t i); +struct vec4i svec4i_multiply(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_multiply_i(struct vec4i v0, mint_t i); +struct vec4i svec4i_divide(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_divide_i(struct vec4i v0, mint_t i); +struct vec4i svec4i_snap(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_snap_i(struct vec4i v0, mint_t i); +struct vec4i svec4i_negative(struct vec4i v0); +struct vec4i svec4i_abs(struct vec4i v0); +struct vec4i svec4i_max(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_min(struct vec4i v0, struct vec4i v1); +struct vec4i svec4i_clamp(struct vec4i v0, struct vec4i v1, struct vec4i v2); +#endif +#if defined(MATHC_USE_FLOATING_POINT) +bool svec2_is_zero(struct vec2 v0); +bool svec2_is_equal(struct vec2 v0, struct vec2 v1); +struct vec2 svec2(mfloat_t x, mfloat_t y); +struct vec2 svec2_assign(struct vec2 v0); +#if defined(MATHC_USE_INT) +struct vec2 svec2_assign_vec2i(struct vec2i v0); +#endif +struct vec2 svec2_zero(void); +struct vec2 svec2_one(void); +struct vec2 svec2_sign(struct vec2 v0); +struct vec2 svec2_add(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_add_f(struct vec2 v0, mfloat_t f); +struct vec2 svec2_subtract(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_subtract_f(struct vec2 v0, mfloat_t f); +struct vec2 svec2_multiply(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_multiply_f(struct vec2 v0, mfloat_t f); +struct vec2 svec2_multiply_mat2(struct vec2 v0, struct mat2 m0); +struct vec2 svec2_divide(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_divide_f(struct vec2 v0, mfloat_t f); +struct vec2 svec2_snap(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_snap_f(struct vec2 v0, mfloat_t f); +struct vec2 svec2_negative(struct vec2 v0); +struct vec2 svec2_abs(struct vec2 v0); +struct vec2 svec2_floor(struct vec2 v0); +struct vec2 svec2_ceil(struct vec2 v0); +struct vec2 svec2_round(struct vec2 v0); +struct vec2 svec2_max(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_min(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_clamp(struct vec2 v0, struct vec2 v1, struct vec2 v2); +struct vec2 svec2_normalize(struct vec2 v0); +mfloat_t svec2_dot(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_project(struct vec2 v0, struct vec2 v1); +struct vec2 svec2_slide(struct vec2 v0, struct vec2 normal); +struct vec2 svec2_reflect(struct vec2 v0, struct vec2 normal); +struct vec2 svec2_tangent(struct vec2 v0); +struct vec2 svec2_rotate(struct vec2 v0, mfloat_t f); +struct vec2 svec2_lerp(struct vec2 v0, struct vec2 v1, mfloat_t f); +struct vec2 svec2_bezier3(struct vec2 v0, struct vec2 v1, struct vec2 v2, mfloat_t f); +struct vec2 svec2_bezier4(struct vec2 v0, struct vec2 v1, struct vec2 v2, struct vec2 v3, mfloat_t f); +mfloat_t svec2_angle(struct vec2 v0); +mfloat_t svec2_length(struct vec2 v0); +mfloat_t svec2_length_squared(struct vec2 v0); +mfloat_t svec2_distance(struct vec2 v0, struct vec2 v1); +mfloat_t svec2_distance_squared(struct vec2 v0, struct vec2 v1); +bool svec3_is_zero(struct vec3 v0); +bool svec3_is_equal(struct vec3 v0, struct vec3 v1); +struct vec3 svec3(mfloat_t x, mfloat_t y, mfloat_t z); +struct vec3 svec3_assign(struct vec3 v0); +#if defined(MATHC_USE_INT) +struct vec3 svec3_assign_vec3i(struct vec3i v0); +#endif +struct vec3 svec3_zero(void); +struct vec3 svec3_one(void); +struct vec3 svec3_sign(struct vec3 v0); +struct vec3 svec3_add(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_add_f(struct vec3 v0, mfloat_t f); +struct vec3 svec3_subtract(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_subtract_f(struct vec3 v0, mfloat_t f); +struct vec3 svec3_multiply(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_multiply_f(struct vec3 v0, mfloat_t f); +struct vec3 svec3_multiply_mat3(struct vec3 v0, struct mat3 m0); +struct vec3 svec3_divide(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_divide_f(struct vec3 v0, mfloat_t f); +struct vec3 svec3_snap(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_snap_f(struct vec3 v0, mfloat_t f); +struct vec3 svec3_negative(struct vec3 v0); +struct vec3 svec3_abs(struct vec3 v0); +struct vec3 svec3_floor(struct vec3 v0); +struct vec3 svec3_ceil(struct vec3 v0); +struct vec3 svec3_round(struct vec3 v0); +struct vec3 svec3_max(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_min(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_clamp(struct vec3 v0, struct vec3 v1, struct vec3 v2); +struct vec3 svec3_cross(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_normalize(struct vec3 v0); +mfloat_t svec3_dot(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_project(struct vec3 v0, struct vec3 v1); +struct vec3 svec3_slide(struct vec3 v0, struct vec3 normal); +struct vec3 svec3_reflect(struct vec3 v0, struct vec3 normal); +struct vec3 svec3_rotate(struct vec3 v0, struct vec3 ra, mfloat_t f); +struct vec3 svec3_lerp(struct vec3 v0, struct vec3 v1, mfloat_t f); +struct vec3 svec3_bezier3(struct vec3 v0, struct vec3 v1, struct vec3 v2, mfloat_t f); +struct vec3 svec3_bezier4(struct vec3 v0, struct vec3 v1, struct vec3 v2, struct vec3 v3, mfloat_t f); +mfloat_t svec3_length(struct vec3 v0); +mfloat_t svec3_length_squared(struct vec3 v0); +mfloat_t svec3_distance(struct vec3 v0, struct vec3 v1); +mfloat_t svec3_distance_squared(struct vec3 v0, struct vec3 v1); +bool svec4_is_zero(struct vec4 v0); +bool svec4_is_equal(struct vec4 v0, struct vec4 v1); +struct vec4 svec4(mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +struct vec4 svec4_assign(struct vec4 v0); +#if defined(MATHC_USE_INT) +struct vec4 svec4_assign_vec4i(struct vec4i v0); +#endif +struct vec4 svec4_zero(void); +struct vec4 svec4_one(void); +struct vec4 svec4_sign(struct vec4 v0); +struct vec4 svec4_add(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_add_f(struct vec4 v0, mfloat_t f); +struct vec4 svec4_subtract(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_subtract_f(struct vec4 v0, mfloat_t f); +struct vec4 svec4_multiply(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_multiply_f(struct vec4 v0, mfloat_t f); +struct vec4 svec4_multiply_mat4(struct vec4 v0, struct mat4 m0); +struct vec4 svec4_divide(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_divide_f(struct vec4 v0, mfloat_t f); +struct vec4 svec4_snap(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_snap_f(struct vec4 v0, mfloat_t f); +struct vec4 svec4_negative(struct vec4 v0); +struct vec4 svec4_abs(struct vec4 v0); +struct vec4 svec4_floor(struct vec4 v0); +struct vec4 svec4_ceil(struct vec4 v0); +struct vec4 svec4_round(struct vec4 v0); +struct vec4 svec4_max(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_min(struct vec4 v0, struct vec4 v1); +struct vec4 svec4_clamp(struct vec4 v0, struct vec4 v1, struct vec4 v2); +struct vec4 svec4_normalize(struct vec4 v0); +struct vec4 svec4_lerp(struct vec4 v0, struct vec4 v1, mfloat_t f); +bool squat_is_zero(struct quat q0); +bool squat_is_equal(struct quat q0, struct quat q1); +struct quat squat(mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +struct quat squat_assign(struct quat q0); +struct quat squat_zero(void); +struct quat squat_null(void); +struct quat squat_multiply(struct quat q0, struct quat q1); +struct quat squat_multiply_f(struct quat q0, mfloat_t f); +struct quat squat_divide(struct quat q0, struct quat q1); +struct quat squat_divide_f(struct quat q0, mfloat_t f); +struct quat squat_negative(struct quat q0); +struct quat squat_conjugate(struct quat q0); +struct quat squat_inverse(struct quat q0); +struct quat squat_normalize(struct quat q0); +mfloat_t squat_dot(struct quat q0, struct quat q1); +struct quat squat_power(struct quat q0, mfloat_t exponent); +struct quat squat_from_axis_angle(struct vec3 v0, mfloat_t angle); +struct quat squat_from_vec3(struct vec3 v0, struct vec3 v1); +struct quat squat_from_mat4(struct mat4 m0); +struct quat squat_lerp(struct quat q0, struct quat q1, mfloat_t f); +struct quat squat_slerp(struct quat q0, struct quat q1, mfloat_t f); +mfloat_t squat_length(struct quat q0); +mfloat_t squat_length_squared(struct quat q0); +mfloat_t squat_angle(struct quat q0, struct quat q1); +struct mat2 smat2(mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22); +struct mat2 smat2_zero(void); +struct mat2 smat2_identity(void); +mfloat_t smat2_determinant(struct mat2 m0); +struct mat2 smat2_assign(struct mat2 m0); +struct mat2 smat2_negative(struct mat2 m0); +struct mat2 smat2_transpose(struct mat2 m0); +struct mat2 smat2_cofactor(struct mat2 m0); +struct mat2 smat2_adjugate(struct mat2 m0); +struct mat2 smat2_multiply(struct mat2 m0, struct mat2 m1); +struct mat2 smat2_multiply_f(struct mat2 m0, mfloat_t f); +struct mat2 smat2_inverse(struct mat2 m0); +struct mat2 smat2_scaling(struct vec2 v0); +struct mat2 smat2_scale(struct mat2 m0, struct vec2 v0); +struct mat2 smat2_rotation_z(mfloat_t f); +struct mat2 smat2_lerp(struct mat2 m0, struct mat2 m1, mfloat_t f); +struct mat3 smat3(mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33); +struct mat3 smat3_zero(void); +struct mat3 smat3_identity(void); +mfloat_t smat3_determinant(struct mat3 m0); +struct mat3 smat3_assign(struct mat3 m0); +struct mat3 smat3_negative(struct mat3 m0); +struct mat3 smat3_transpose(struct mat3 m0); +struct mat3 smat3_cofactor(struct mat3 m0); +struct mat3 smat3_multiply(struct mat3 m0, struct mat3 m1); +struct mat3 smat3_multiply_f(struct mat3 m0, mfloat_t f); +struct mat3 smat3_inverse(struct mat3 m0); +struct mat3 smat3_scaling(struct vec3 v0); +struct mat3 smat3_scale(struct mat3 m0, struct vec3 v0); +struct mat3 smat3_rotation_x(mfloat_t f); +struct mat3 smat3_rotation_y(mfloat_t f); +struct mat3 smat3_rotation_z(mfloat_t f); +struct mat3 smat3_rotation_axis(struct vec3 v0, mfloat_t f); +struct mat3 smat3_rotation_quat(struct quat q0); +struct mat3 smat3_lerp(struct mat3 m0, struct mat3 m1, mfloat_t f); +struct mat4 smat4(mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44); +struct mat4 smat4_zero(void); +struct mat4 smat4_identity(void); +mfloat_t smat4_determinant(struct mat4 m0); +struct mat4 smat4_assign(struct mat4 m0); +struct mat4 smat4_negative(struct mat4 m0); +struct mat4 smat4_transpose(struct mat4 m0); +struct mat4 smat4_cofactor(struct mat4 m0); +struct mat4 smat4_rotation_x(mfloat_t f); +struct mat4 smat4_rotation_y(mfloat_t f); +struct mat4 smat4_rotation_z(mfloat_t f); +struct mat4 smat4_rotation_axis(struct vec3 v0, mfloat_t f); +struct mat4 smat4_rotation_quat(struct quat q0); +struct mat4 smat4_translation(struct mat4 m0, struct vec3 v0); +struct mat4 smat4_translate(struct mat4 m0, struct vec3 v0); +struct mat4 smat4_scaling(struct mat4 m0, struct vec3 v0); +struct mat4 smat4_scale(struct mat4 m0, struct vec3 v0); +struct mat4 smat4_multiply(struct mat4 m0, struct mat4 m1); +struct mat4 smat4_multiply_f(struct mat4 m0, mfloat_t f); +struct mat4 smat4_inverse(struct mat4 m0); +struct mat4 smat4_lerp(struct mat4 m0, struct mat4 m1, mfloat_t f); +struct mat4 smat4_look_at(struct vec3 position, struct vec3 target, struct vec3 up); +struct mat4 smat4_ortho(mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f); +struct mat4 smat4_perspective(mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f); +struct mat4 smat4_perspective_fov(mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f); +struct mat4 smat4_perspective_infinite(mfloat_t fov_y, mfloat_t aspect, mfloat_t n); +#endif +#endif + +#if defined(MATHC_USE_POINTER_STRUCT_FUNCTIONS) +#if defined(MATHC_USE_INT) +bool psvec2i_is_zero(struct vec2i *v0); +bool psvec2i_is_equal(struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i(struct vec2i *result, mint_t x, mint_t y); +struct vec2i *psvec2i_assign(struct vec2i *result, struct vec2i *v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec2i *psvec2i_assign_vec2(struct vec2i *result, struct vec2 *v0); +#endif +struct vec2i *psvec2i_zero(struct vec2i *result); +struct vec2i *psvec2i_one(struct vec2i *result); +struct vec2i *psvec2i_sign(struct vec2i *result, struct vec2i *v0); +struct vec2i *psvec2i_add(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_add_i(struct vec2i *result, struct vec2i *v0, mint_t i); +struct vec2i *psvec2i_subtract(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_subtract_i(struct vec2i *result, struct vec2i *v0, mint_t i); +struct vec2i *psvec2i_multiply(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_multiply_i(struct vec2i *result, struct vec2i *v0, mint_t i); +struct vec2i *psvec2i_divide(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_divide_i(struct vec2i *result, struct vec2i *v0, mint_t i); +struct vec2i *psvec2i_snap(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_snap_i(struct vec2i *result, struct vec2i *v0, mint_t i); +struct vec2i *psvec2i_negative(struct vec2i *result, struct vec2i *v0); +struct vec2i *psvec2i_abs(struct vec2i *result, struct vec2i *v0); +struct vec2i *psvec2i_max(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_min(struct vec2i *result, struct vec2i *v0, struct vec2i *v1); +struct vec2i *psvec2i_clamp(struct vec2i *result, struct vec2i *v0, struct vec2i *v1, struct vec2i *v2); +struct vec2i *psvec2i_tangent(struct vec2i *result, struct vec2i *v0); +bool psvec3i_is_zero(struct vec3i *v0); +bool psvec3i_is_equal(struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i(struct vec3i *result, mint_t x, mint_t y, mint_t z); +struct vec3i *psvec3i_assign(struct vec3i *result, struct vec3i *v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec3i *psvec3i_assign_vec3(struct vec3i *result, struct vec3 *v0); +#endif +struct vec3i *psvec3i_zero(struct vec3i *result); +struct vec3i *psvec3i_one(struct vec3i *result); +struct vec3i *psvec3i_sign(struct vec3i *result, struct vec3i *v0); +struct vec3i *psvec3i_add(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_add_i(struct vec3i *result, struct vec3i *v0, mint_t i); +struct vec3i *psvec3i_subtract(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_subtract_i(struct vec3i *result, struct vec3i *v0, mint_t i); +struct vec3i *psvec3i_multiply(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_multiply_i(struct vec3i *result, struct vec3i *v0, mint_t i); +struct vec3i *psvec3i_divide(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_divide_i(struct vec3i *result, struct vec3i *v0, mint_t i); +struct vec3i *psvec3i_snap(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_snap_i(struct vec3i *result, struct vec3i *v0, mint_t i); +struct vec3i *psvec3i_cross(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_negative(struct vec3i *result, struct vec3i *v0); +struct vec3i *psvec3i_abs(struct vec3i *result, struct vec3i *v0); +struct vec3i *psvec3i_max(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_min(struct vec3i *result, struct vec3i *v0, struct vec3i *v1); +struct vec3i *psvec3i_clamp(struct vec3i *result, struct vec3i *v0, struct vec3i *v1, struct vec3i *v2); +bool psvec4i_is_zero(struct vec4i *v0); +bool psvec4i_is_equal(struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i(struct vec4i *result, mint_t x, mint_t y, mint_t z, mint_t w); +struct vec4i *psvec4i_assign(struct vec4i *result, struct vec4i *v0); +#if defined(MATHC_USE_FLOATING_POINT) +struct vec4i *psvec4i_assign_vec4(struct vec4i *result, struct vec4 *v0); +#endif +struct vec4i *psvec4i_zero(struct vec4i *result); +struct vec4i *psvec4i_one(struct vec4i *result); +struct vec4i *psvec4i_sign(struct vec4i *result, struct vec4i *v0); +struct vec4i *psvec4i_add(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_add_i(struct vec4i *result, struct vec4i *v0, mint_t i); +struct vec4i *psvec4i_subtract(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_subtract_i(struct vec4i *result, struct vec4i *v0, mint_t i); +struct vec4i *psvec4i_multiply(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_multiply_i(struct vec4i *result, struct vec4i *v0, mint_t i); +struct vec4i *psvec4i_divide(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_divide_i(struct vec4i *result, struct vec4i *v0, mint_t i); +struct vec4i *psvec4i_snap(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_snap_i(struct vec4i *result, struct vec4i *v0, mint_t i); +struct vec4i *psvec4i_negative(struct vec4i *result, struct vec4i *v0); +struct vec4i *psvec4i_abs(struct vec4i *result, struct vec4i *v0); +struct vec4i *psvec4i_max(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_min(struct vec4i *result, struct vec4i *v0, struct vec4i *v1); +struct vec4i *psvec4i_clamp(struct vec4i *result, struct vec4i *v0, struct vec4i *v1, struct vec4i *v2); +#endif +#if defined(MATHC_USE_FLOATING_POINT) +bool psvec2_is_zero(struct vec2 *v0); +bool psvec2_is_equal(struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2(struct vec2 *result, mfloat_t x, mfloat_t y); +struct vec2 *psvec2_assign(struct vec2 *result, struct vec2 *v0); +#if defined(MATHC_USE_INT) +struct vec2 *psvec2_assign_vec2i(struct vec2 *result, struct vec2i *v0); +#endif +struct vec2 *psvec2_zero(struct vec2 *result); +struct vec2 *psvec2_one(struct vec2 *result); +struct vec2 *psvec2_sign(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_add(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_add_f(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_subtract(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_subtract_f(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_multiply(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_multiply_f(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_multiply_mat2(struct vec2 *result, struct vec2 *v0, struct mat2 *m0); +struct vec2 *psvec2_divide(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_divide_f(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_snap(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_snap_f(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_negative(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_abs(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_floor(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_ceil(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_round(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_max(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_min(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_clamp(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2); +struct vec2 *psvec2_normalize(struct vec2 *result, struct vec2 *v0); +mfloat_t psvec2_dot(struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_project(struct vec2 *result, struct vec2 *v0, struct vec2 *v1); +struct vec2 *psvec2_slide(struct vec2 *result, struct vec2 *v0, struct vec2 *normal); +struct vec2 *psvec2_reflect(struct vec2 *result, struct vec2 *v0, struct vec2 *normal); +struct vec2 *psvec2_tangent(struct vec2 *result, struct vec2 *v0); +struct vec2 *psvec2_rotate(struct vec2 *result, struct vec2 *v0, mfloat_t f); +struct vec2 *psvec2_lerp(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, mfloat_t f); +struct vec2 *psvec2_bezier3(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2, mfloat_t f); +struct vec2 *psvec2_bezier4(struct vec2 *result, struct vec2 *v0, struct vec2 *v1, struct vec2 *v2, struct vec2 *v3, mfloat_t f); +mfloat_t psvec2_angle(struct vec2 *v0); +mfloat_t psvec2_length(struct vec2 *v0); +mfloat_t psvec2_length_squared(struct vec2 *v0); +mfloat_t psvec2_distance(struct vec2 *v0, struct vec2 *v1); +mfloat_t psvec2_distance_squared(struct vec2 *v0, struct vec2 *v1); +bool psvec3_is_zero(struct vec3 *v0); +bool psvec3_is_equal(struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3(struct vec3 *result, mfloat_t x, mfloat_t y, mfloat_t z); +struct vec3 *psvec3_assign(struct vec3 *result, struct vec3 *v0); +#if defined(MATHC_USE_INT) +struct vec3 *psvec3_assign_vec3i(struct vec3 *result, struct vec3i *v0); +#endif +struct vec3 *psvec3_zero(struct vec3 *result); +struct vec3 *psvec3_one(struct vec3 *result); +struct vec3 *psvec3_sign(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_add(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_add_f(struct vec3 *result, struct vec3 *v0, mfloat_t f); +struct vec3 *psvec3_subtract(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_subtract_f(struct vec3 *result, struct vec3 *v0, mfloat_t f); +struct vec3 *psvec3_multiply(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_multiply_f(struct vec3 *result, struct vec3 *v0, mfloat_t f); +struct vec3 *psvec3_multiply_mat3(struct vec3 *result, struct vec3 *v0, struct mat3 *m0); +struct vec3 *psvec3_divide(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_divide_f(struct vec3 *result, struct vec3 *v0, mfloat_t f); +struct vec3 *psvec3_snap(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_snap_f(struct vec3 *result, struct vec3 *v0, mfloat_t f); +struct vec3 *psvec3_negative(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_abs(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_floor(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_ceil(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_round(struct vec3 *result, struct vec3 *v0); +struct vec3 *psvec3_max(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_min(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_clamp(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2); +struct vec3 *psvec3_cross(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_normalize(struct vec3 *result, struct vec3 *v0); +mfloat_t psvec3_dot(struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_project(struct vec3 *result, struct vec3 *v0, struct vec3 *v1); +struct vec3 *psvec3_slide(struct vec3 *result, struct vec3 *v0, struct vec3 *normal); +struct vec3 *psvec3_reflect(struct vec3 *result, struct vec3 *v0, struct vec3 *normal); +struct vec3 *psvec3_rotate(struct vec3 *result, struct vec3 *v0, struct vec3 *ra, mfloat_t f); +struct vec3 *psvec3_lerp(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, mfloat_t f); +struct vec3 *psvec3_bezier3(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2, mfloat_t f); +struct vec3 *psvec3_bezier4(struct vec3 *result, struct vec3 *v0, struct vec3 *v1, struct vec3 *v2, struct vec3 *v3, mfloat_t f); +mfloat_t psvec3_length(struct vec3 *v0); +mfloat_t psvec3_length_squared(struct vec3 *v0); +mfloat_t psvec3_distance(struct vec3 *v0, struct vec3 *v1); +mfloat_t psvec3_distance_squared(struct vec3 *v0, struct vec3 *v1); +bool psvec4_is_zero(struct vec4 *v0); +bool psvec4_is_equal(struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4(struct vec4 *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +struct vec4 *psvec4_assign(struct vec4 *result, struct vec4 *v0); +#if defined(MATHC_USE_INT) +struct vec4 *psvec4_assign_vec4i(struct vec4 *result, struct vec4i *v0); +#endif +struct vec4 *psvec4_zero(struct vec4 *result); +struct vec4 *psvec4_one(struct vec4 *result); +struct vec4 *psvec4_sign(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_add(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_add_f(struct vec4 *result, struct vec4 *v0, mfloat_t f); +struct vec4 *psvec4_subtract(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_subtract_f(struct vec4 *result, struct vec4 *v0, mfloat_t f); +struct vec4 *psvec4_multiply(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_multiply_f(struct vec4 *result, struct vec4 *v0, mfloat_t f); +struct vec4 *psvec4_multiply_mat4(struct vec4 *result, struct vec4 *v0, struct mat4 *m0); +struct vec4 *psvec4_divide(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_divide_f(struct vec4 *result, struct vec4 *v0, mfloat_t f); +struct vec4 *psvec4_snap(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_snap_f(struct vec4 *result, struct vec4 *v0, mfloat_t f); +struct vec4 *psvec4_negative(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_abs(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_floor(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_ceil(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_round(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_max(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_min(struct vec4 *result, struct vec4 *v0, struct vec4 *v1); +struct vec4 *psvec4_clamp(struct vec4 *result, struct vec4 *v0, struct vec4 *v1, struct vec4 *v2); +struct vec4 *psvec4_normalize(struct vec4 *result, struct vec4 *v0); +struct vec4 *psvec4_lerp(struct vec4 *result, struct vec4 *v0, struct vec4 *v1, mfloat_t f); +bool psquat_is_zero(struct quat *q0); +bool psquat_is_equal(struct quat *q0, struct quat *q1); +struct quat *psquat(struct quat *result, mfloat_t x, mfloat_t y, mfloat_t z, mfloat_t w); +struct quat *psquat_assign(struct quat *result, struct quat *q0); +struct quat *psquat_zero(struct quat *result); +struct quat *psquat_null(struct quat *result); +struct quat *psquat_multiply(struct quat *result, struct quat *q0, struct quat *q1); +struct quat *psquat_multiply_f(struct quat *result, struct quat *q0, mfloat_t f); +struct quat *psquat_divide(struct quat *result, struct quat *q0, struct quat *q1); +struct quat *psquat_divide_f(struct quat *result, struct quat *q0, mfloat_t f); +struct quat *psquat_negative(struct quat *result, struct quat *q0); +struct quat *psquat_conjugate(struct quat *result, struct quat *q0); +struct quat *psquat_inverse(struct quat *result, struct quat *q0); +struct quat *psquat_normalize(struct quat *result, struct quat *q0); +mfloat_t psquat_dot(struct quat *q0, struct quat *q1); +struct quat *psquat_power(struct quat *result, struct quat *q0, mfloat_t exponent); +struct quat *psquat_from_axis_angle(struct quat *result, struct vec3 *v0, mfloat_t angle); +struct quat *psquat_from_vec3(struct quat *result, struct vec3 *v0, struct vec3 *v1); +struct quat *psquat_from_mat4(struct quat *result, struct mat4 *m0); +struct quat *psquat_lerp(struct quat *result, struct quat *q0, struct quat *q1, mfloat_t f); +struct quat *psquat_slerp(struct quat *result, struct quat *q0, struct quat *q1, mfloat_t f); +mfloat_t psquat_length(struct quat *q0); +mfloat_t psquat_length_squared(struct quat *q0); +mfloat_t psquat_angle(struct quat *q0, struct quat *q1); +struct mat2 *psmat2(struct mat2 *result, mfloat_t m11, mfloat_t m12, mfloat_t m21, mfloat_t m22); +struct mat2 *psmat2_zero(struct mat2 *result); +struct mat2 *psmat2_identity(struct mat2 *result); +mfloat_t psmat2_determinant(struct mat2 *m0); +struct mat2 *psmat2_assign(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_negative(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_transpose(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_cofactor(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_adjugate(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_multiply(struct mat2 *result, struct mat2 *m0, struct mat2 *m1); +struct mat2 *psmat2_multiply_f(struct mat2 *result, struct mat2 *m0, mfloat_t f); +struct mat2 *psmat2_inverse(struct mat2 *result, struct mat2 *m0); +struct mat2 *psmat2_scaling(struct mat2 *result, struct vec2 *v0); +struct mat2 *psmat2_scale(struct mat2 *result, struct mat2 *m0, struct vec2 *v0); +struct mat2 *psmat2_rotation_z(struct mat2 *result, mfloat_t f); +struct mat2 *psmat2_lerp(struct mat2 *result, struct mat2 *m0, struct mat2 *m1, mfloat_t f); +struct mat3 *psmat3(struct mat3 *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m31, mfloat_t m32, mfloat_t m33); +struct mat3 *psmat3_zero(struct mat3 *result); +struct mat3 *psmat3_identity(struct mat3 *result); +mfloat_t psmat3_determinant(struct mat3 *m0); +struct mat3 *psmat3_assign(struct mat3 *result, struct mat3 *m0); +struct mat3 *psmat3_negative(struct mat3 *result, struct mat3 *m0); +struct mat3 *psmat3_transpose(struct mat3 *result, struct mat3 *m0); +struct mat3 *psmat3_cofactor(struct mat3 *result, struct mat3 *m0); +struct mat3 *psmat3_multiply(struct mat3 *result, struct mat3 *m0, struct mat3 *m1); +struct mat3 *psmat3_multiply_f(struct mat3 *result, struct mat3 *m0, mfloat_t f); +struct mat3 *psmat3_inverse(struct mat3 *result, struct mat3 *m0); +struct mat3 *psmat3_scaling(struct mat3 *result, struct vec3 *v0); +struct mat3 *psmat3_scale(struct mat3 *result, struct mat3 *m0, struct vec3 *v0); +struct mat3 *psmat3_rotation_x(struct mat3 *result, mfloat_t f); +struct mat3 *psmat3_rotation_y(struct mat3 *result, mfloat_t f); +struct mat3 *psmat3_rotation_z(struct mat3 *result, mfloat_t f); +struct mat3 *psmat3_rotation_axis(struct mat3 *result, struct vec3 *v0, mfloat_t f); +struct mat3 *psmat3_rotation_quat(struct mat3 *result, struct quat *q0); +struct mat3 *psmat3_lerp(struct mat3 *result, struct mat3 *m0, struct mat3 *m1, mfloat_t f); +struct mat4 *psmat4(struct mat4 *result, mfloat_t m11, mfloat_t m12, mfloat_t m13, mfloat_t m14, mfloat_t m21, mfloat_t m22, mfloat_t m23, mfloat_t m24, mfloat_t m31, mfloat_t m32, mfloat_t m33, mfloat_t m34, mfloat_t m41, mfloat_t m42, mfloat_t m43, mfloat_t m44); +struct mat4 *psmat4_zero(struct mat4 *result); +struct mat4 *psmat4_identity(struct mat4 *result); +mfloat_t psmat4_determinant(struct mat4 *m0); +struct mat4 *psmat4_assign(struct mat4 *result, struct mat4 *m0); +struct mat4 *psmat4_negative(struct mat4 *result, struct mat4 *m0); +struct mat4 *psmat4_transpose(struct mat4 *result, struct mat4 *m0); +struct mat4 *psmat4_cofactor(struct mat4 *result, struct mat4 *m0); +struct mat4 *psmat4_rotation_x(struct mat4 *result, mfloat_t f); +struct mat4 *psmat4_rotation_y(struct mat4 *result, mfloat_t f); +struct mat4 *psmat4_rotation_z(struct mat4 *result, mfloat_t f); +struct mat4 *psmat4_rotation_axis(struct mat4 *result, struct vec3 *v0, mfloat_t f); +struct mat4 *psmat4_rotation_quat(struct mat4 *result, struct quat *q0); +struct mat4 *psmat4_translation(struct mat4 *result, struct mat4 *m0, struct vec3 *v0); +struct mat4 *psmat4_translate(struct mat4 *result, struct mat4 *m0, struct vec3 *v0); +struct mat4 *psmat4_scaling(struct mat4 *result, struct mat4 *m0, struct vec3 *v0); +struct mat4 *psmat4_scale(struct mat4 *result, struct mat4 *m0, struct vec3 *v0); +struct mat4 *psmat4_multiply(struct mat4 *result, struct mat4 *m0, struct mat4 *m1); +struct mat4 *psmat4_multiply_f(struct mat4 *result, struct mat4 *m0, mfloat_t f); +struct mat4 *psmat4_inverse(struct mat4 *result, struct mat4 *m0); +struct mat4 *psmat4_lerp(struct mat4 *result, struct mat4 *m0, struct mat4 *m1, mfloat_t f); +struct mat4 *psmat4_look_at(struct mat4 *result, struct vec3 *position, struct vec3 *target, struct vec3 *up); +struct mat4 *psmat4_ortho(struct mat4 *result, mfloat_t l, mfloat_t r, mfloat_t b, mfloat_t t, mfloat_t n, mfloat_t f); +struct mat4 *psmat4_perspective(struct mat4 *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n, mfloat_t f); +struct mat4 *psmat4_perspective_fov(struct mat4 *result, mfloat_t fov, mfloat_t w, mfloat_t h, mfloat_t n, mfloat_t f); +struct mat4 *psmat4_perspective_infinite(struct mat4 *result, mfloat_t fov_y, mfloat_t aspect, mfloat_t n); +#endif +#endif + +#if defined(MATHC_USE_FLOATING_POINT) && defined(MATHC_USE_EASING_FUNCTIONS) +mfloat_t quadratic_ease_out(mfloat_t f); +mfloat_t quadratic_ease_in(mfloat_t f); +mfloat_t quadratic_ease_in_out(mfloat_t f); +mfloat_t cubic_ease_out(mfloat_t f); +mfloat_t cubic_ease_in(mfloat_t f); +mfloat_t cubic_ease_in_out(mfloat_t f); +mfloat_t quartic_ease_out(mfloat_t f); +mfloat_t quartic_ease_in(mfloat_t f); +mfloat_t quartic_ease_in_out(mfloat_t f); +mfloat_t quintic_ease_out(mfloat_t f); +mfloat_t quintic_ease_in(mfloat_t f); +mfloat_t quintic_ease_in_out(mfloat_t f); +mfloat_t sine_ease_out(mfloat_t f); +mfloat_t sine_ease_in(mfloat_t f); +mfloat_t sine_ease_in_out(mfloat_t f); +mfloat_t circular_ease_out(mfloat_t f); +mfloat_t circular_ease_in(mfloat_t f); +mfloat_t circular_ease_in_out(mfloat_t f); +mfloat_t exponential_ease_out(mfloat_t f); +mfloat_t exponential_ease_in(mfloat_t f); +mfloat_t exponential_ease_in_out(mfloat_t f); +mfloat_t elastic_ease_out(mfloat_t f); +mfloat_t elastic_ease_in(mfloat_t f); +mfloat_t elastic_ease_in_out(mfloat_t f); +mfloat_t back_ease_out(mfloat_t f); +mfloat_t back_ease_in(mfloat_t f); +mfloat_t back_ease_in_out(mfloat_t f); +mfloat_t bounce_ease_out(mfloat_t f); +mfloat_t bounce_ease_in(mfloat_t f); +mfloat_t bounce_ease_in_out(mfloat_t f); +#endif #endif diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index 6be4c21..0000000 --- a/run_tests.sh +++ /dev/null @@ -1,17 +0,0 @@ -if [ -n $CC ] -then - if [ $CC=clang ] - then - clang test.c -include mathc.h -c mathc.c && clang -o test_clang test.o mathc.o -lm && chmod +x test_clang - ./test_clang - elif [ $CC=gcc ] - then - gcc -o test_gcc test.c mathc.c -I. -lm && chmod +x test_gcc - ./test_gcc - else - echo -e "unrecognized compiler" - exit - fi -else - echo -e "CC is not defined, compiler cannot be identified" -fi diff --git a/test.c b/test.c deleted file mode 100644 index ea98a98..0000000 --- a/test.c +++ /dev/null @@ -1,410 +0,0 @@ -/* -Copyright (C) 2016 Felipe Ferreira da Silva - -This software is provided 'as-is', without any express or implied warranty. In -no event will the authors be held liable for any damages arising from the use of -this software. - -Permission is granted to anyone to use this software for any purpose, including -commercial applications, and to alter it and redistribute it freely, subject to -the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not claim - that you wrote the original software. If you use this software in a - product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include -#include -#include -#include -#include "mathc.h" - -const float epsilon = FLT_EPSILON; - -struct cerror { - int32_t failed; - int32_t passed; - int32_t passed_with_e10; - int32_t passed_with_e100; - int32_t passed_with_e1000; -}; - -void printf_1f_test(struct cerror *error, char *msg, float e1, float r1) -{ - bool done = false; - printf("%s:\n\tExpected % .4f\n\t Actual % .4f\t", msg, e1, r1); - if (nearly_equal(e1, r1, epsilon)) { - error->passed = error->passed + 1; - done = true; - printf("~passed~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 10.0f)) { - error->passed_with_e10 = error->passed_with_e10 + 1; - done = true; - printf("~passed with epsilon * 10.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 100.0f)) { - error->passed_with_e100 = error->passed_with_e100 + 1; - done = true; - printf("~passed with epsilon * 100.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 1000.0f)) { - error->passed_with_e1000 = error->passed_with_e1000 + 1; - done = true; - printf("~passed with epsilon * 1000.0~\n\n"); - } - if (!done) { - error->failed = error->failed + 1; - printf("~failed~\n\n"); - } -} - -void printf_2f_test(struct cerror *error, char *msg, float e1, float e2, float r1, float r2) -{ - bool done = false; - printf("%s:\n\tExpected % .4f, % .4f\n\t Actual % .4f, % .4f\t", msg, e1, e2, r1, r2); - if (nearly_equal(e1, r1, epsilon) && nearly_equal(e2, r2, epsilon)) { - error->passed = error->passed + 1; - done = true; - printf("~passed~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 10.0f) && nearly_equal(e2, r2, epsilon * 10.0f)) { - error->passed_with_e10 = error->passed_with_e10 + 1; - done = true; - printf("~passed with epsilon * 10.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 100.0f) && nearly_equal(e2, r2, epsilon * 100.0f)) { - error->passed_with_e100 = error->passed_with_e100 + 1; - done = true; - printf("~passed with epsilon * 100.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 1000.0f) && nearly_equal(e2, r2, epsilon * 1000.0f)) { - error->passed_with_e1000 = error->passed_with_e1000 + 1; - done = true; - printf("~passed with epsilon * 1000.0~\n\n"); - } - if (!done) { - error->failed = error->failed + 1; - printf("~failed~\n\n"); - } -} - -void printf_3f_test(struct cerror *error, char *msg, float e1, float e2, float e3, float r1, float r2, float r3) -{ - bool done = false; - printf("%s:\n\tExpected % .4f, % .4f, % .4f\n\t Actual % .4f, % .4f, % .4f\t", msg, e1, e2, e3, r1, r2, r3); - if (nearly_equal(e1, r1, epsilon) && nearly_equal(e2, r2, epsilon) && nearly_equal(e3, r3, epsilon)) { - error->passed = error->passed + 1; - done = true; - printf("~passed~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 10.0f) && nearly_equal(e2, r2, epsilon * 10.0f) && nearly_equal(e3, r3, epsilon * 10.0f)) { - error->passed_with_e10 = error->passed_with_e10 + 1; - done = true; - printf("~passed with epsilon * 10.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 100.0f) && nearly_equal(e2, r2, epsilon * 100.0f) && nearly_equal(e2, r2, epsilon * 100.0f)) { - error->passed_with_e100 = error->passed_with_e100 + 1; - done = true; - printf("~passed with epsilon * 100.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 1000.0f) && nearly_equal(e2, r2, epsilon * 1000.0f) && nearly_equal(e2, r2, epsilon * 1000.0f)) { - error->passed_with_e1000 = error->passed_with_e1000 + 1; - done = true; - printf("~passed with epsilon * 1000.0~\n\n"); - } - if (!done) { - error->failed = error->failed + 1; - printf("~failed~\n\n"); - } -} - -void printf_4f_test(struct cerror *error, char *msg, float e1, float e2, float e3, float e4, float r1, float r2, float r3, float r4) -{ - bool done = false; - printf("%s:\n\tExpected % .9f, % .9f, % .9f, % .9f\n\t Actual % .9f, % .9f, % .9f, % .9f\t", msg, e1, e2, e3, e4, r1, r2, r3, r4); - if (nearly_equal(e1, r1, epsilon) && nearly_equal(e2, r2, epsilon) && nearly_equal(e3, r3, epsilon) && nearly_equal(e3, r3, epsilon)) { - error->passed = error->passed + 1; - done = true; - printf("~passed~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 10.0f) && nearly_equal(e2, r2, epsilon * 10.0f) && nearly_equal(e3, r3, epsilon * 10.0f) && nearly_equal(e3, r3, epsilon * 10.0f)) { - error->passed_with_e10 = error->passed_with_e10 + 1; - done = true; - printf("~passed with epsilon * 10.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 100.0f) && nearly_equal(e2, r2, epsilon * 100.0f) && nearly_equal(e3, r3, epsilon * 100.0f) && nearly_equal(e4, r4, epsilon * 100.0f)) { - error->passed_with_e100 = error->passed_with_e100 + 1; - done = true; - printf("~passed with epsilon * 100.0~\n\n"); - } - if (!done && nearly_equal(e1, r1, epsilon * 1000.0f) && nearly_equal(e2, r2, epsilon * 1000.0f) && nearly_equal(e3, r3, epsilon * 1000.0f) && nearly_equal(e4, r4, epsilon * 1000.0f)) { - error->passed_with_e1000 = error->passed_with_e1000 + 1; - done = true; - printf("~passed with epsilon * 1000.0~\n\n"); - } - if (!done) { - error->failed = error->failed + 1; - printf("~failed~\n\n"); - } -} - -void vector2_tests(struct cerror *error) -{ - struct vec a; - struct vec b; - struct vec r; - float p; - printf("\n# Making tests with 2D vectors...\n"); - a = to_vector2(1.11f, 2.5f); - b = to_vector2(0.9f, 1.3f); - r = vector2_add(a, b); - printf_2f_test(error, "Add two vectors", 2.01f, 3.8f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - b = to_vector2(0.9f, 1.3f); - r = vector2_subtract(a, b); - printf_2f_test(error, "Subtract two vectors", 0.21f, 1.2f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - r = vector2_scale(a, 3.3f); - printf_2f_test(error, "Scale vector", 3.663f, 8.25f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - b = to_vector2(0.9f, 1.3f); - r = vector2_multiply(a, b); - printf_2f_test(error, "Multiply two vectors", 0.999f, 3.25f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - b = to_vector2(0.9f, 1.3f); - r = vector2_divide(a, b); - printf_2f_test(error, "Divide two vectors", 1.2333333333f, 1.9230769231f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - r = vector2_negative(a); - printf_2f_test(error, "Negative vector", -1.11f, -2.5f, r.x, r.y); - a = to_vector2(1.11f, 2.5f); - r = vector2_inverse(a); - printf_2f_test(error, "Inverse vector", 0.9009009009f, 0.4f, r.x, r.y); - a = to_vector2(-3.33f, 1.1f); - r = vector2_abs(a); - printf_2f_test(error, "Absolute vector", 3.33f, 1.1f, r.x, r.y); - a = to_vector2(1.11f, -2.5f); - r = vector2_floor(a); - printf_2f_test(error, "Floor vector", 1.0f, -3.0f, r.x, r.y); - a = to_vector2(-0.00011f, 3.999999f); - r = vector2_floor(a); - printf_2f_test(error, "Floor vector", -1.0f, 3.0f, r.x, r.y); - a = to_vector2(1.11f, -2.5f); - r = vector2_ceil(a); - printf_2f_test(error, "Ceil vector", 2.0f, -2.0f, r.x, r.y); - a = to_vector2(-0.00011f, 3.999999f); - r = vector2_ceil(a); - printf_2f_test(error, "Ceil vector", 0.0f, 4.0f, r.x, r.y); - a = to_vector2(1.11f, -2.55f); - r = vector2_round(a); - printf_2f_test(error, "Round vector", 1.0f, -3.0f, r.x, r.y); - a = to_vector2(4.31f, -6.65f); - b = to_vector2(-3.41f, 2.7f); - r = vector2_max(a, b); - printf_2f_test(error, "Maximum of vectors", 4.31f, 2.7f, r.x, r.y); - a = to_vector2(4.31f, -6.65f); - b = to_vector2(-3.41f, 2.7f); - r = vector2_min(a, b); - printf_2f_test(error, "Minimum of vectors", -3.41f, -6.65f, r.x, r.y); - a = to_vector2(4.31f, -6.65f); - b = to_vector2(-3.41f, 2.7f); - p = vector2_dot(a, b); - printf_1f_test(error, "Dot value of vectors", -32.6521f, p); - a = to_vector2(2.0f, 2.0f); - p = vector2_angle(a); - printf_1f_test(error, "Angle (radians) of vector", 0.78539816339745f, p); - a = to_vector2(4.31f, -6.65f); - p = vector2_angle(a); - printf_1f_test(error, "Angle (radians) of vector", -0.99574364682817f, p); - a = to_vector2(-5.31f, -7.33f); - p = vector2_angle(a); - printf_1f_test(error, "Angle (radians) of vector", -2.1977243674756f, p); - a = to_vector2(3.33f, 2.0f); - p = vector2_length_squared(a); - printf_1f_test(error, "Length squared of vector", 15.0889f, p); - a = to_vector2(3.33f, 2.0f); - p = vector2_length(a); - printf_1f_test(error, "Length of vector", 3.8844433321f, p); - a = to_vector2(3.33f, 2.0f); - r = vector2_normalize(a); - printf_2f_test(error, "Normalize vector", 0.8572664271f, 0.514874731f, r.x, r.y); - a = to_vector2(1.0f, -1.0f); - b = to_vector2(0.0f, 1.0f); - r = vector2_slide(a, b); - printf_2f_test(error, "Slide vector by normal", 1.0f, 0.0f, r.x, r.y); - a = to_vector2(-2.0f, 0.0f); - b = vector2_normalize(to_vector2(1.0f, 1.0f)); - r = vector2_slide(a, b); - printf_2f_test(error, "Slide vector by normal", -1.0f, 1.0f, r.x, r.y); - a = to_vector2(1.0f, -1.0f); - b = to_vector2(-1.0f, 0.0f); - r = vector2_reflect(a, b); - printf_2f_test(error, "Reflect vector by another", -1.0f, -1.0f, r.x, r.y); - a = to_vector2(1.0f, 1.0f); - b = to_vector2(0.0f, -1.0f); - r = vector2_reflect(a, b); - printf_2f_test(error, "Reflect vector by another", 1.0f, -1.0f, r.x, r.y); - a = to_vector2(2.0f, 1.0f); - r = vector2_tangent(a); - printf_2f_test(error, "Vector tangent", 1.0f, -2.0f, r.x, r.y); - a = to_vector2(1.0f, 0.0f); - r = vector2_rotate(a, 90.0f * M_PIF / 180.0f); - printf_2f_test(error, "Rotate vector", 0.0f, 1.0f, r.x, r.y); - a = to_vector2(1.0f, 0.0f); - r = vector2_rotate(a, 45.0f * M_PIF / 180.0f); - printf_2f_test(error, "Rotate vector", 0.707106781f,0.707106781f, r.x, r.y); - a = to_vector2(1.0f, 0.0f); - r = vector2_rotate(a, 130.0f * M_PIF / 180.0f); - printf_2f_test(error, "Rotate vector", -0.64278761f,0.766044443f, r.x, r.y); - a = to_vector2(-7.0f, -4.0f); - b = to_vector2(17.0f, 6.5f); - p = vector2_distance_to(a, b); - printf_1f_test(error, "Distance between vector", 26.196374f, p); - a = to_vector2(-7.0f, -4.0f); - b = to_vector2(17.0f, 6.5f); - p = vector2_distance_squared_to(a, b); - printf_1f_test(error, "Distance squared between vector", 686.2500107479f, p); - a = to_vector2(-7.0f, -4.0f); - b = to_vector2(17.0f, 6.5f); - r = vector2_linear_interpolation(a, b, 0.33f); - printf_2f_test(error, "Linear interpolation between vectors", 0.92f, -0.535f, r.x, r.y); -} - -void vector3_tests(struct cerror *error) -{ - struct vec a; - struct vec b; - struct vec r; - float p; - printf("\n# Making tests with 3D vectors...\n"); - a = to_vector3(1.11f, 2.5f, 0.0003f); - b = to_vector3(0.9f, 1.3f, 3.999999f); - r = vector3_add(a, b); - printf_3f_test(error, "Add two vectors", 2.01f, 3.8f, 4.000299f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - b = to_vector3(0.9f, 1.3f, 3.999999f); - r = vector3_subtract(a, b); - printf_3f_test(error, "Subtract vectors", 0.21f, 1.2f, -3.999699f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - r = vector3_scale(a, 3.3f); - printf_3f_test(error, "Scale vector", 3.663f, 8.25f, 0.000990f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - b = to_vector3(0.9f, 1.3f, 3.999999f); - r = vector3_multiply(a, b); - printf_3f_test(error, "Multiply vectors", 0.999f, 3.25f, 0.001200f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - b = to_vector3(0.9f, 1.3f, 3.999999f); - r = vector3_divide(a, b); - printf_3f_test(error, "Divide vectors", 1.2333333333f, 1.9230769231f, 0.000075f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - r = vector3_negative(a); - printf_3f_test(error, "Negative vector", -1.11f, -2.5f, -0.0003f, r.x, r.y, r.z); - a = to_vector3(1.11f, 2.5f, 0.0003f); - r = vector3_inverse(a); - printf_3f_test(error, "Inverse vector", 0.9009009009f, 0.4f, 3333.3333333333f, r.x, r.y, r.z); - a = to_vector3(-3.33f, 1.1f, -0.00001f); - r = vector3_abs(a); - printf_3f_test(error, "Absolute vector", 3.33f, 1.1f, 0.00001f, r.x, r.y, r.z); - a = to_vector3(1.11f, -2.5f, 0.0003f); - r = vector3_floor(a); - printf_3f_test(error, "Floor vector", 1.0f, -3.0f, 0.0f, r.x, r.y, r.z); - a = to_vector3(-0.00011f, 3.999999f, -0.99999f); - r = vector3_floor(a); - printf_3f_test(error, "Floor vector", -1.0f, 3.0f, -1.0f, r.x, r.y, r.z); - a = to_vector3(1.11f, -2.5f, 9.99999f); - r = vector3_ceil(a); - printf_3f_test(error, "Ceil vector", 2.0f, -2.0f, 10.0f, r.x, r.y, r.z); - a = to_vector3(-0.00011f, 3.999999f, 0.0000001f); - r = vector3_ceil(a); - printf_3f_test(error, "Ceil vector", 0.0f, 4.0f, 1.0f, r.x, r.y, r.z); - a = to_vector3(1.11f, -2.55f, 3.50000001f); - r = vector3_round(a); - printf_3f_test(error, "Round vector", 1.0f, -3.0f, 4.0f, r.x, r.y, r.z); - a = to_vector3(544.00001f, -233333.51f, 7999.50000001f); - r = vector3_round(a); - printf_3f_test(error, "Round vector", 544.0f, -233334.0f, 8000.0f, r.x, r.y, r.z); - a = to_vector3(4.31f, -6.65f, 4.5f); - b = to_vector3(-3.41f, 2.7f, -5.0f); - r = vector3_max(a, b); - printf_3f_test(error, "Maximum between vectors", 4.31f, 2.7f, 4.5f, r.x, r.y, r.z); - a = to_vector3(4.31f, -6.65f, 4.5f); - b = to_vector3(-3.41f, 2.7f, -5.0f); - r = vector3_min(a, b); - printf_3f_test(error, "Minimum between vectors", -3.41f, -6.65f, -5.0f, r.x, r.y, r.z); - a = to_vector3(4.31f, -6.65f, 1.0f); - b = to_vector3(-3.41f, 2.7f, 2.0f); - p = vector3_dot(a, b); - printf_1f_test(error, "Dot value of vectors", -30.652100f, p); - a = to_vector3(3.33f, 2.0f, 3.0f); - p = vector3_length_squared(a); - printf_1f_test(error, "Length squared of vector", 24.088900f, p); - a = to_vector3(3.33f, 2.0f, 3.0f); - p = vector3_length(a); - printf_1f_test(error, "Length of vector", 4.908044f, p); - a = to_vector3(3.33f, 2.0f, 5.0f); - r = vector3_normalize(a); - printf_3f_test(error, "Normalize vector", 0.525935f, 0.315877f, 0.789692f, r.x, r.y, r.z); - a = to_vector3(-7.0f, -4.0f, 99.9f); - b = to_vector3(17.0f, 6.5f, 103.33f); - p = vector3_distance_to(a, b); - printf_1f_test(error, "Distance between vectors", 26.419971f, p); - a = to_vector3(-7.0f, -4.0f, 99.9f); - b = to_vector3(17.0f, 6.5f, 103.33f); - p = vector3_distance_squared_to(a, b); - printf_1f_test(error, "Distance squared between vectors", 698.014893f, p); - a = to_vector3(-7.0f, -4.0f, 99.9f); - b = to_vector3(17.0f, 6.5f, 103.33f); - r = vector3_linear_interpolation(a, b, 0.33f); - printf_3f_test(error, "Linear interpolation between vectors", 0.92f, -0.535f, 101.031898f, r.x, r.y, r.z); -} - -void quaternion_tests(struct cerror *error) -{ - struct vec a; - struct vec b; - struct vec r; - float p; - printf("\n# Making tests with quaternions...\n"); - a = to_quaternion(0.0f, 1.0f, 0.0f, 1.0f); - r = quaternion_normalize(a); - printf_4f_test(error, "Normalize quaternion", 0.707099974f, 0.0, 0.707099974f, 0.0f, r.w, r.x, r.y, r.z); - a = to_vector3(1.0f, 0.0f, 0.0f); - r = quaternion_from_axis_angle(a, M_PIF_2); - printf_4f_test(error, "Quaternion from axis-angle", 0.707099974f, 0.707099974f, 0.0f, 0.0f, r.w, r.x, r.y, r.z); - a = to_quaternion(0.7071f, 0.0f, 0.0f, 0.7071f); - r = quaternion_to_axis_angle(a); - printf_4f_test(error, "Quaternion to axis-angle", 1.0f, 0.0f, 0.0f, 1.570796371f, r.x, r.y, r.z, r.w); -} - -void matrix_tests(struct cerror *error) -{ - struct mat a; - struct mat b; - struct mat r; - float p; - printf("\n# Making tests with matrices...\n"); - a = matrix_identity(); - b = matrix_identity(); - r = matrix_multiply_matrix(a, b); -} - -int main(int argc, char **args) -{ - struct cerror error = {0}; - vector2_tests(&error); - vector3_tests(&error); - quaternion_tests(&error); - matrix_tests(&error); - printf("\nTotal of failed tests: %d\n", error.failed); - printf("Total of tests that passed: %d\n", error.passed); - printf("Total of tests that passed with epsilon * 10.0: %d\n", error.passed_with_e10); - printf("Total of tests that passed with epsilon * 100.0: %d\n", error.passed_with_e100); - printf("Total of tests that passed with epsilon * 1000.0: %d\n", error.passed_with_e1000); - return error.failed; -}