rework: change struct to full c

This commit is contained in:
2025-08-28 21:21:03 +02:00
parent a5a9cc596d
commit 471b21b952
14 changed files with 84 additions and 385 deletions

View File

@@ -1,34 +1,13 @@
cmake_minimum_required(VERSION 3.10)
project(t3dsr C CXX)
project(t3dsr C)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
# ==== sources ====
file(GLOB_RECURSE C_SOURCES CONFIGURE_DEPENDS src/*.c)
file(GLOB_RECURSE CPP_SOURCES CONFIGURE_DEPENDS src/*.cpp)
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS src/*.h src/*.hpp)
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS src/*.h)
file(GLOB MAIN_SRC CONFIGURE_DEPENDS src/main.*)
set(ALL_SOURCES ${C_SOURCES} ${CPP_SOURCES})
list(REMOVE_ITEM ALL_SOURCES ${MAIN_SRC})
add_executable(main ${MAIN_SRC} ${ALL_SOURCES} ${HEADERS})
add_executable(main ${C_SOURCES} ${HEADERS})
if(NOT MSVC)
target_link_libraries(main m)
endif()
# ==== tests ====
enable_testing()
file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS tests/*.c)
foreach(test_src ${TEST_SOURCES})
get_filename_component(test_name ${test_src} NAME_WE)
add_executable(${test_name} ${test_src} ${ALL_SOURCES})
if(NOT MSVC)
target_link_libraries(${test_name} m)
endif()
add_test(NAME ${test_name} COMMAND ${test_name})
endforeach()

30
src/cam.c Normal file
View File

@@ -0,0 +1,30 @@
#include "math/mat4.h"
#include "math/vec3.h"
#include "math/vec4.h"
#include <math.h>
Mat4f_t perspCam(float fov, float asp, float near, float far)
{
const float t = 1 / tanf(fov/2);
const float persp[16] =
{
t/asp, 0.f, 0.f, 0.f,
0.f, t, 0.f, 0.f,
0.f, 0.f, (far + near) / (far - near), -1.f,
0.f, 0.f, (2.f * far * near) / (far - near), 0.f
};
return mat4f_from_array(persp);
}
Vec4f_t* normCoord_r(Vec4f_t* vec)
{
float inv_w = 1.f / vec->w;
vec->x *= inv_w;
vec->y *= inv_w;
vec->z *= inv_w;
return vec;
}
// Vec3f_t

0
src/cam.h Normal file
View File

8
src/main.c Normal file
View File

@@ -0,0 +1,8 @@
#include <stdio.h>
#include "math/mat4.h"
int main(int argc, const char** argv)
{
printf("hello world");
return 0;
}

View File

@@ -1,9 +0,0 @@
#include <iostream>
#include "math/mat4.hpp"
int main()
{
math::Mat4f test = math::Mat4f::Identity();
std::cout << test.data().m[0] << test.data().m[5] << test.data().m[10] << test.data().m[15] << std::endl;
return 0;
}

View File

@@ -1,5 +1,14 @@
#include "mat4.h"
#include <math.h>
#include <float.h>
#ifdef SIMD_X86
#include <xmmintrin.h>
#elif defined(SIMD_ARCH)
#include <arm_neon.h>
#endif
Mat4f_t* mat4f_from_array_r(Mat4f_t *__restrict m, const float arr[16])
{
for(int i = 0; i<MAT_SIZE; i+=MAT_DIM) {

View File

@@ -1,20 +1,13 @@
#ifndef MATRIX4_H
#define MATRIX4_H
#include <math.h>
#include <float.h>
#define MAT_SIZE 16
#define MAT_DIM 4
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
#define SIMD_X86
#include <xmmintrin.h>
#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
#define SIMD_ARCH
#include <arm_neon.h>
#else
#endif

View File

@@ -1,24 +0,0 @@
extern "C"
{
#include "mat4.h"
}
namespace math
{
class Mat4f
{
private:
Mat4f_t mat4;
public:
Mat4f() { mat4f_zero_r(&mat4); }
explicit Mat4f(const Mat4f_t& m) : mat4(m) {}
explicit Mat4f(const float arr[16]) { mat4f_from_array_r(&mat4, arr); }
static Mat4f Identity() { Mat4f mat; mat4f_identity_r(&mat.mat4); return mat; }
static Mat4f Zero() { Mat4f mat; mat4f_zero_r(&mat.mat4); return mat; }
const Mat4f_t& data() const { return mat4; }
Mat4f_t& data() { return mat4; }
};
}

View File

@@ -1,5 +1,15 @@
#include "vec3.h"
#include <math.h>
#include <float.h>
#ifdef SIMD_X86
#include <xmmintrin.h>
#elif defined(SIMD_ARCH)
#include <arm_neon.h>
#endif
Vec3f_t vec3f(float x, float y, float z)
{
Vec3f_t vec = {.x = x, .y = y, .z = z};
@@ -160,6 +170,11 @@ float vec3f_dot(Vec3f_t a, Vec3f_t b)
#endif
}
float vec3f_len(Vec3f_t v)
{
return sqrtf(vec3f_dot(v, v));
}
Vec3f_t* vec3f_norm_r(Vec3f_t *__restrict v)
{
float length = vec3f_len(*v);

View File

@@ -8,21 +8,16 @@
#ifndef vec3_h
#define vec3_h
#include <math.h>
#include <float.h>
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
#define SIMD_X86
#define SIMD_ENABLE
#include <xmmintrin.h>
#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
#define SIMD_ARCH
#define SIMD_ENABLE
#include <arm_neon.h>
#else
#define SIMD_NONE
#endif
#ifdef _MSC_VER
@@ -61,10 +56,7 @@ Vec3f_t vec3f_scale(Vec3f_t a, float scale);
float vec3f_dot(Vec3f_t a, Vec3f_t b);
inline static float vec3f_len(Vec3f_t v)
{
return sqrtf(vec3f_dot(v, v));
}
float vec3f_len(Vec3f_t v);
Vec3f_t* vec3f_norm_r(Vec3f_t *__restrict v);
Vec3f_t vec3f_norm(Vec3f_t v);

View File

@@ -1,5 +1,15 @@
#include "vec4.h"
#include <math.h>
#include <float.h>
#ifdef SIMD_X86
#include <xmmintrin.h>
#elif defined(SIMD_ARCH)
#include <arm_neon.h>
#endif
Vec4f_t vec4f(float x, float y, float z, float w)
{
return (Vec4f_t){.x = x, .y = y, .z = z, .w = w};
@@ -161,6 +171,12 @@ float vec4f_dot(Vec4f_t a, Vec4f_t b)
#endif
}
float vec4f_len(Vec4f_t v)
{
return sqrtf(vec4f_dot(v, v));
}
Vec4f_t* vec4f_norm_r(Vec4f_t *__restrict v)
{
float length = vec4f_len(*v);

View File

@@ -1,21 +1,13 @@
#ifndef VECTOR4_H
#define VECTOR4_H
#include <math.h>
#include <float.h>
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
#define SIMD_X86
#define SIMD_ENABLE
#include <xmmintrin.h>
#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
#define SIMD_ARCH
#define SIMD_ENABLE
#include <arm_neon.h>
#else
#define SIMD_NONE
#endif
#ifdef _MSC_VER
@@ -58,10 +50,7 @@ Vec4f_t vec4f_scale(Vec4f_t a, float scale);
float vec4f_dot(Vec4f_t a, Vec4f_t b);
inline static float vec4f_len(Vec4f_t v)
{
return sqrtf(vec4f_dot(v, v));
}
float vec4f_len(Vec4f_t v);
Vec4f_t* vec4f_norm_r(Vec4f_t *__restrict v);
Vec4f_t vec4f_norm(Vec4f_t v);

View File

@@ -1,146 +0,0 @@
//
// tests.c
// tests
//
// Created by Loïc GUEZO on 26/06/2025.
//
#include <assert.h>
#include <stdio.h>
#include "../src/math/vec3.h"
#define EPSILON 1e-6f
void test_vec3f_creation() {
Vec3f_t v = vec3f(1.f, 2.f, 3.f);
assert(fabsf(v.x - 1.f) < EPSILON);
assert(fabsf(v.y - 2.f) < EPSILON);
assert(fabsf(v.z - 3.f) < EPSILON);
}
// a -> [1, 2, 3]
// b -> [5, 6, 7]
// r -> [6, 8, 10]
void test_vec3f_add() {
Vec3f_t a = vec3f(1.f, 2.f, 3.f);
Vec3f_t b = vec3f(5.f, 6.f, 7.f);
Vec3f_t r = vec3f_add(a, b);
assert(fabsf(r.x - 6.f) < EPSILON);
assert(fabsf(r.y - 8.f) < EPSILON);
assert(fabsf(r.z - 10.f) < EPSILON);
}
// a -> [5, 6, 7]
// b -> [1, 2, 3]
// r -> [4, 4, 4]
void test_vec3f_sub() {
Vec3f_t a = vec3f(5.f, 6.f, 7.f);
Vec3f_t b = vec3f(1.f, 2.f, 3.f);
Vec3f_t r = vec3f_sub(a, b);
assert(fabsf(r.x - 4.f) < EPSILON);
assert(fabsf(r.y - 4.f) < EPSILON);
assert(fabsf(r.z - 4.f) < EPSILON);
}
// a -> [1, 2, 3]
// r -> [2, 4, 6]
void test_vec3f_scale() {
Vec3f_t a = vec3f(1.f, 2.f, 3.f);
Vec3f_t r = vec3f_scale(a, 2.f);
assert(fabsf(r.x - 2.f) < EPSILON);
assert(fabsf(r.y - 4.f) < EPSILON);
assert(fabsf(r.z - 6.f) < EPSILON);
}
// dot product:
// + : same direction
// 0 : orthgonal
// - : opposite direction
void test_vec3f_dot() {
Vec3f_t a = vec3f(1.f, 2.f, 3.f);
Vec3f_t b = vec3f(5.f, 6.f, 7.f);
float d = vec3f_dot(a, b);
assert(fabsf(d - (1*5 + 2*6 + 3*7)) < EPSILON);
}
// normalize:
// [4, 0, 0] -> [1, 0, 0]
void test_vec3f_norm() {
Vec3f_t v = vec3f(3.f, 0.f, 0.f);
Vec3f_t n = vec3f_norm(v);
assert(fabsf(n.x - 1.f) < EPSILON);
assert(fabsf(n.y) < EPSILON);
assert(fabsf(n.z) < EPSILON);
}
// lerp:
// return vector between a and b
// if t = 0.5
// a = [0, 0, 0]
// b = [3, 3, 3]
// r = [1.5, 1.5, 1.5] (t = 0.5) is middle
void test_vec3f_lerp() {
Vec3f_t a = vec3f(0.f, 0.f, 0.f);
Vec3f_t b = vec3f(1.f, 1.f, 1.f);
Vec3f_t r = vec3f_lerp(a, b, 0.5f);
assert(fabsf(r.x - 0.5f) < EPSILON);
assert(fabsf(r.y - 0.5f) < EPSILON);
assert(fabsf(r.z - 0.5f) < EPSILON);
}
// angle:
// return angle of two vectors
void test_vec3f_angle() {
Vec3f_t a = vec3f(1.f, 0.f, 0.f);
Vec3f_t b = vec3f(0.f, 1.f, 0.f);
float angle = vec3f_angle(a, b);
assert(fabsf(angle - (float)(M_PI / 2)) < EPSILON);
}
// proj:
// return size of a on b
void test_vec3f_proj() {
Vec3f_t a = vec3f(2.f, 0.f, 0.f);
Vec3f_t b = vec3f(1.f, 0.f, 0.f);
Vec3f_t r = vec3f_proj(a, b);
assert(fabsf(r.x - 2.f) < EPSILON);
assert(fabsf(r.y) < EPSILON);
assert(fabsf(r.z) < EPSILON);
}
// refl:
// return a bounce vector
// raytracing
void test_vec3f_refl() {
Vec3f_t v = vec3f(1.f, -1.f, 0.f);
Vec3f_t normal = vec3f(0.f, 1.f, 0.f);
Vec3f_t r = vec3f_refl(v, normal);
assert(fabsf(r.x - 1.f) < EPSILON);
assert(fabsf(r.y - 1.f) < EPSILON);
assert(fabsf(r.z) < EPSILON);
}
// dist:
// return distance between two vectors
void test_vec3f_dist() {
Vec3f_t a = vec3f(1.f, 0.f, 0.f);
Vec3f_t b = vec3f(0.f, 0.f, 0.f);
float d = vec3f_dist(a, b);
assert(fabsf(d - 1.f) < EPSILON);
}
int main(void) {
test_vec3f_creation();
test_vec3f_add();
test_vec3f_sub();
test_vec3f_scale();
test_vec3f_dot();
test_vec3f_norm();
test_vec3f_lerp();
test_vec3f_angle();
test_vec3f_proj();
test_vec3f_refl();
test_vec3f_dist();
return 0; // success
}

View File

@@ -1,153 +0,0 @@
//
// tests_vec4f.c
// RUN_TESTS
//
// Created by Loïc GUEZO on 28/06/2025.
//
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include "../src/math/vec4.h"
void test_vec4f_creation() {
Vec4f_t v = vec4f(1.f, 2.f, 3.f, 4.f);
assert(fabsf(v.x - 1.f) < FLT_EPSILON);
assert(fabsf(v.y - 2.f) < FLT_EPSILON);
assert(fabsf(v.z - 3.f) < FLT_EPSILON);
assert(fabsf(v.w - 4.f) < FLT_EPSILON);
}
// a -> [1, 2, 3, 4]
// b -> [5, 6, 7, 8]
// r -> [6, 8, 10, 12]
void test_vec4f_add() {
Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f);
Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f);
Vec4f_t r = vec4f_add(a, b);
assert(fabsf(r.x - 6.f) < FLT_EPSILON);
assert(fabsf(r.y - 8.f) < FLT_EPSILON);
assert(fabsf(r.z - 10.f) < FLT_EPSILON);
assert(fabsf(r.w - 12.f) < FLT_EPSILON);
}
// a -> [5, 6, 7, 8]
// b -> [1, 2, 3, 4]
// r -> [4, 4, 4, 4]
void test_vec4f_sub() {
Vec4f_t a = vec4f(5.f, 6.f, 7.f, 8.f);
Vec4f_t b = vec4f(1.f, 2.f, 3.f, 4.f);
Vec4f_t r = vec4f_sub(a, b);
assert(fabsf(r.x - 4.f) < FLT_EPSILON);
assert(fabsf(r.y - 4.f) < FLT_EPSILON);
assert(fabsf(r.z - 4.f) < FLT_EPSILON);
assert(fabsf(r.w - 4.f) < FLT_EPSILON);
}
// a -> [1, 2, 3, 4]
// r -> [2, 4, 6, 8]
void test_vec4f_scale() {
Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f);
Vec4f_t r = vec4f_scale(a, 2.f);
assert(fabsf(r.x - 2.f) < FLT_EPSILON);
assert(fabsf(r.y - 4.f) < FLT_EPSILON);
assert(fabsf(r.z - 6.f) < FLT_EPSILON);
assert(fabsf(r.w - 8.f) < FLT_EPSILON);
}
// dot product:
// + : same direction
// 0 : orthgonal
// - : opposite direction
void test_vec4f_dot() {
Vec4f_t a = vec4f(1.f, 2.f, 3.f, 4.f);
Vec4f_t b = vec4f(5.f, 6.f, 7.f, 8.f);
float d = vec4f_dot(a, b);
assert(fabsf(d - (1*5 + 2*6 + 3*7 + 4*8)) < FLT_EPSILON);
}
// normalize:
// [4, 0, 0, 0] -> [1, 0, 0, 0]
void test_vec4f_norm() {
Vec4f_t v = vec4f(3.f, 0.f, 0.f, 0.f);
Vec4f_t n = vec4f_norm(v);
assert(fabsf(n.x - 1.f) < FLT_EPSILON);
assert(fabsf(n.y) < FLT_EPSILON);
assert(fabsf(n.z) < FLT_EPSILON);
assert(fabsf(n.w) < FLT_EPSILON);
}
// lerp:
// return vector between a and b
// if t = 0.5
// a = [0, 0, 0, 0]
// b = [3, 3, 3, 3]
// r = [1.5, 1.5, 1.5, 1.5] (t = 0.5) is middle
void test_vec4f_lerp() {
Vec4f_t a = vec4f(0.f, 0.f, 0.f, 0.f);
Vec4f_t b = vec4f(1.f, 1.f, 1.f, 1.f);
Vec4f_t r = vec4f_lerp(a, b, 0.5f);
assert(fabsf(r.x - 0.5f) < FLT_EPSILON);
assert(fabsf(r.y - 0.5f) < FLT_EPSILON);
assert(fabsf(r.z - 0.5f) < FLT_EPSILON);
assert(fabsf(r.w - 0.5f) < FLT_EPSILON);
}
// angle:
// return angle of two vectors
void test_vec4f_angle() {
Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f);
Vec4f_t b = vec4f(0.f, 1.f, 0.f, 0.f);
float angle = vec4f_angle(a, b);
assert(fabsf(angle - (float)(M_PI / 2)) < FLT_EPSILON);
}
// proj:
// return size of a on b
void test_vec4f_proj() {
Vec4f_t a = vec4f(2.f, 0.f, 0.f, 0.f);
Vec4f_t b = vec4f(1.f, 0.f, 0.f, 0.f);
Vec4f_t r = vec4f_proj(a, b);
assert(fabsf(r.x - 2.f) < FLT_EPSILON);
assert(fabsf(r.y) < FLT_EPSILON);
assert(fabsf(r.z) < FLT_EPSILON);
assert(fabsf(r.w) < FLT_EPSILON);
}
// refl:
// return a bounce vector
// raytracing
void test_vec4f_refl() {
Vec4f_t v = vec4f(1.f, -1.f, 0.f, 0.f);
Vec4f_t normal = vec4f(0.f, 1.f, 0.f, 0.f);
Vec4f_t r = vec4f_refl(v, normal);
assert(fabsf(r.x - 1.f) < FLT_EPSILON);
assert(fabsf(r.y - 1.f) < FLT_EPSILON);
assert(fabsf(r.z) < FLT_EPSILON);
assert(fabsf(r.w) < FLT_EPSILON);
}
// dist:
// return distance between two vectors
void test_vec4f_dist() {
Vec4f_t a = vec4f(1.f, 0.f, 0.f, 0.f);
Vec4f_t b = vec4f(0.f, 0.f, 0.f, 0.f);
float d = vec4f_dist(a, b);
assert(fabsf(d - 1.f) < FLT_EPSILON);
}
int main(void) {
test_vec4f_creation();
test_vec4f_add();
test_vec4f_sub();
test_vec4f_scale();
test_vec4f_dot();
test_vec4f_norm();
test_vec4f_lerp();
test_vec4f_angle();
test_vec4f_proj();
test_vec4f_refl();
test_vec4f_dist();
return 0; // success
}