Add first utilities
The utilities are grouped into the following categories: - Math Matrices, vectors and special rounding functions are included in the math category. This still is severely lacking in functionality. - Containers Datatypes for storing arbitrary data in a special way, for example for being able to search through it quickly, in the case of a map. Currently the only function in this category is for testing how long a string is, with a maximum number of bytes to check. - Allocation Special-purpose memory allocators with restrictions on what they can allocate. The restrictions are used to be faster in those use cases. - UUID Universally-unique identifiers are used to identify one specific object within the engine's lifetime.
This commit is contained in:
parent
004f089cf0
commit
c3fb07b871
|
@ -0,0 +1,175 @@
|
|||
|
||||
#ifndef VOXULA_UTILITY_H
|
||||
#define VOXULA_UTILITY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct vx_uuid_table vx_uuid_table_s;
|
||||
typedef struct vx_uuid_block vx_uuid_block_s;
|
||||
typedef struct vx_uuid_entry vx_uuid_entry_s;
|
||||
|
||||
typedef uint64_t vx_uuid_d;
|
||||
|
||||
typedef struct vx_vec2f vx_vec2f_s;
|
||||
typedef struct vx_vec3f vx_vec3f_s;
|
||||
typedef struct vx_vec4f vx_vec4f_s;
|
||||
typedef struct vx_mat2f vx_mat2f_s;
|
||||
typedef struct vx_mat3f vx_mat3f_s;
|
||||
typedef struct vx_mat4f vx_mat4f_s;
|
||||
|
||||
typedef struct vx_pool vx_pool_s;
|
||||
typedef struct vx_pool_slot_header vx_pool_slot_header_s;
|
||||
typedef struct vx_arena vx_arena_s;
|
||||
|
||||
struct vx_uuid_entry
|
||||
{
|
||||
vx_uuid_d uuid;
|
||||
};
|
||||
|
||||
struct vx_uuid_block
|
||||
{
|
||||
/// @brief Start of the block's UUIDs;
|
||||
/// this must be multiplied with 4096
|
||||
/// to get the first ID's number.
|
||||
uint32_t offset;
|
||||
uint8_t num_ids;
|
||||
vx_uuid_entry_s entries[256];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct vx_uuid_table
|
||||
{
|
||||
uint32_t block_capacity;
|
||||
uint32_t num_blocks;
|
||||
vx_uuid_block_s **blocks;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct vx_vec2f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct vx_vec3f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
struct vx_vec4f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct vx_mat2f
|
||||
{
|
||||
float val[4];
|
||||
};
|
||||
|
||||
struct vx_mat3f
|
||||
{
|
||||
float val[9];
|
||||
};
|
||||
|
||||
struct vx_mat4f
|
||||
{
|
||||
float val[16];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct vx_pool_slot_header
|
||||
{
|
||||
vx_pool_slot_header_s *next;
|
||||
vx_pool_s *pool;
|
||||
};
|
||||
|
||||
struct vx_pool
|
||||
{
|
||||
uint32_t capacity;
|
||||
uint32_t unit_size;
|
||||
void *allocation;
|
||||
|
||||
vx_pool_slot_header_s *first_free;
|
||||
vx_pool_s *continuation;
|
||||
};
|
||||
|
||||
struct vx_arena
|
||||
{
|
||||
uint32_t capacity;
|
||||
uint32_t usage;
|
||||
void *allocation;
|
||||
vx_arena_s *continuation;
|
||||
};
|
||||
vx_uuid_table_s * vx_new_uuid_table();
|
||||
vx_uuid_d vx_new_uuid(vx_uuid_table_s *table);
|
||||
|
||||
uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum);
|
||||
|
||||
vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector);
|
||||
|
||||
vx_mat2f_s vx_mat2f_identity();
|
||||
vx_mat3f_s vx_mat3f_identity();
|
||||
vx_mat4f_s vx_mat4f_identity();
|
||||
|
||||
void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix);
|
||||
|
||||
vx_mat4f_s vx_mat4f_translate(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s translation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_x(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_y(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_z(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_scale(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s scaling
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_perspective(
|
||||
float aspect_ratio,
|
||||
float fov,
|
||||
float near_plane,
|
||||
float far_plane
|
||||
);
|
||||
|
||||
uint64_t vx_ceil_to(uint64_t base, uint64_t anchor);
|
||||
uint64_t vx_ceil_pow2(uint64_t base);
|
||||
uint64_t vx_min_u64(uint64_t first, uint64_t second);
|
||||
uint64_t vx_max_u64(uint64_t first, uint64_t second);
|
||||
|
||||
|
||||
// Pool Functions
|
||||
|
||||
vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity);
|
||||
void vx_free_pool(vx_pool_s *pool);
|
||||
|
||||
void * vx_pool(vx_pool_s *pool);
|
||||
void vx_unpool(void *allocation);
|
||||
|
||||
// Arena Functions
|
||||
|
||||
vx_arena_s * vx_new_arena(uint32_t capacity);
|
||||
void vx_free_arena(vx_arena_s *arena);
|
||||
|
||||
void * vx_arena_alloc(vx_arena_s *arena, uint32_t length);
|
||||
char * vx_arena_dupe_string(vx_arena_s *arena, const char *string);
|
||||
char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum);
|
||||
|
||||
#endif // VOXULA_UTILITY_H
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
#ifndef VOXULA_ALLOCATOR_H
|
||||
#define VOXULA_ALLOCATOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct vx_pool vx_pool_s;
|
||||
typedef struct vx_pool_slot_header vx_pool_slot_header_s;
|
||||
typedef struct vx_arena vx_arena_s;
|
||||
|
||||
struct vx_pool_slot_header
|
||||
{
|
||||
vx_pool_slot_header_s *next;
|
||||
vx_pool_s *pool;
|
||||
};
|
||||
|
||||
struct vx_pool
|
||||
{
|
||||
uint32_t capacity;
|
||||
uint32_t unit_size;
|
||||
void *allocation;
|
||||
|
||||
vx_pool_slot_header_s *first_free;
|
||||
vx_pool_s *continuation;
|
||||
};
|
||||
|
||||
struct vx_arena
|
||||
{
|
||||
uint32_t capacity;
|
||||
uint32_t usage;
|
||||
void *allocation;
|
||||
vx_arena_s *continuation;
|
||||
};
|
||||
|
||||
// Pool Functions
|
||||
|
||||
vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity);
|
||||
void vx_free_pool(vx_pool_s *pool);
|
||||
|
||||
void * vx_pool(vx_pool_s *pool);
|
||||
void vx_unpool(void *allocation);
|
||||
|
||||
// Arena Functions
|
||||
|
||||
vx_arena_s * vx_new_arena(uint32_t capacity);
|
||||
void vx_free_arena(vx_arena_s *arena);
|
||||
|
||||
void * vx_arena_alloc(vx_arena_s *arena, uint32_t length);
|
||||
char * vx_arena_dupe_string(vx_arena_s *arena, const char *string);
|
||||
char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum);
|
||||
|
||||
#endif // VOXULA_ALLOCATOR_H
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef VOXULA_CONTAINERS_H
|
||||
#define VOXULA_CONTAINERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum);
|
||||
|
||||
#endif // VOXULA_CONTAINERS_H
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
#ifndef VOXULA_MATH_H
|
||||
#define VOXULA_MATH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct vx_vec2f vx_vec2f_s;
|
||||
typedef struct vx_vec3f vx_vec3f_s;
|
||||
typedef struct vx_vec4f vx_vec4f_s;
|
||||
|
||||
typedef struct vx_mat2f vx_mat2f_s;
|
||||
typedef struct vx_mat3f vx_mat3f_s;
|
||||
typedef struct vx_mat4f vx_mat4f_s;
|
||||
|
||||
struct vx_vec2f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct vx_vec3f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
struct vx_vec4f
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct vx_mat2f
|
||||
{
|
||||
float val[4];
|
||||
};
|
||||
|
||||
struct vx_mat3f
|
||||
{
|
||||
float val[9];
|
||||
};
|
||||
|
||||
struct vx_mat4f
|
||||
{
|
||||
float val[16];
|
||||
};
|
||||
|
||||
vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector);
|
||||
|
||||
vx_mat2f_s vx_mat2f_identity();
|
||||
vx_mat3f_s vx_mat3f_identity();
|
||||
vx_mat4f_s vx_mat4f_identity();
|
||||
|
||||
vx_mat4f_s vx_mat4f_translate(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s translation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_x(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_y(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_rotate_z(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_scale(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s scaling
|
||||
);
|
||||
vx_mat4f_s vx_mat4f_perspective(
|
||||
float aspect_ratio,
|
||||
float fov,
|
||||
float near_plane,
|
||||
float far_plane
|
||||
);
|
||||
|
||||
void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix);
|
||||
|
||||
uint64_t vx_ceil_to(uint64_t base, uint64_t anchor);
|
||||
uint64_t vx_ceil_pow2(uint64_t base);
|
||||
uint64_t vx_min_u64(uint64_t first, uint64_t second);
|
||||
uint64_t vx_max_u64(uint64_t first, uint64_t second);
|
||||
|
||||
#endif // VOXULA_MATH_H
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
#ifndef VOXULA_UUID_H
|
||||
#define VOXULA_UUID_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct vx_uuid_table vx_uuid_table_s;
|
||||
typedef struct vx_uuid_block vx_uuid_block_s;
|
||||
typedef struct vx_uuid_entry vx_uuid_entry_s;
|
||||
|
||||
typedef uint64_t vx_uuid_d;
|
||||
|
||||
struct vx_uuid_entry
|
||||
{
|
||||
vx_uuid_d uuid;
|
||||
};
|
||||
|
||||
struct vx_uuid_block
|
||||
{
|
||||
/// @brief Start of the block's UUIDs;
|
||||
/// this must be multiplied with 4096
|
||||
/// to get the first ID's number.
|
||||
uint32_t offset;
|
||||
uint8_t num_ids;
|
||||
vx_uuid_entry_s entries[256];
|
||||
};
|
||||
|
||||
struct vx_uuid_table
|
||||
{
|
||||
uint32_t block_capacity;
|
||||
uint32_t num_blocks;
|
||||
vx_uuid_block_s **blocks;
|
||||
};
|
||||
|
||||
vx_uuid_table_s * vx_new_uuid_table();
|
||||
vx_uuid_d vx_new_uuid(vx_uuid_table_s *table);
|
||||
|
||||
#endif // VOXULA_UUID_H
|
|
@ -0,0 +1,57 @@
|
|||
#include <voxula/internals/utility/allocation.h>
|
||||
#include <voxula/internals/utility/math.h>
|
||||
#include <voxula/internals/utility/containers.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
vx_arena_s * vx_new_arena(uint32_t capacity)
|
||||
{
|
||||
vx_arena_s *arena = malloc(vx_ceil_to(sizeof(vx_arena_s), 32) + capacity);
|
||||
arena->usage = 0;
|
||||
arena->capacity = capacity;
|
||||
arena->allocation = (void *) ((int8_t *) arena) + 32;
|
||||
arena->continuation = NULL;
|
||||
return arena;
|
||||
}
|
||||
|
||||
void vx_free_arena(vx_arena_s *arena)
|
||||
{
|
||||
if(arena->continuation)
|
||||
{
|
||||
vx_free_arena(arena->continuation);
|
||||
}
|
||||
free(arena);
|
||||
}
|
||||
|
||||
void * vx_arena_alloc(vx_arena_s *arena, uint32_t length)
|
||||
{
|
||||
if((arena->usage + length) >= arena->capacity)
|
||||
{
|
||||
if( ! arena->continuation)
|
||||
{
|
||||
arena->continuation = vx_new_arena(vx_max_u64(arena->capacity * 2, length * 2));
|
||||
}
|
||||
return vx_arena_alloc(arena->continuation, length);
|
||||
}
|
||||
void *allocation = (uint8_t *) arena->allocation + arena->usage;
|
||||
arena->usage += length;
|
||||
return allocation;
|
||||
}
|
||||
|
||||
char * vx_arena_dupe_string(vx_arena_s *arena, const char *string)
|
||||
{
|
||||
uint32_t len_string = strlen(string);
|
||||
char *string_duplicate = vx_arena_alloc(arena, len_string + 1);
|
||||
memcpy(string_duplicate, string, len_string);
|
||||
return string_duplicate;
|
||||
}
|
||||
|
||||
char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum)
|
||||
{
|
||||
uint32_t length = vx_measure_string_up_to(string, maximum);
|
||||
char *string_duplicate = vx_arena_alloc(arena, length + 1);
|
||||
memcpy(string_duplicate, string, length);
|
||||
string_duplicate[length] = 0;
|
||||
return string_duplicate;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#include <voxula/internals/utility/allocation.h>
|
||||
#include <voxula/internals/utility/math.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void vx_reset_pool_allocation(vx_pool_s *pool, uint32_t slot_size)
|
||||
{
|
||||
uint32_t slot_index = 0;
|
||||
while(slot_index > pool->capacity)
|
||||
{
|
||||
vx_pool_slot_header_s *header =
|
||||
pool->allocation + slot_index * slot_size;
|
||||
|
||||
header->next =
|
||||
(void *) ((uint8_t *) pool->allocation
|
||||
+ (slot_index + 1) * slot_size);
|
||||
header->pool = pool;
|
||||
++slot_index;
|
||||
}
|
||||
vx_pool_slot_header_s *last_header = (void *)
|
||||
((uint8_t *) pool->allocation + slot_size * (pool->capacity - 1));
|
||||
last_header->next = NULL;
|
||||
}
|
||||
|
||||
vx_pool_s * vx_new_pool(uint32_t unit_size, uint32_t capacity)
|
||||
{
|
||||
uint32_t len_header = vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
|
||||
uint32_t slot_size = vx_ceil_to(unit_size + len_header, 16);
|
||||
|
||||
vx_pool_s *pool = malloc(64 + (slot_size * capacity));
|
||||
pool->allocation = (void *) vx_ceil_to((uint64_t) pool + 32, (uint64_t) 32);
|
||||
pool->first_free = pool->allocation;
|
||||
pool->unit_size = unit_size;
|
||||
pool->capacity = capacity;
|
||||
|
||||
vx_reset_pool_allocation(pool, slot_size);
|
||||
return pool;
|
||||
}
|
||||
|
||||
void vx_free_pool(vx_pool_s *pool)
|
||||
{
|
||||
if(pool->continuation)
|
||||
{
|
||||
vx_free_pool(pool->continuation);
|
||||
}
|
||||
free(pool);
|
||||
}
|
||||
|
||||
void * vx_pool(vx_pool_s *pool)
|
||||
{
|
||||
vx_pool_slot_header_s *item = pool->first_free;
|
||||
if( ! item)
|
||||
{
|
||||
if( ! pool->continuation)
|
||||
{
|
||||
pool->continuation = vx_new_pool(pool->unit_size, pool->capacity * 2);
|
||||
}
|
||||
return vx_pool(pool->allocation);
|
||||
}
|
||||
pool->first_free = item->next;
|
||||
return item + vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
|
||||
}
|
||||
|
||||
void vx_unpool(void *allocation)
|
||||
{
|
||||
vx_pool_slot_header_s *slot_header =
|
||||
allocation
|
||||
- vx_ceil_to(sizeof(vx_pool_slot_header_s), 16);
|
||||
slot_header->next = slot_header->pool->first_free;
|
||||
slot_header->pool->first_free = slot_header;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <voxula/internals/utility/containers.h>
|
||||
|
||||
uint32_t vx_measure_string_up_to(const char *string, uint32_t maximum)
|
||||
{
|
||||
uint32_t index = 0;
|
||||
while(string[index] != 0)
|
||||
{
|
||||
if(index > maximum)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return index;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#include <voxula/internals/utility/math.h>
|
||||
|
||||
uint64_t vx_min_u64(uint64_t first, uint64_t second)
|
||||
{
|
||||
if(first < second)
|
||||
{
|
||||
return first;
|
||||
}
|
||||
return second;
|
||||
}
|
||||
|
||||
uint64_t vx_max_u64(uint64_t first, uint64_t second)
|
||||
{
|
||||
if(first > second)
|
||||
{
|
||||
return first;
|
||||
}
|
||||
return second;
|
||||
}
|
||||
|
||||
uint64_t vx_ceil_to(uint64_t base, uint64_t anchor)
|
||||
{
|
||||
return base - (base % anchor) + anchor;
|
||||
}
|
||||
|
||||
uint64_t vx_ceil_pow2(uint64_t base)
|
||||
{
|
||||
// This function relies on the fact that a
|
||||
// single set bit is always a power of two.
|
||||
//
|
||||
// If the single set bit is the only one that
|
||||
// is in a number, the number itself is returned.
|
||||
//
|
||||
// If there are other bits, the next highest
|
||||
// power of two is created by returning the
|
||||
// highest set bit after it was moved one to
|
||||
// the left.
|
||||
|
||||
// Get the most significant bit that is set.
|
||||
uint64_t highest_set_bit = (uint64_t) 1 << 63;
|
||||
while(highest_set_bit > 0)
|
||||
{
|
||||
if(base & highest_set_bit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
highest_set_bit >>= 1;
|
||||
}
|
||||
if(base == highest_set_bit)
|
||||
{
|
||||
return base;
|
||||
}
|
||||
return vx_max_u64(highest_set_bit << 1, 1);
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
#include <voxula/internals/utility/math.h>
|
||||
#include <math.h>
|
||||
|
||||
vx_mat2f_s vx_mat2f_identity()
|
||||
{
|
||||
vx_mat2f_s matrix;
|
||||
matrix.val[0] = 1.0f;
|
||||
matrix.val[1] = 0.0f;
|
||||
matrix.val[2] = 0.0f;
|
||||
matrix.val[3] = 1.0f;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
vx_mat3f_s vx_mat3f_identity()
|
||||
{
|
||||
vx_mat3f_s matrix;
|
||||
matrix.val[0] = 1.0f;
|
||||
matrix.val[1] = 0.0f;
|
||||
matrix.val[2] = 0.0f;
|
||||
matrix.val[3] = 0.0f;
|
||||
matrix.val[4] = 1.0f;
|
||||
matrix.val[5] = 0.0f;
|
||||
matrix.val[6] = 0.0f;
|
||||
matrix.val[7] = 0.0f;
|
||||
matrix.val[8] = 1.0f;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_identity()
|
||||
{
|
||||
vx_mat4f_s matrix;
|
||||
matrix.val[0] = 1.0f;
|
||||
matrix.val[1] = 0.0f;
|
||||
matrix.val[2] = 0.0f;
|
||||
matrix.val[3] = 0.0f;
|
||||
matrix.val[4] = 0.0f;
|
||||
matrix.val[5] = 1.0f;
|
||||
matrix.val[6] = 0.0f;
|
||||
matrix.val[7] = 0.0f;
|
||||
matrix.val[8] = 0.0f;
|
||||
matrix.val[9] = 0.0f;
|
||||
matrix.val[10] = 1.0f;
|
||||
matrix.val[11] = 0.0f;
|
||||
matrix.val[12] = 0.0f;
|
||||
matrix.val[13] = 0.0f;
|
||||
matrix.val[14] = 0.0f;
|
||||
matrix.val[15] = 1.0f;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_translate(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s translation
|
||||
) {
|
||||
matrix.val[12] += translation.x;
|
||||
matrix.val[13] += translation.y;
|
||||
matrix.val[14] += translation.z;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_multiply(
|
||||
vx_mat4f_s first,
|
||||
vx_mat4f_s second
|
||||
) {
|
||||
vx_mat4f_s result;
|
||||
|
||||
uint8_t x_index = 0;
|
||||
uint8_t y_index = 0;
|
||||
uint8_t level = 0;
|
||||
while(x_index < 4)
|
||||
{
|
||||
y_index = 0;
|
||||
while(y_index < 4)
|
||||
{
|
||||
result.val[y_index * 4 + x_index] = 0.0f;
|
||||
level = 0;
|
||||
while(level < 4)
|
||||
{
|
||||
result.val[y_index * 4 + x_index] +=
|
||||
first.val[level * 4 + x_index]
|
||||
* second.val[y_index * 4 + level];
|
||||
++level;
|
||||
}
|
||||
++y_index;
|
||||
}
|
||||
++x_index;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_rotate_x(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
) {
|
||||
float cosine = cos(rotation);
|
||||
float sine = sin(rotation);
|
||||
vx_mat4f_s rotation_matrix;
|
||||
rotation_matrix.val[0] = 1.0f;
|
||||
rotation_matrix.val[5] = cosine;
|
||||
rotation_matrix.val[6] = -sine;
|
||||
rotation_matrix.val[9] = sine;
|
||||
rotation_matrix.val[10] = cosine;
|
||||
rotation_matrix.val[15] = 1.0f;
|
||||
vx_mat4f_multiply(matrix, rotation_matrix);
|
||||
return rotation_matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_rotate_y(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
) {
|
||||
float cosine = cos(rotation);
|
||||
float sine = sin(rotation);
|
||||
vx_mat4f_s rotation_matrix;
|
||||
rotation_matrix.val[0] = cosine;
|
||||
rotation_matrix.val[2] = sine;
|
||||
rotation_matrix.val[5] = 1.0f;
|
||||
rotation_matrix.val[8] = -sine;
|
||||
rotation_matrix.val[10] = cosine;
|
||||
rotation_matrix.val[15] = 1.0f;
|
||||
vx_mat4f_multiply(matrix, rotation_matrix);
|
||||
return rotation_matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_rotate_z(
|
||||
vx_mat4f_s matrix,
|
||||
float rotation
|
||||
) {
|
||||
float cosine = cos(rotation);
|
||||
float sine = sin(rotation);
|
||||
vx_mat4f_s rotation_matrix;
|
||||
rotation_matrix.val[0] = cosine;
|
||||
rotation_matrix.val[1] = -sine;
|
||||
rotation_matrix.val[4] = sine;
|
||||
rotation_matrix.val[5] = cosine;
|
||||
rotation_matrix.val[10] = 1.0f;
|
||||
vx_mat4f_multiply(matrix, rotation_matrix);
|
||||
return rotation_matrix;
|
||||
}
|
||||
vx_mat4f_s vx_mat4f_scale(
|
||||
vx_mat4f_s matrix,
|
||||
vx_vec3f_s scaling
|
||||
) {
|
||||
matrix.val[0] *= scaling.x;
|
||||
matrix.val[5] *= scaling.y;
|
||||
matrix.val[10] *= scaling.z;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
vx_mat4f_s vx_mat4f_perspective(
|
||||
float aspect_ratio,
|
||||
float fov,
|
||||
float near_plane,
|
||||
float far_plane
|
||||
) {
|
||||
float plane_range = tanf(fov / 2.0f) * near_plane;
|
||||
float scale_x = (2.0f * near_plane) / (plane_range * aspect_ratio * 2.0f);
|
||||
float scale_y = near_plane / plane_range;
|
||||
float scale_z = (far_plane + near_plane) / (far_plane - near_plane);
|
||||
float position_z = (2.0f * far_plane * near_plane) / (far_plane - near_plane);
|
||||
|
||||
vx_mat4f_s matrix;
|
||||
matrix.val[0] = scale_x;
|
||||
matrix.val[1] = 0.0f;
|
||||
matrix.val[2] = 0.0f;
|
||||
matrix.val[3] = 0.0f;
|
||||
matrix.val[4] = 0.0f;
|
||||
matrix.val[5] = scale_y;
|
||||
matrix.val[6] = 0.0f;
|
||||
matrix.val[7] = 0.0f;
|
||||
matrix.val[8] = 0.0f;
|
||||
matrix.val[9] = 0.0f;
|
||||
matrix.val[10] = scale_z;
|
||||
matrix.val[11] = - 1.0f;
|
||||
matrix.val[12] = 0.0f;
|
||||
matrix.val[13] = 0.0f;
|
||||
matrix.val[14] = position_z;
|
||||
matrix.val[15] = 0.0f;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
void vx_mat4f_stringify(FILE *file, vx_mat4f_s matrix)
|
||||
{
|
||||
fprintf(file, "ROW 1: %f %f %f %f\n", matrix.val[0], matrix.val[1], matrix.val[2], matrix.val[3]);
|
||||
fprintf(file, "ROW 2: %f %f %f %f\n", matrix.val[4], matrix.val[5], matrix.val[6], matrix.val[7]);
|
||||
fprintf(file, "ROW 3: %f %f %f %f\n", matrix.val[8], matrix.val[9], matrix.val[10], matrix.val[11]);
|
||||
fprintf(file, "ROW 4: %f %f %f %f\n", matrix.val[12], matrix.val[13], matrix.val[14], matrix.val[15]);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <voxula/internals/utility/math.h>
|
||||
|
||||
vx_vec3f_s vx_vec3f_negative(vx_vec3f_s vector) {
|
||||
vx_vec3f_s result;
|
||||
result.x = - vector.x;
|
||||
result.y = - vector.y;
|
||||
result.z = - vector.z;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
#include <voxula/internals/utility/uuid.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
vx_uuid_table_s * vx_new_uuid_table()
|
||||
{
|
||||
vx_uuid_table_s *table = malloc(sizeof(vx_uuid_table_s));
|
||||
table->num_blocks = 0;
|
||||
table->block_capacity = 32;
|
||||
table->blocks = malloc(table->block_capacity * sizeof(vx_uuid_block_s *));
|
||||
return table;
|
||||
}
|
||||
|
||||
bool vx_uuid_block_exists(vx_uuid_table_s *table, uint32_t offset)
|
||||
{
|
||||
uint32_t block_index = 0;
|
||||
while(block_index < table->num_blocks)
|
||||
{
|
||||
if(table->blocks[block_index]->offset == offset)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++block_index;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool vx_uuid_exists_in_block(vx_uuid_block_s *block, vx_uuid_d uuid)
|
||||
{
|
||||
uint32_t entry_index = 0;
|
||||
while(entry_index < block->num_ids)
|
||||
{
|
||||
if(block->entries[entry_index].uuid == uuid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++entry_index;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
vx_uuid_d vx_allocate_uuid_in_block(vx_uuid_block_s *block)
|
||||
{
|
||||
vx_uuid_d last_id = 0;
|
||||
if(block->num_ids)
|
||||
{
|
||||
last_id = block->entries[block->num_ids - 1].uuid;
|
||||
}
|
||||
vx_uuid_d uuid =
|
||||
block->offset * 4096
|
||||
+ last_id * 53;
|
||||
block->entries[block->num_ids].uuid = uuid;
|
||||
++block->num_ids;
|
||||
while(vx_uuid_exists_in_block(block, uuid))
|
||||
{
|
||||
++uuid;
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
vx_uuid_block_s * vx_allocate_new_id_block(vx_uuid_table_s *table)
|
||||
{
|
||||
vx_uuid_block_s *block = NULL;
|
||||
if(table->num_blocks >= table->block_capacity)
|
||||
{
|
||||
table->block_capacity *= 2;
|
||||
table->blocks = malloc(table->block_capacity * sizeof(vx_uuid_block_s *));
|
||||
}
|
||||
table->blocks[table->num_blocks] = malloc(sizeof(vx_uuid_block_s));
|
||||
block = table->blocks[table->num_blocks];
|
||||
block->num_ids = 0;
|
||||
block->offset = (table->num_blocks * 7) * 4096;
|
||||
++table->num_blocks;
|
||||
return block;
|
||||
}
|
||||
|
||||
vx_uuid_d vx_new_uuid(vx_uuid_table_s *table)
|
||||
{
|
||||
vx_uuid_block_s *block = NULL;
|
||||
|
||||
uint32_t block_index = 0;
|
||||
while(block_index < table->num_blocks)
|
||||
{
|
||||
if(table->blocks[block_index]->num_ids != 255)
|
||||
{
|
||||
block = table->blocks[block_index];
|
||||
break;
|
||||
}
|
||||
++block_index;
|
||||
}
|
||||
if( ! block)
|
||||
{
|
||||
block = vx_allocate_new_id_block(table);
|
||||
}
|
||||
return vx_allocate_uuid_in_block(block);
|
||||
}
|
Loading…
Reference in New Issue