topaz/linear.c

179 lines
3.9 KiB
C

// SPDX-License-Identifier: BSD-3-Clause
#include "linear.h"
float vec2_dot(vec2 a, vec2 b)
{
float result = 0.0f;
for (int i=0; i<2; i++) {
result += a[i] * b[i];
}
return result;
}
float vec3_dot(vec3 a, vec3 b)
{
float result = 0.0f;
for (int i=0; i<3; i++) {
result += a[i] * b[i];
}
return result;
}
float vec4_dot(vec4 a, vec4 b)
{
float result = 0.0f;
for (int i=0; i<4; i++) {
result += a[i] * b[i];
}
return result;
}
void vec3_cross(vec3 dest, vec3 a, vec3 b)
{
vec3 res = {0};
res[0] = a[1] * b[2] - a[2] * b[1];
res[1] = a[2] * b[0] - a[0] * b[2];
res[2] = a[0] * b[1] - a[1] * b[0];
memcpy(dest, res, sizeof(vec3));
}
void mat4_perspective(mat4 dest, float fov, float aspect, float near, float far)
{
mat4 perspective = {
{ 1.0f/(aspect*tan(fov/2.0f)), 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f/tan(fov/2.0f), 0.0f, 0.0f },
{ 0.0f, 0.0f, -((far+near)/(far-near)), -((2*far*near)/(far-near)) },
{ 0.0f, 0.0f, -1.0f, 0.0f }
};
memcpy(dest, perspective, sizeof(mat4));
}
void mat4_lookat(mat4 dest, vec3 eye, vec3 target, vec3 up)
{
vec3 target_cpy = {0};
memcpy(target_cpy, target, sizeof(vec3));
vec3_sub(target_cpy, target_cpy, eye);
vec3 zaxis = {0};
vec3_normalize(zaxis, target_cpy);
vec3 zaxis_cpy = {0};
memcpy(zaxis_cpy, zaxis, sizeof(vec3));
vec3_cross(zaxis_cpy, zaxis, up);
vec3 xaxis = {0};
vec3_normalize(xaxis, zaxis_cpy);
vec3 yaxis = {0};
vec3_cross(yaxis, xaxis, zaxis);
zaxis[0] = -zaxis[0];
zaxis[1] = -zaxis[1];
zaxis[2] = -zaxis[2];
mat4 view = {
{ xaxis[0], xaxis[1], xaxis[2], -vec3_dot(xaxis, eye) },
{ yaxis[0], yaxis[1], yaxis[2], -vec3_dot(yaxis, eye) },
{ zaxis[0], zaxis[1], zaxis[2], -vec3_dot(zaxis, eye) },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
memcpy(dest, view, sizeof(mat4));
}
void vec2_sub(vec2 dest, vec2 a, vec2 b)
{
vec2 res = {0};
for (int i=0; i<2; i++) res[i] = a[i] - b[i];
memcpy(dest, res, sizeof(vec2));
}
void vec3_sub(vec3 dest, vec3 a, vec3 b)
{
vec3 res = {0};
for (int i=0; i<3; i++) res[i] = a[i] - b[i];
memcpy(dest, res, sizeof(vec3));
}
void vec4_sub(vec4 dest, vec4 a, vec4 b)
{
vec4 res = {0};
for (int i=0; i<4; i++) res[i] = a[i] - b[i];
memcpy(dest, res, sizeof(vec4));
}
void vec2_add(vec2 dest, vec2 a, vec2 b)
{
vec2 res = {0};
for (int i=0; i<2; i++) res[i] = a[i] + b[i];
memcpy(dest, res, sizeof(vec2));
}
void vec3_add(vec3 dest, vec3 a, vec3 b)
{
vec3 res = {0};
for (int i=0; i<3; i++) res[i] = a[i] + b[i];
memcpy(dest, res, sizeof(vec3));
}
void vec4_add(vec4 dest, vec4 a, vec4 b)
{
vec4 res = {0};
for (int i=0; i<4; i++) res[i] = a[i] + b[i];
memcpy(dest, res, sizeof(vec4));
}
void vec2_normalize(vec2 dest, vec2 a)
{
vec2 res = {0};
memcpy(res, a, sizeof(vec2));
float w = sqrt(a[0] * a[0] + a[1] * a[1]);
res[0] /= w;
res[1] /= w;
memcpy(dest, res, sizeof(vec2));
}
void vec3_normalize(vec3 dest, vec3 a)
{
vec3 res = {0};
memcpy(res, a, sizeof(vec3));
float w = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
res[0] /= w;
res[1] /= w;
res[2] /= w;
memcpy(dest, res, sizeof(vec3));
}
void vec4_normalize(vec4 dest, vec4 a)
{
vec4 res = {0};
memcpy(res, a, sizeof(vec4));
float w = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
res[0] /= w;
res[1] /= w;
res[2] /= w;
res[3] /= w;
memcpy(dest, res, sizeof(vec4));
}
void vec2_scale(vec2 dest, vec2 a, float scale)
{
memcpy(dest, a, sizeof(vec2));
for (int i=0; i<2; i++) dest[i] *= scale;
}
void vec3_scale(vec3 dest, vec3 a, float scale)
{
memcpy(dest, a, sizeof(vec3));
for (int i=0; i<3; i++) dest[i] *= scale;
}
void vec4_scale(vec4 dest, vec4 a, float scale)
{
memcpy(dest, a, sizeof(vec4));
for (int i=0; i<4; i++) dest[i] *= scale;
}