Сегодня мы рассмотрим проект MATHC. По своей сути, это простая математическая библиотека, которая может быть использована для разработки 2D- и 3D-игр. Она содержит реализации следующих математических объектов на чистом С:
- 2D- и 3D-векторы;
- кватернионы;
- матрицы;
- функции плавности.
Реализация объектов поддерживает как стандарт С99, так и более новые.
Тип float
Каждая структура и функция библиотеки использует тип float
, поскольку в большинстве своём в разработке 2D- и 3D-игр при помощи OpenGL применяется именно этот тип данных.
Передача по значению или по указателю
Для функций, принимающих в качестве параметров структуры, предусмотрено две версии реализации. Первая — когда структура передаётся по значению, вторая — по указателю. Второй вид функций имеет префикс p
перед именем типа (pvector2
, pvector3
, pquaternion
и pmatrix
), а результат записывается в передаваемый аргумент *result
.
/* Передаём по значению, результат – конкретное значение */
struct mat projection = matrix_ortho(-100.0f, 100.0f, 100.0f, -100.0f);
struct mat view = matrix_look_at(to_vector3(0.0f, 0.0f, 1.0f),
to_vector3(0.0f, 0.0f, 0.0f));
struct mat pv = matrix_multiply_matrix(projection, view);
/* Передаём по указателю */
struct vec pos = {0};
struct vec target = {0};
struct mat projection = {0};
struct mat view = {0};
struct mat multiplied_matrix = {0};
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, &projection);
pmatrix_look_at(&pos, &target, &view);
pmatrix_multiply_matrix(&projection, &view, &multiplied_matrix);
Векторы
Все векторы (2D, 3D и кватернионы) имеют вид структур типа struct vec
. Отметим, что компонента z
может быть использована и для 2D-векторов, поскольку она применяется в OpenGL для проверки глубины. Компонента w
используется только для описания кватерниона.
/* Перевернём 2D-вектор на 90º */
struct vec direction = to_vector2(0.0f, -1.0f);
direction = vector2_rotate(90.0f * M_PIF / 180.0f);
/* Получим угол наклона в радианах для 2D-вектора*/
float angle = vector2_angle(direction);
/* Создаём 3D-вектор */
struct vec position = to_vector3(0.0f, 0.0f, 0.0f);
/* Создаём кватернион */
struct vec quaternion = to_quaternion(0.0f, 0.0f, 0.0f, 1.0f);
/* Сферическая интерполяция между двумя кватернионами */
struct vec interpolated = quaternion_spherical_linear_interpolation(a, b, 0.5f);
Матрицы
Все матрицы в библиотеке имеют размер 4×4. В MATHC также реализованы функции для настройки матриц модели, мира и проекции. Обычно матрица мира используется для изменения множества вершин на стороне клиента или на графическом процессоре. Если вы хотите изменить вершины на стороне клиента, то используйте функции matrix_multiply_f4()
или pmatrix_multiply_f4()
для изменения массива с 4 float-элементами:
/* Компоненты x, y, z и w */
float v[4] = {0.0f, 10.0f, 0.0f, 1.0f};
struct mat rotation = matrix_rotation_z(to_radians(45.0f));
matrix_multiply_f4(rotation, v);
Если вы хотите изменить вершины на стороне GPU, то используйте функции matrix_to_array()
или pmatrix_to_array()
для перевода матрицы в массив с 16 float-элементами:
/* MAT_SIZE - макрос в mathc.h со значением, равным 16 */
float v[MAT_SIZE];
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));
struct mat pv = matrix_multiply_matrix(projection, view);
matrix_to_array(pv, v);
Функции плавности
Функции плавности полезны для анимации. Библиотечная реализация функций основана на их описании. Функции принимают значения от 0.0f
до 1.0f
и возвращают значения внутри этого же диапазона. Однако в некоторых из функций возвращаемое значение экстраполирует этот диапазон.
Лицензия MATHC
Исходный код проекта подчиняется лицензии ZLIB.