From e28e2414859fb8dc4b8b97e305ec5a036e3b357f Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 26 Nov 2025 18:22:22 -0600 Subject: [PATCH] cleanup --- meson.build | 1 - qopconv.c | 491 ---------- scripts/compile.ce | 85 ++ scripts/doc.cm | 1 - scripts/engine.cm | 2 + source/HandmadeMath.c | 2019 ----------------------------------------- source/HandmadeMath.h | 673 -------------- source/cell.h | 9 +- source/jsffi.c | 479 +--------- source/jsffi.h | 95 -- source/qjs_actor.c | 1 - source/qjs_debug.c | 2 +- source/qjs_fd.c | 1 - source/qjs_fit.c | 2 +- source/qjs_js.c | 1 - source/qjs_kim.c | 1 - source/qjs_macros.h | 40 + source/qjs_math.c | 491 ---------- source/qjs_os.c | 14 +- source/qjs_qop.c | 1 - source/qjs_socket.c | 1 - source/qjs_soloud.c | 24 - source/qjs_utf8.c | 1 - source/qjs_wildstar.c | 2 +- tangletart.bat | 3 - 25 files changed, 150 insertions(+), 4290 deletions(-) delete mode 100644 qopconv.c create mode 100644 scripts/compile.ce delete mode 100644 source/HandmadeMath.c delete mode 100644 source/HandmadeMath.h delete mode 100644 source/qjs_math.c delete mode 100644 tangletart.bat diff --git a/meson.build b/meson.build index 5a53a9bb..b43b4270 100644 --- a/meson.build +++ b/meson.build @@ -255,7 +255,6 @@ src += 'qjs_http.c' src += [ # engine 'qjs_soloud.c', - 'HandmadeMath.c', ] src += ['quickjs.c', 'libregexp.c', 'libunicode.c', 'cutils.c', 'dtoa.c'] diff --git a/qopconv.c b/qopconv.c deleted file mode 100644 index 3cedc9fa..00000000 --- a/qopconv.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - -Copyright (c) 2024, Dominic Szablewski - https://phoboslab.org -SPDX-License-Identifier: MIT - - -Command line tool to create and unpack qop archives - -*/ - -#define _DEFAULT_SOURCE -#include -#include -#include -#include -#include - -#define QOP_IMPLEMENTATION -#include "qop.h" - -#define MAX_PATH_LEN 1024 -#define BUFFER_SIZE 4096 - -#define UNUSED(x) (void)(x) -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) -#define die(...) \ - printf("Abort at " TOSTRING(__FILE__) " line " TOSTRING(__LINE__) ": " __VA_ARGS__); \ - printf("\n"); \ - exit(1) - -#define error_if(TEST, ...) \ - if (TEST) { \ - die(__VA_ARGS__); \ - } - - -// ----------------------------------------------------------------------------- -// Platform specific file/dir handling - -typedef struct { - char *name; - unsigned char is_dir; - unsigned char is_file; -} pi_dirent; - -#if defined(_WIN32) - #include - - typedef struct { - WIN32_FIND_DATA data; - pi_dirent current; - HANDLE dir; - unsigned char is_first; - } pi_dir; - - pi_dir *pi_dir_open(const char *path) { - char find_str[MAX_PATH_LEN]; - snprintf(find_str, MAX_PATH_LEN, "%s/*", path); - - pi_dir *d = malloc(sizeof(pi_dir)); - d->is_first = 1; - d->dir = FindFirstFile(find_str, &d->data); - if (d->dir == INVALID_HANDLE_VALUE) { - free(d); - return NULL; - } - return d; - } - - pi_dirent *pi_dir_next(pi_dir *d) { - if (!d->is_first) { - if (FindNextFile(d->dir, &d->data) == 0) { - return NULL; - } - } - d->is_first = 0; - d->current.name = d->data.cFileName; - d->current.is_dir = d->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - d->current.is_file = !d->current.is_dir; - return &d->current; - } - - void pi_dir_close(pi_dir *d) { - FindClose(d->dir); - free(d); - } - - int pi_mkdir(char *path, int mode) { - UNUSED(mode); - return CreateDirectory(path, NULL) ? 0 : -1; - } -#else - #include - - typedef struct { - DIR *dir; - struct dirent *data; - pi_dirent current; - } pi_dir; - - pi_dir *pi_dir_open(const char *path) { - DIR *dir = opendir(path); - if (!dir) { - return NULL; - } - pi_dir *d = malloc(sizeof(pi_dir)); - d->dir = dir; - return d; - } - - pi_dirent *pi_dir_next(pi_dir *d) { - d->data = readdir(d->dir); - if (!d->data) { - return NULL; - } - d->current.name = d->data->d_name; - d->current.is_dir = d->data->d_type & DT_DIR; - d->current.is_file = d->data->d_type == DT_REG; - return &d->current; - } - - void pi_dir_close(pi_dir *d) { - closedir(d->dir); - free(d); - } - - int pi_mkdir(char *path, int mode) { - return mkdir(path, mode); - } -#endif - - -// ----------------------------------------------------------------------------- -// Unpack - -int create_path(const char *path, const mode_t mode) { - char tmp[MAX_PATH_LEN]; - char *p = NULL; - struct stat sb; - size_t len; - - // copy path - len = strnlen(path, MAX_PATH_LEN); - if (len == 0 || len == MAX_PATH_LEN) { - return -1; - } - memcpy(tmp, path, len); - tmp[len] = '\0'; - - // remove file part - char *last_slash = strrchr(tmp, '/'); - if (last_slash == NULL) { - return 0; - } - *last_slash = '\0'; - - // check if path exists and is a directory - if (stat(tmp, &sb) == 0) { - if (S_ISDIR(sb.st_mode)) { - return 0; - } - } - - // recursive mkdir - for (p = tmp + 1; *p; p++) { - if (*p == '/') { - *p = 0; - if (stat(tmp, &sb) != 0) { - if (pi_mkdir(tmp, mode) < 0) { - return -1; - } - } - else if (!S_ISDIR(sb.st_mode)) { - return -1; - } - *p = '/'; - } - } - if (stat(tmp, &sb) != 0) { - if (pi_mkdir(tmp, mode) < 0) { - return -1; - } - } - else if (!S_ISDIR(sb.st_mode)) { - return -1; - } - return 0; -} - -unsigned int copy_out(FILE *src, unsigned int offset, unsigned int size, const char *dest_path) { - FILE *dest = fopen(dest_path, "wb"); - error_if(!dest, "Could not open file %s for writing", dest_path); - - char buffer[BUFFER_SIZE]; - size_t bytes_read, bytes_written; - unsigned int bytes_total = 0; - unsigned int read_size = size < BUFFER_SIZE ? size : BUFFER_SIZE; - - fseek(src, offset, SEEK_SET); - while (read_size > 0 && (bytes_read = fread(buffer, 1, read_size, src)) > 0) { - bytes_written = fwrite(buffer, 1, bytes_read, dest); - error_if(bytes_written != bytes_read, "Write error"); - bytes_total += bytes_written; - if (bytes_total >= size) { - break; - } - if (size - bytes_total < read_size) { - read_size = size - bytes_total; - } - } - - error_if(ferror(src), "read error for file %s", dest_path); - fclose(dest); - return bytes_total; -} - -void unpack(const char *archive_path, int list_only) { - qop_desc qop; - int archive_size = qop_open(archive_path, &qop); - error_if(archive_size == 0, "Could not open archive %s", archive_path); - - // Read the archive index - int index_len = qop_read_index(&qop, malloc(qop.hashmap_size)); - error_if(index_len == 0, "Could not read index from archive %s", archive_path); - - // Extract all files - for (unsigned int i = 0; i < qop.hashmap_len; i++) { - qop_file *file = &qop.hashmap[i]; - if (file->size == 0) { - continue; - } - error_if(file->path_len >= MAX_PATH_LEN, "Path for file %016llx exceeds %d", file->hash, MAX_PATH_LEN); - char path[MAX_PATH_LEN]; - qop_read_path(&qop, file, path); - - // Integrity check - // error_if(!qop_find(&qop, path), "could not find %s", path); - - printf("%6d %016llx %10d %s\n", i, file->hash, file->size, path); - - if (!list_only) { - error_if(create_path(path, 0755) != 0, "Could not create path %s", path); - copy_out(qop.fh, qop.files_offset + file->offset + file->path_len, file->size, path); - } - } - - free(qop.hashmap); - qop_close(&qop); -} - - -// ----------------------------------------------------------------------------- -// Pack - -typedef struct { - qop_file *files; - int len; - int capacity; - int size; - char dest_path[MAX_PATH_LEN]; -} pack_state; - -int canonicalize_path(const char *path, char *buffer, size_t buffer_len) { -#if defined(_WIN32) - return _fullpath(buffer, path, buffer_len) != NULL; -#else - UNUSED(buffer_len); - return realpath(path, buffer) != NULL; -#endif -} - -void write_16(unsigned int v, FILE *fh) { - unsigned char b[sizeof(unsigned short)]; - b[0] = 0xff & (v ); - b[1] = 0xff & (v >> 8); - int written = fwrite(b, sizeof(unsigned short), 1, fh); - error_if(!written, "Write error"); -} - -void write_32(unsigned int v, FILE *fh) { - unsigned char b[sizeof(unsigned int)]; - b[0] = 0xff & (v ); - b[1] = 0xff & (v >> 8); - b[2] = 0xff & (v >> 16); - b[3] = 0xff & (v >> 24); - int written = fwrite(b, sizeof(unsigned int), 1, fh); - error_if(!written, "Write error"); -} - -void write_64(qop_uint64_t v, FILE *fh) { - unsigned char b[sizeof(qop_uint64_t)]; - b[0] = 0xff & (v ); - b[1] = 0xff & (v >> 8); - b[2] = 0xff & (v >> 16); - b[3] = 0xff & (v >> 24); - b[4] = 0xff & (v >> 32); - b[5] = 0xff & (v >> 40); - b[6] = 0xff & (v >> 48); - b[7] = 0xff & (v >> 56); - int written = fwrite(b, sizeof(qop_uint64_t), 1, fh); - error_if(!written, "Write error"); -} - -unsigned int copy_into(const char *src_path, FILE *dest) { - FILE *src = fopen(src_path, "rb"); - error_if(!src, "Could not open file %s for reading", src_path); - - char buffer[BUFFER_SIZE]; - size_t bytes_read, bytes_written; - unsigned int bytes_total = 0; - - while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, src)) > 0) { - bytes_written = fwrite(buffer, 1, bytes_read, dest); - error_if(bytes_written != bytes_read, "Write error"); - bytes_total += bytes_written; - } - - error_if(ferror(src), "read error for file %s", src_path); - fclose(src); - return bytes_total; -} - -void add_file(const char *path, FILE *dest, pack_state *state) { - if (state->dest_path[0]) { - char absolute[MAX_PATH_LEN]; - if (canonicalize_path(path, absolute, MAX_PATH_LEN) && strcmp(absolute, state->dest_path) == 0) { - return; - } - } - - if (state->len >= state->capacity) { - state->capacity *= 2; - state->files = realloc(state->files, state->capacity * sizeof(qop_file)); - } - - // Strip leading "./" from path for archive - const char *archive_path = path; - if (path[0] == '.' && path[1] == '/') { - archive_path = path + 2; - } - - qop_uint64_t hash = qop_hash(archive_path); - - - // Write the path into the archive - int path_len = strlen(archive_path) + 1; - int path_written = fwrite(archive_path, sizeof(char), path_len, dest); - error_if(path_written != path_len, "Write error"); - - // Copy the file into the archive - unsigned int size = copy_into(path, dest); - - printf("%6d %016llx %10d %s\n", state->len, hash, size, archive_path); - - // Collect file info for the index - state->files[state->len] = (qop_file){ - .hash = hash, - .offset = state->size, - .size = size, - .path_len = path_len, - .flags = QOP_FLAG_NONE - }; - state->size += size + path_len; - state->len++; -} - -void add_dir(const char *path, FILE *dest, pack_state *state) { - pi_dir *dir = pi_dir_open(path); - error_if(!dir, "Could not open directory %s for reading", path); - - pi_dirent *entry; - while ((entry = pi_dir_next(dir))) { - if ( - entry->is_dir && - strcmp(entry->name, ".") != 0 && - strcmp(entry->name, "..") != 0 - ) { - char subpath[MAX_PATH_LEN]; - snprintf(subpath, MAX_PATH_LEN, "%s/%s", path, entry->name); - add_dir(subpath, dest, state); - } - else if (entry->is_file) { - char subpath[MAX_PATH_LEN]; - snprintf(subpath, MAX_PATH_LEN, "%s/%s", path, entry->name); - add_file(subpath, dest, state); - } - } - pi_dir_close(dir); -} - -void pack(const char *read_dir, char **sources, int sources_len, const char *archive_path) { - FILE *dest = fopen(archive_path, "wb"); - error_if(!dest, "Could not open file %s for writing", archive_path); - - pack_state state; - state.files = malloc(sizeof(qop_file) * 1024); - state.len = 0; - state.capacity = 1024; - state.size = 0; - state.dest_path[0] = '\0'; - if (!canonicalize_path(archive_path, state.dest_path, MAX_PATH_LEN)) { - state.dest_path[0] = '\0'; - } - - if (read_dir) { - error_if(chdir(read_dir) != 0, "Could not change to directory %s", read_dir); - } - - // Add files/directories - for (int i = 0; i < sources_len; i++) { - struct stat s; - error_if(stat(sources[i], &s) != 0, "Could not stat file %s", sources[i]); - if (S_ISDIR(s.st_mode)) { - add_dir(sources[i], dest, &state); - } - else if (S_ISREG(s.st_mode)) { - add_file(sources[i], dest, &state); - } - else { - die("Path %s is neither a directory nor a regular file", sources[i]); - } - } - - // Write index and header - unsigned int total_size = state.size + QOP_HEADER_SIZE; - for (int i = 0; i < state.len; i++) { - write_64(state.files[i].hash, dest); - write_32(state.files[i].offset, dest); - write_32(state.files[i].size, dest); - write_16(state.files[i].path_len, dest); - write_16(state.files[i].flags, dest); - total_size += 20; - } - - write_32(state.len, dest); - write_32(total_size, dest); - write_32(QOP_MAGIC, dest); - - free(state.files); - fclose(dest); - - printf("files: %d, size: %d bytes\n", state.len, total_size); -} - -void exit_usage(void) { - puts( - "Usage: qopconv [OPTION...] FILE...\n" - "\n" - "Examples:\n" - " qopconv dir1 archive.qop # Create archive.qop from dir1/\n" - " qopconv foo bar archive.qop # Create archive.qop from files foo and bar\n" - " qoponvv -u archive.qop # Unpack archive.qop in current directory\n" - " qopconv -l archive.qop # List files in archive.qop\n" - " qopconv -d dir1 dir2 archive.qop # Use dir1 prefix for reading, create\n" - " archive.qop from files in dir1/dir2/\n" - "\n" - "Options (mutually exclusive):\n" - " -u ... unpack archive\n" - " -l ... list contents of archive\n" - " -d ....... change read dir when creating archives\n" - ); - exit(1); -} - -int main(int argc, char **argv) { - if (argc < 3) { - exit_usage(); - } - - // Unpack - if (strcmp(argv[1], "-u") == 0) { - unpack(argv[2], 0); - } - else if (strcmp(argv[1], "-l") == 0) { - unpack(argv[2], 1); - } - else { - int files_start = 1; - char *read_dir = NULL; - if (strcmp(argv[1], "-d") == 0) { - read_dir = argv[2]; - files_start = 3; - } - if (argc < 2 + files_start) { - exit_usage(); - } - pack(read_dir, argv + files_start, argc - 1 - files_start, argv[argc-1]); - } - return 0; -} \ No newline at end of file diff --git a/scripts/compile.ce b/scripts/compile.ce new file mode 100644 index 00000000..18558f33 --- /dev/null +++ b/scripts/compile.ce @@ -0,0 +1,85 @@ +// cell compile +var os = use('os') +var io = use('cellfs') + +log.console(json.encode(cell.config)) + +var project_name = cell.config.project.name + +if (!project_name) { + log.console("Error: project.name not found in cell.toml") + $_.stop() +} + +log.console("Building project: " + project_name) + +// 2. Prepare output directory +if (!io.exists('.cell')) { + io.mkdir('.cell') +} + +// 3. Find source files +var files = io.enumerate('.', true) +var objects = [] + +for (var i = 0; i < files.length; i++) { + var file = files[i] + if (file.endsWith('.c')) { + var path_no_ext = file.substring(0, file.length - 2) + var safe_path = path_no_ext.replace(/\//g, '_').replace(/\\/g, '_') + if (safe_path.startsWith('._')) safe_path = safe_path.substring(2) + + var use_name = 'js_' + project_name + '_' + safe_path + '_use' + + var obj_file = '.cell/build/' + file + '.o' + var obj_dir = io.realdir(obj_file) + var last_slash = file.lastIndexOf('/') + if (last_slash != -1) { + var dir = '.cell/build/' + file.substring(0, last_slash) + if (!io.exists(dir)) { + obj_file = '.cell/build/' + safe_path + '.o' + } + } else { + obj_file = '.cell/build/' + file + '.o' + } + + objects.push(obj_file) + + log.console("Compiling " + file + " -> " + obj_file) + log.console(`export name is ${use_name}`) + + // Compile command + // cc -fPIC -c -O3 -DCELL_USE_NAME= -o + var cmd = 'cc -fPIC -c ' + file + ' -O3 -DCELL_USE_NAME=' + use_name + ' -o ' + obj_file + var ret = os.system(cmd) + if (ret != 0) { + log.console("Compilation failed for " + file) + $_.stop() + } + } +} + +// 4. Link shared library +var lib_ext = '.so' +var link_flags = '-shared' +if (os.platform() == 'macOS') { + lib_ext = '.dylib' + link_flags = '-shared' +} else if (os.platform() == 'Windows') { + lib_ext = '.dll' +} + +var lib_name = project_name + lib_ext +log.console("Linking " + lib_name) + +var link_cmd = 'cc ' + link_flags + ' ' + objects.join(' ') + ' -lcell -o ' + lib_name +var ret = os.system(link_cmd) + +if (ret != 0) { + log.console("Linking failed") + $_.stop() +} + +log.console("Build complete: " + lib_name) + +$_.stop() \ No newline at end of file diff --git a/scripts/doc.cm b/scripts/doc.cm index 505754d6..a9acdaba 100644 --- a/scripts/doc.cm +++ b/scripts/doc.cm @@ -1,4 +1,3 @@ -// doc.js function docOf(obj, prop) { var block = obj[cell.DOC]; if (!block) return ''; diff --git a/scripts/engine.cm b/scripts/engine.cm index 2bcfd27c..def7b6de 100644 --- a/scripts/engine.cm +++ b/scripts/engine.cm @@ -497,6 +497,8 @@ config ??= {} config.system ??= {} config.system.__proto__ = default_config +cell.config = config + ENETSERVICE = config.system.net_service REPLYTIMEOUT = config.system.reply_timeout diff --git a/source/HandmadeMath.c b/source/HandmadeMath.c deleted file mode 100644 index 46394417..00000000 --- a/source/HandmadeMath.c +++ /dev/null @@ -1,2019 +0,0 @@ -#include "HandmadeMath.h" -#include -#include - -const HMM_Vec2 v2zero = {0,0}; -const HMM_Vec2 v2one = {1,1}; -const HMM_Vec3 v3zero = {0,0,0}; -const HMM_Vec3 v3one = {1,1,1}; -const HMM_Vec4 v4zero = {0,0,0,0}; - -const HMM_Vec3 vX = {1.0,0.0,0.0}; -const HMM_Vec3 vY = {0.0,1.0,0.0}; -const HMM_Vec3 vZ = {0.0,0.0,1.0}; - -const HMM_Vec3 vUP = {0,1,0}; -const HMM_Vec3 vDOWN = {0,-1,0}; -const HMM_Vec3 vFWD = {0,0,-1}; -const HMM_Vec3 vBKWD = {0,0,1}; -const HMM_Vec3 vLEFT = {-1,0,0}; -const HMM_Vec3 vRIGHT = {1,0,0}; - -const HMM_Mat4 MAT1 = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; -const HMM_Quat QUAT1 = {0,0,0,1}; - -/* - * Angle unit conversion functions - */ -float HMM_ToRad(float Angle) { -#if defined(HANDMADE_MATH_USE_RADIANS) - float Result = Angle; -#elif defined(HANDMADE_MATH_USE_DEGREES) - float Result = Angle * HMM_DegToRad; -#elif defined(HANDMADE_MATH_USE_TURNS) - float Result = Angle * HMM_TurnToRad; -#endif - - return Result; -} - -float HMM_ToDeg(float Angle) { -#if defined(HANDMADE_MATH_USE_RADIANS) - float Result = Angle * HMM_RadToDeg; -#elif defined(HANDMADE_MATH_USE_DEGREES) - float Result = Angle; -#elif defined(HANDMADE_MATH_USE_TURNS) - float Result = Angle * HMM_TurnToDeg; -#endif - - return Result; -} - -float HMM_ToTurn(float Angle) { -#if defined(HANDMADE_MATH_USE_RADIANS) - float Result = Angle * HMM_RadToTurn; -#elif defined(HANDMADE_MATH_USE_DEGREES) - float Result = Angle * HMM_DegToTurn; -#elif defined(HANDMADE_MATH_USE_TURNS) - float Result = Angle; -#endif - - return Result; -} - -/* - * Floating-point math functions - */ - -float HMM_SinF(float Angle) { - return HMM_SINF(HMM_ANGLE_USER_TO_INTERNAL(Angle)); -} - -float HMM_CosF(float Angle) { - return HMM_COSF(HMM_ANGLE_USER_TO_INTERNAL(Angle)); -} - -float HMM_TanF(float Angle) { - return HMM_TANF(HMM_ANGLE_USER_TO_INTERNAL(Angle)); -} - -float HMM_ACosF(float Arg) { - return HMM_ANGLE_INTERNAL_TO_USER(HMM_ACOSF(Arg)); -} - -float HMM_SqrtF(float Float) { - - float Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 In = _mm_set_ss(Float); - __m128 Out = _mm_sqrt_ss(In); - Result = _mm_cvtss_f32(Out); -#else - Result = HMM_SQRTF(Float); -#endif - - return Result; -} - -float HMM_InvSqrtF(float Float) { - - float Result; - - Result = 1.0f / HMM_SqrtF(Float); - - return Result; -} - -/* - * Utility functions - */ - -float HMM_Lerp(float A, float Time, float B) { - return (1.0f - Time) * A + Time * B; -} - -float HMM_Clamp(float Min, float Value, float Max) { - - float Result = Value; - - if (Result < Min) { - Result = Min; - } - - if (Result > Max) { - Result = Max; - } - - return Result; -} - -float frand(float max) { - return ((float)rand()/(float)(RAND_MAX))*max; -} - -/* - * Vector initialization - */ - -HMM_Vec2 HMM_V2(float X, float Y) { - - HMM_Vec2 Result; - Result.X = X; - Result.Y = Y; - - return Result; -} - -HMM_Vec3 HMM_V3(float X, float Y, float Z) { - - HMM_Vec3 Result; - Result.X = X; - Result.Y = Y; - Result.Z = Z; - - return Result; -} - -HMM_Vec3 HMM_V3i(float i) -{ - return (HMM_Vec3){i,i,i}; -} - -HMM_Vec4 HMM_V4(float X, float Y, float Z, float W) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_setr_ps(X, Y, Z, W); -#else - Result.X = X; - Result.Y = Y; - Result.Z = Z; - Result.W = W; -#endif - - return Result; -} - -HMM_Vec4 HMM_V4V(HMM_Vec3 Vector, float W) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_setr_ps(Vector.X, Vector.Y, Vector.Z, W); -#else - Result.XYZ = Vector; - Result.W = W; -#endif - - return Result; -} - -/* - * Binary vector operations - */ - -HMM_Vec2 HMM_AddV2(HMM_Vec2 Left, HMM_Vec2 Right) { - - HMM_Vec2 Result; - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - - return Result; -} - - -HMM_Vec3 HMM_AddV3(HMM_Vec3 Left, HMM_Vec3 Right) { - - HMM_Vec3 Result; - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - - return Result; -} - -HMM_Vec4 HMM_AddV4(HMM_Vec4 Left, HMM_Vec4 Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_NEON - Result.NEON = vaddq_f32(Left.NEON, Right.NEON); - #elif defined(HANDMADE_MATH__USE_SSE) - Result.SSE = _mm_add_ps(Left.SSE, Right.SSE); - #else - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - Result.W = Left.W + Right.W; -#endif - - return Result; -} - -HMM_Vec2 HMM_SubV2(HMM_Vec2 Left, HMM_Vec2 Right) { - - HMM_Vec2 Result; - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - - return Result; -} - -HMM_Vec3 HMM_SubV3(HMM_Vec3 Left, HMM_Vec3 Right) { - - HMM_Vec3 Result; - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - - return Result; -} - -HMM_Vec4 HMM_SubV4(HMM_Vec4 Left, HMM_Vec4 Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_sub_ps(Left.SSE, Right.SSE); -#else - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - Result.W = Left.W - Right.W; -#endif - - return Result; -} - -HMM_Vec2 HMM_ScaleV2(HMM_Vec2 v, double s) -{ - return HMM_V2(v.X*s, v.Y*s); -} - -HMM_Vec2 HMM_MulV2(HMM_Vec2 Left, HMM_Vec2 Right) { - - HMM_Vec2 Result; - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - - return Result; -} - -HMM_Vec2 HMM_MulV2F(HMM_Vec2 Left, float Right) { - - HMM_Vec2 Result; - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - - return Result; -} - -HMM_Vec3 HMM_MulV3(HMM_Vec3 Left, HMM_Vec3 Right) { - - HMM_Vec3 Result; - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - Result.Z = Left.Z * Right.Z; - - return Result; -} - -HMM_Vec3 HMM_MulV3F(HMM_Vec3 Left, float Right) { - - HMM_Vec3 Result; - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - Result.Z = Left.Z * Right; - - return Result; -} - -HMM_Vec4 HMM_MulV4(HMM_Vec4 Left, HMM_Vec4 Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_NEON - Result.NEON = vmulq_f32(Left.NEON, Right.NEON); - #elif defined(HANDMADE_MATH__USE_SSE) - Result.SSE = _mm_mul_ps(Left.SSE, Right.SSE); - #else - Result.X = Left.X * Right.X; - Result.Y = Left.Y * Right.Y; - Result.Z = Left.Z * Right.Z; - Result.W = Left.W * Right.W; -#endif - - return Result; -} - -HMM_Vec4 HMM_MulV4F(HMM_Vec4 Left, float Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Right); - Result.SSE = _mm_mul_ps(Left.SSE, Scalar); -#else - Result.X = Left.X * Right; - Result.Y = Left.Y * Right; - Result.Z = Left.Z * Right; - Result.W = Left.W * Right; -#endif - - return Result; -} - -HMM_Vec2 HMM_DivV2(HMM_Vec2 Left, HMM_Vec2 Right) { - - HMM_Vec2 Result; - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - - return Result; -} - -HMM_Vec2 HMM_DivV2F(HMM_Vec2 Left, float Right) { - - HMM_Vec2 Result; - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - - return Result; -} - -HMM_Vec3 HMM_DivV3(HMM_Vec3 Left, HMM_Vec3 Right) { - - HMM_Vec3 Result; - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - Result.Z = Left.Z / Right.Z; - - return Result; -} - -HMM_Vec3 HMM_DivV3F(HMM_Vec3 Left, float Right) { - - HMM_Vec3 Result; - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - Result.Z = Left.Z / Right; - - return Result; -} - -HMM_Vec4 HMM_DivV4(HMM_Vec4 Left, HMM_Vec4 Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_div_ps(Left.SSE, Right.SSE); -#else - Result.X = Left.X / Right.X; - Result.Y = Left.Y / Right.Y; - Result.Z = Left.Z / Right.Z; - Result.W = Left.W / Right.W; -#endif - - return Result; -} - -HMM_Vec4 HMM_DivV4F(HMM_Vec4 Left, float Right) { - - HMM_Vec4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Right); - Result.SSE = _mm_div_ps(Left.SSE, Scalar); -#else - Result.X = Left.X / Right; - Result.Y = Left.Y / Right; - Result.Z = Left.Z / Right; - Result.W = Left.W / Right; -#endif - - return Result; -} - -HMM_Bool HMM_EqV2(HMM_Vec2 Left, HMM_Vec2 Right) { - return Left.X == Right.X && Left.Y == Right.Y; -} - -HMM_Bool HMM_EqV3(HMM_Vec3 Left, HMM_Vec3 Right) { - return Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z; -} - -HMM_Bool HMM_EqV4(HMM_Vec4 Left, HMM_Vec4 Right) { - return Left.X == Right.X && Left.Y == Right.Y && Left.Z == Right.Z && Left.W == Right.W; -} - -float HMM_DotV2(HMM_Vec2 Left, HMM_Vec2 Right) { - return (Left.X * Right.X) + (Left.Y * Right.Y); -} - -HMM_Vec2 HMM_ProjV2(HMM_Vec2 a, HMM_Vec2 b) -{ - return HMM_MulV2F(b, HMM_DotV2(a,b)/HMM_DotV2(b,b)); -} - -float HMM_DotV3(HMM_Vec3 Left, HMM_Vec3 Right) { - return (Left.X * Right.X) + (Left.Y * Right.Y) + (Left.Z * Right.Z); -} - -float HMM_DotV4(HMM_Vec4 Left, HMM_Vec4 Right) { - - float Result; - - // NOTE(zak): IN the future if we wanna check what version SSE is support - // we can use _mm_dp_ps (4.3) but for now we will use the old way. - // Or a r = _mm_mul_ps(v1, v2), r = _mm_hadd_ps(r, r), r = _mm_hadd_ps(r, r) for SSE3 -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_mul_ps(Left.SSE, Right.SSE); - __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - _mm_store_ss(&Result, SSEResultOne); -#else - Result = ((Left.X * Right.X) + (Left.Z * Right.Z)) + ((Left.Y * Right.Y) + (Left.W * Right.W)); -#endif - - return Result; -} - -HMM_Vec3 HMM_Cross(HMM_Vec3 Left, HMM_Vec3 Right) { - - HMM_Vec3 Result; - Result.X = (Left.Y * Right.Z) - (Left.Z * Right.Y); - Result.Y = (Left.Z * Right.X) - (Left.X * Right.Z); - Result.Z = (Left.X * Right.Y) - (Left.Y * Right.X); - - return Result; -} - -/* - * Unary vector operations - */ - -float HMM_LenSqrV2(HMM_Vec2 A) { - return HMM_DotV2(A, A); -} - -float HMM_LenSqrV3(HMM_Vec3 A) { - return HMM_DotV3(A, A); -} - -float HMM_LenSqrV4(HMM_Vec4 A) { - return HMM_DotV4(A, A); -} - -float HMM_LenV2(HMM_Vec2 A) { - return HMM_SqrtF(HMM_LenSqrV2(A)); -} - -float HMM_AngleV2(HMM_Vec2 a, HMM_Vec2 b) -{ - return acos(HMM_DotV2(a,b)/(HMM_LenV2(a)*HMM_LenV2(b))); -} - -float HMM_DistV2(HMM_Vec2 a, HMM_Vec2 b) { - return HMM_LenV2(HMM_SubV2(a,b)); -} - -HMM_Vec2 HMM_V2Rotate(HMM_Vec2 v, float angle) -{ - float r = HMM_LenV2(v); - angle += atan2(v.x, v.y); - return (HMM_Vec2){r*cos(angle), r*sin(angle)}; -} - -float HMM_LenV3(HMM_Vec3 A) { - return HMM_SqrtF(HMM_LenSqrV3(A)); -} - -float HMM_DistV3(HMM_Vec3 a, HMM_Vec3 b) { - return HMM_LenV3(HMM_SubV3(a,b)); -} - -float HMM_AngleV3(HMM_Vec3 a, HMM_Vec3 b) -{ - return acos(HMM_DotV3(a,b)/(HMM_LenV3(a)*HMM_LenV3(b))); -} - -float HMM_LenV4(HMM_Vec4 A) { - return HMM_SqrtF(HMM_LenSqrV4(A)); -} - -float HMM_AngleV4(HMM_Vec4 a, HMM_Vec4 b) -{ - return acos(HMM_DotV4(a,b)/(HMM_LenV4(a)*HMM_LenV4(b))); -} - -HMM_Vec2 HMM_NormV2(HMM_Vec2 A) { - return HMM_MulV2F(A, HMM_InvSqrtF(HMM_DotV2(A, A))); -} - -HMM_Vec3 HMM_NormV3(HMM_Vec3 A) { - return HMM_MulV3F(A, HMM_InvSqrtF(HMM_DotV3(A, A))); -} - -HMM_Vec4 HMM_NormV4(HMM_Vec4 A) { - return HMM_MulV4F(A, HMM_InvSqrtF(HMM_DotV4(A, A))); -} - -/* - * Utility vector functions - */ - -HMM_Vec2 HMM_LerpV2(HMM_Vec2 A, float Time, HMM_Vec2 B) { - return HMM_AddV2(HMM_MulV2F(A, 1.0f - Time), HMM_MulV2F(B, Time)); -} - -HMM_Vec3 HMM_LerpV3(HMM_Vec3 A, float Time, HMM_Vec3 B) { - return HMM_AddV3(HMM_MulV3F(A, 1.0f - Time), HMM_MulV3F(B, Time)); -} - -HMM_Vec4 HMM_LerpV4(HMM_Vec4 A, float Time, HMM_Vec4 B) { - return HMM_AddV4(HMM_MulV4F(A, 1.0f - Time), HMM_MulV4F(B, Time)); -} - -/* - * SSE stuff - */ - - HMM_Vec4 HMM_LinearCombineV4M4_P(HMM_Vec4 *Left, HMM_Mat4 *Right) - { - HMM_Vec4 Result; - - #ifdef HANDMADE_MATH__USE_NEON - float32x4_t a = Left->NEON; - - float x = vgetq_lane_f32(a, 0); - float y = vgetq_lane_f32(a, 1); - float z = vgetq_lane_f32(a, 2); - float w = vgetq_lane_f32(a, 3); - - float32x4_t r0 = vmulq_n_f32(Right->Columns[0].NEON, x); - float32x4_t r1 = vmulq_n_f32(Right->Columns[1].NEON, y); - float32x4_t r2 = vmulq_n_f32(Right->Columns[2].NEON, z); - float32x4_t r3 = vmulq_n_f32(Right->Columns[3].NEON, w); - - float32x4_t sum = vaddq_f32(r0, r1); - sum = vaddq_f32(sum, r2); - sum = vaddq_f32(sum, r3); - - Result.NEON = sum; - #elif defined(HANDMADE_MATH__USE_SSE) - Result.SSE = _mm_mul_ps(_mm_shuffle_ps(Left->SSE, Left->SSE, 0x00), Right->Columns[0].SSE); - Result.SSE = _mm_add_ps(Result.SSE, _mm_mul_ps(_mm_shuffle_ps(Left->SSE, Left->SSE, 0x55), Right->Columns[1].SSE)); - Result.SSE = _mm_add_ps(Result.SSE, _mm_mul_ps(_mm_shuffle_ps(Left->SSE, Left->SSE, 0xaa), Right->Columns[2].SSE)); - Result.SSE = _mm_add_ps(Result.SSE, _mm_mul_ps(_mm_shuffle_ps(Left->SSE, Left->SSE, 0xff), Right->Columns[3].SSE)); - - #else - Result.X = Left->Elements[0] * Right->Columns[0].X; - Result.Y = Left->Elements[0] * Right->Columns[0].Y; - Result.Z = Left->Elements[0] * Right->Columns[0].Z; - Result.W = Left->Elements[0] * Right->Columns[0].W; - - Result.X += Left->Elements[1] * Right->Columns[1].X; - Result.Y += Left->Elements[1] * Right->Columns[1].Y; - Result.Z += Left->Elements[1] * Right->Columns[1].Z; - Result.W += Left->Elements[1] * Right->Columns[1].W; - - Result.X += Left->Elements[2] * Right->Columns[2].X; - Result.Y += Left->Elements[2] * Right->Columns[2].Y; - Result.Z += Left->Elements[2] * Right->Columns[2].Z; - Result.W += Left->Elements[2] * Right->Columns[2].W; - - Result.X += Left->Elements[3] * Right->Columns[3].X; - Result.Y += Left->Elements[3] * Right->Columns[3].Y; - Result.Z += Left->Elements[3] * Right->Columns[3].Z; - Result.W += Left->Elements[3] * Right->Columns[3].W; - #endif - - return Result; - } - -HMM_Vec4 HMM_LinearCombineV4M4(HMM_Vec4 Left, HMM_Mat4 Right) { - return HMM_LinearCombineV4M4_P(&Left, &Right); - } - -/* - * 2x2 Matrices - */ - -HMM_Mat2 HMM_M2(void) { - HMM_Mat2 Result = {0}; - return Result; -} - -HMM_Mat2 HMM_M2D(float Diagonal) { - - HMM_Mat2 Result = {0}; - Result.Elements[0][0] = Diagonal; - Result.Elements[1][1] = Diagonal; - - return Result; -} - -HMM_Mat2 HMM_TransposeM2(HMM_Mat2 Matrix) { - - HMM_Mat2 Result = Matrix; - - Result.Elements[0][1] = Matrix.Elements[1][0]; - Result.Elements[1][0] = Matrix.Elements[0][1]; - - return Result; -} - -HMM_Mat2 HMM_RotateM2(float angle) -{ - HMM_Mat2 result; - result.Elements[0][0] = cos(angle); - result.Elements[0][1] = sin(angle); - result.Elements[1][0] = -result.Elements[0][1]; - result.Elements[1][1] = result.Elements[0][0]; - - return result; -} - - -HMM_Mat2 HMM_AddM2(HMM_Mat2 Left, HMM_Mat2 Right) { - - HMM_Mat2 Result; - - Result.Elements[0][0] = Left.Elements[0][0] + Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] + Right.Elements[0][1]; - Result.Elements[1][0] = Left.Elements[1][0] + Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] + Right.Elements[1][1]; - - return Result; -} - -HMM_Mat2 HMM_SubM2(HMM_Mat2 Left, HMM_Mat2 Right) { - - HMM_Mat2 Result; - - Result.Elements[0][0] = Left.Elements[0][0] - Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] - Right.Elements[0][1]; - Result.Elements[1][0] = Left.Elements[1][0] - Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] - Right.Elements[1][1]; - - return Result; -} - -HMM_Vec2 HMM_MulM2V2(HMM_Mat2 Matrix, HMM_Vec2 Vector) { - - HMM_Vec2 Result; - - Result.X = Vector.Elements[0] * Matrix.Columns[0].X; - Result.Y = Vector.Elements[0] * Matrix.Columns[0].Y; - - Result.X += Vector.Elements[1] * Matrix.Columns[1].X; - Result.Y += Vector.Elements[1] * Matrix.Columns[1].Y; - - return Result; -} - -HMM_Mat2 HMM_MulM2(HMM_Mat2 Left, HMM_Mat2 Right) { - - HMM_Mat2 Result; - Result.Columns[0] = HMM_MulM2V2(Left, Right.Columns[0]); - Result.Columns[1] = HMM_MulM2V2(Left, Right.Columns[1]); - - return Result; -} - -HMM_Mat2 HMM_MulM2F(HMM_Mat2 Matrix, float Scalar) { - - HMM_Mat2 Result; - - Result.Elements[0][0] = Matrix.Elements[0][0] * Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] * Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] * Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] * Scalar; - - return Result; -} - -HMM_Mat2 HMM_DivM2F(HMM_Mat2 Matrix, float Scalar) { - - HMM_Mat2 Result; - - Result.Elements[0][0] = Matrix.Elements[0][0] / Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] / Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] / Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] / Scalar; - - return Result; -} - -float HMM_DeterminantM2(HMM_Mat2 Matrix) { - return Matrix.Elements[0][0] * Matrix.Elements[1][1] - Matrix.Elements[0][1] * Matrix.Elements[1][0]; -} - -HMM_Mat2 HMM_InvGeneralM2(HMM_Mat2 Matrix) { - - HMM_Mat2 Result; - float InvDeterminant = 1.0f / HMM_DeterminantM2(Matrix); - Result.Elements[0][0] = InvDeterminant * +Matrix.Elements[1][1]; - Result.Elements[1][1] = InvDeterminant * +Matrix.Elements[0][0]; - Result.Elements[0][1] = InvDeterminant * -Matrix.Elements[0][1]; - Result.Elements[1][0] = InvDeterminant * -Matrix.Elements[1][0]; - - return Result; -} - -/* - * 3x3 Matrices - */ - -HMM_Mat3 HMM_M3(void) { - HMM_Mat3 Result = {0}; - return Result; -} - -HMM_Mat3 HMM_M3D(float Diagonal) { - - HMM_Mat3 Result = {0}; - Result.Elements[0][0] = Diagonal; - Result.Elements[1][1] = Diagonal; - Result.Elements[2][2] = Diagonal; - - return Result; -} - -HMM_Mat3 HMM_Translate2D(HMM_Vec2 p) -{ - HMM_Mat3 res = HMM_M3D(1); - res.Columns[2].XY = p; - return res; -} - -HMM_Mat3 HMM_RotateM3(float angle) -{ - HMM_Mat3 r = HMM_M3D(1); - r.Columns[0] = (HMM_Vec3){cos(angle), sin(angle), 0}; - r.Columns[1] = (HMM_Vec3){-sin(angle), cos(angle), 0}; - return r; -} - -HMM_Mat3 HMM_ScaleM3(HMM_Vec2 s) -{ - HMM_Mat3 sm = HMM_M3D(1); - sm.Columns[0].X = s.x; - sm.Columns[1].Y = s.y; - return sm; -} - -HMM_Mat3 HMM_TransposeM3(HMM_Mat3 Matrix) { - - HMM_Mat3 Result = Matrix; - - Result.Elements[0][1] = Matrix.Elements[1][0]; - Result.Elements[0][2] = Matrix.Elements[2][0]; - Result.Elements[1][0] = Matrix.Elements[0][1]; - Result.Elements[1][2] = Matrix.Elements[2][1]; - Result.Elements[2][1] = Matrix.Elements[1][2]; - Result.Elements[2][0] = Matrix.Elements[0][2]; - - return Result; -} - -HMM_Mat3 HMM_AddM3(HMM_Mat3 Left, HMM_Mat3 Right) { - - HMM_Mat3 Result; - - Result.Elements[0][0] = Left.Elements[0][0] + Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] + Right.Elements[0][1]; - Result.Elements[0][2] = Left.Elements[0][2] + Right.Elements[0][2]; - Result.Elements[1][0] = Left.Elements[1][0] + Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] + Right.Elements[1][1]; - Result.Elements[1][2] = Left.Elements[1][2] + Right.Elements[1][2]; - Result.Elements[2][0] = Left.Elements[2][0] + Right.Elements[2][0]; - Result.Elements[2][1] = Left.Elements[2][1] + Right.Elements[2][1]; - Result.Elements[2][2] = Left.Elements[2][2] + Right.Elements[2][2]; - - return Result; -} - -HMM_Mat3 HMM_SubM3(HMM_Mat3 Left, HMM_Mat3 Right) { - - HMM_Mat3 Result; - - Result.Elements[0][0] = Left.Elements[0][0] - Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] - Right.Elements[0][1]; - Result.Elements[0][2] = Left.Elements[0][2] - Right.Elements[0][2]; - Result.Elements[1][0] = Left.Elements[1][0] - Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] - Right.Elements[1][1]; - Result.Elements[1][2] = Left.Elements[1][2] - Right.Elements[1][2]; - Result.Elements[2][0] = Left.Elements[2][0] - Right.Elements[2][0]; - Result.Elements[2][1] = Left.Elements[2][1] - Right.Elements[2][1]; - Result.Elements[2][2] = Left.Elements[2][2] - Right.Elements[2][2]; - - return Result; -} - -HMM_Vec3 HMM_MulM3V3(HMM_Mat3 Matrix, HMM_Vec3 Vector) { - HMM_Vec3 Result; - - Result.X = Vector.Elements[0] * Matrix.Columns[0].X; - Result.Y = Vector.Elements[0] * Matrix.Columns[0].Y; - Result.Z = Vector.Elements[0] * Matrix.Columns[0].Z; - - Result.X += Vector.Elements[1] * Matrix.Columns[1].X; - Result.Y += Vector.Elements[1] * Matrix.Columns[1].Y; - Result.Z += Vector.Elements[1] * Matrix.Columns[1].Z; - - Result.X += Vector.Elements[2] * Matrix.Columns[2].X; - Result.Y += Vector.Elements[2] * Matrix.Columns[2].Y; - Result.Z += Vector.Elements[2] * Matrix.Columns[2].Z; - - return Result; -} - -HMM_Mat3 HMM_MulM3(HMM_Mat3 Left, HMM_Mat3 Right) { - - HMM_Mat3 Result; - Result.Columns[0] = HMM_MulM3V3(Left, Right.Columns[0]); - Result.Columns[1] = HMM_MulM3V3(Left, Right.Columns[1]); - Result.Columns[2] = HMM_MulM3V3(Left, Right.Columns[2]); - - return Result; -} - -/*HMM_Mat3 HMM_VMulM3(int c, ...) -{ - HMM_Mat3 res = HMM_M3D(1); - va_list args; - va_start(args, c); - for (int i = 0; i < c; i++) { - HMM_Mat3 m = va_arg(args, HMM_Mat3); - res = HMM_MulM3(m, res); - } - va_end(args); - return res; -} -*/ -HMM_Mat3 HMM_MulM3F(HMM_Mat3 Matrix, float Scalar) { - - HMM_Mat3 Result; - - Result.Elements[0][0] = Matrix.Elements[0][0] * Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] * Scalar; - Result.Elements[0][2] = Matrix.Elements[0][2] * Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] * Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] * Scalar; - Result.Elements[1][2] = Matrix.Elements[1][2] * Scalar; - Result.Elements[2][0] = Matrix.Elements[2][0] * Scalar; - Result.Elements[2][1] = Matrix.Elements[2][1] * Scalar; - Result.Elements[2][2] = Matrix.Elements[2][2] * Scalar; - - return Result; -} - -HMM_Mat3 HMM_DivM3F(HMM_Mat3 Matrix, float Scalar) { - - HMM_Mat3 Result; - - Result.Elements[0][0] = Matrix.Elements[0][0] / Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] / Scalar; - Result.Elements[0][2] = Matrix.Elements[0][2] / Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] / Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] / Scalar; - Result.Elements[1][2] = Matrix.Elements[1][2] / Scalar; - Result.Elements[2][0] = Matrix.Elements[2][0] / Scalar; - Result.Elements[2][1] = Matrix.Elements[2][1] / Scalar; - Result.Elements[2][2] = Matrix.Elements[2][2] / Scalar; - - return Result; -} - -HMM_Mat2 HMM_ScaleM2(HMM_Vec2 Scale) { - - HMM_Mat2 Result = HMM_M2D(1.0f); - Result.Elements[0][0] = Scale.X; - Result.Elements[1][1] = Scale.Y; - - return Result; -} - -float HMM_DeterminantM3(HMM_Mat3 Matrix) { - - HMM_Mat3 Cross; - Cross.Columns[0] = HMM_Cross(Matrix.Columns[1], Matrix.Columns[2]); - Cross.Columns[1] = HMM_Cross(Matrix.Columns[2], Matrix.Columns[0]); - Cross.Columns[2] = HMM_Cross(Matrix.Columns[0], Matrix.Columns[1]); - - return HMM_DotV3(Cross.Columns[2], Matrix.Columns[2]); -} - -HMM_Mat3 HMM_M2Basis(HMM_Mat2 basis) -{ - HMM_Mat3 m; - m.Columns[0].XY = basis.Columns[0]; - m.Columns[1].XY = basis.Columns[1]; - m.Columns[2].Z = 1; - return m; -} - -HMM_Mat3 HMM_InvGeneralM3(HMM_Mat3 Matrix) { - - HMM_Mat3 Cross; - Cross.Columns[0] = HMM_Cross(Matrix.Columns[1], Matrix.Columns[2]); - Cross.Columns[1] = HMM_Cross(Matrix.Columns[2], Matrix.Columns[0]); - Cross.Columns[2] = HMM_Cross(Matrix.Columns[0], Matrix.Columns[1]); - - float InvDeterminant = 1.0f / HMM_DotV3(Cross.Columns[2], Matrix.Columns[2]); - - HMM_Mat3 Result; - Result.Columns[0] = HMM_MulV3F(Cross.Columns[0], InvDeterminant); - Result.Columns[1] = HMM_MulV3F(Cross.Columns[1], InvDeterminant); - Result.Columns[2] = HMM_MulV3F(Cross.Columns[2], InvDeterminant); - - return HMM_TransposeM3(Result); -} - -/* - * 4x4 Matrices - */ - -HMM_Mat4 HMM_M4(void) { - HMM_Mat4 Result = {0}; - return Result; -} - -HMM_Mat4 HMM_M4D(float Diagonal) { - - HMM_Mat4 Result = {0}; - Result.Elements[0][0] = Diagonal; - Result.Elements[1][1] = Diagonal; - Result.Elements[2][2] = Diagonal; - Result.Elements[3][3] = Diagonal; - - return Result; -} - -HMM_Mat4 HMM_TransposeM4(HMM_Mat4 Matrix) { - - HMM_Mat4 Result = Matrix; -#ifdef HANDMADE_MATH__USE_SSE - _MM_TRANSPOSE4_PS(Result.Columns[0].SSE, Result.Columns[1].SSE, Result.Columns[2].SSE, Result.Columns[3].SSE); -#else - Result.Elements[0][1] = Matrix.Elements[1][0]; - Result.Elements[0][2] = Matrix.Elements[2][0]; - Result.Elements[0][3] = Matrix.Elements[3][0]; - Result.Elements[1][0] = Matrix.Elements[0][1]; - Result.Elements[1][2] = Matrix.Elements[2][1]; - Result.Elements[1][3] = Matrix.Elements[3][1]; - Result.Elements[2][1] = Matrix.Elements[1][2]; - Result.Elements[2][0] = Matrix.Elements[0][2]; - Result.Elements[2][3] = Matrix.Elements[3][2]; - Result.Elements[3][1] = Matrix.Elements[1][3]; - Result.Elements[3][2] = Matrix.Elements[2][3]; - Result.Elements[3][0] = Matrix.Elements[0][3]; -#endif - - return Result; -} - -HMM_Mat4 HMM_AddM4(HMM_Mat4 Left, HMM_Mat4 Right) { - - HMM_Mat4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.Columns[0].SSE = _mm_add_ps(Left.Columns[0].SSE, Right.Columns[0].SSE); - Result.Columns[1].SSE = _mm_add_ps(Left.Columns[1].SSE, Right.Columns[1].SSE); - Result.Columns[2].SSE = _mm_add_ps(Left.Columns[2].SSE, Right.Columns[2].SSE); - Result.Columns[3].SSE = _mm_add_ps(Left.Columns[3].SSE, Right.Columns[3].SSE); -#else - Result.Elements[0][0] = Left.Elements[0][0] + Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] + Right.Elements[0][1]; - Result.Elements[0][2] = Left.Elements[0][2] + Right.Elements[0][2]; - Result.Elements[0][3] = Left.Elements[0][3] + Right.Elements[0][3]; - Result.Elements[1][0] = Left.Elements[1][0] + Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] + Right.Elements[1][1]; - Result.Elements[1][2] = Left.Elements[1][2] + Right.Elements[1][2]; - Result.Elements[1][3] = Left.Elements[1][3] + Right.Elements[1][3]; - Result.Elements[2][0] = Left.Elements[2][0] + Right.Elements[2][0]; - Result.Elements[2][1] = Left.Elements[2][1] + Right.Elements[2][1]; - Result.Elements[2][2] = Left.Elements[2][2] + Right.Elements[2][2]; - Result.Elements[2][3] = Left.Elements[2][3] + Right.Elements[2][3]; - Result.Elements[3][0] = Left.Elements[3][0] + Right.Elements[3][0]; - Result.Elements[3][1] = Left.Elements[3][1] + Right.Elements[3][1]; - Result.Elements[3][2] = Left.Elements[3][2] + Right.Elements[3][2]; - Result.Elements[3][3] = Left.Elements[3][3] + Right.Elements[3][3]; -#endif - - return Result; -} - -HMM_Mat4 HMM_SubM4(HMM_Mat4 Left, HMM_Mat4 Right) { - - HMM_Mat4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.Columns[0].SSE = _mm_sub_ps(Left.Columns[0].SSE, Right.Columns[0].SSE); - Result.Columns[1].SSE = _mm_sub_ps(Left.Columns[1].SSE, Right.Columns[1].SSE); - Result.Columns[2].SSE = _mm_sub_ps(Left.Columns[2].SSE, Right.Columns[2].SSE); - Result.Columns[3].SSE = _mm_sub_ps(Left.Columns[3].SSE, Right.Columns[3].SSE); -#else - Result.Elements[0][0] = Left.Elements[0][0] - Right.Elements[0][0]; - Result.Elements[0][1] = Left.Elements[0][1] - Right.Elements[0][1]; - Result.Elements[0][2] = Left.Elements[0][2] - Right.Elements[0][2]; - Result.Elements[0][3] = Left.Elements[0][3] - Right.Elements[0][3]; - Result.Elements[1][0] = Left.Elements[1][0] - Right.Elements[1][0]; - Result.Elements[1][1] = Left.Elements[1][1] - Right.Elements[1][1]; - Result.Elements[1][2] = Left.Elements[1][2] - Right.Elements[1][2]; - Result.Elements[1][3] = Left.Elements[1][3] - Right.Elements[1][3]; - Result.Elements[2][0] = Left.Elements[2][0] - Right.Elements[2][0]; - Result.Elements[2][1] = Left.Elements[2][1] - Right.Elements[2][1]; - Result.Elements[2][2] = Left.Elements[2][2] - Right.Elements[2][2]; - Result.Elements[2][3] = Left.Elements[2][3] - Right.Elements[2][3]; - Result.Elements[3][0] = Left.Elements[3][0] - Right.Elements[3][0]; - Result.Elements[3][1] = Left.Elements[3][1] - Right.Elements[3][1]; - Result.Elements[3][2] = Left.Elements[3][2] - Right.Elements[3][2]; - Result.Elements[3][3] = Left.Elements[3][3] - Right.Elements[3][3]; -#endif - - return Result; -} - -HMM_Mat4 HMM_MulM4(HMM_Mat4 Left, HMM_Mat4 Right) { - - HMM_Mat4 Result; - Result.Columns[0] = HMM_LinearCombineV4M4(Right.Columns[0], Left); - Result.Columns[1] = HMM_LinearCombineV4M4(Right.Columns[1], Left); - Result.Columns[2] = HMM_LinearCombineV4M4(Right.Columns[2], Left); - Result.Columns[3] = HMM_LinearCombineV4M4(Right.Columns[3], Left); - - return Result; -} - -HMM_Mat4 HMM_MulM4_P(HMM_Mat4 *Left, HMM_Mat4 *Right) -{ - HMM_Mat4 Result; - Result.Columns[0] = HMM_LinearCombineV4M4_P(&Right->Columns[0], Left); - Result.Columns[1] = HMM_LinearCombineV4M4_P(&Right->Columns[1], Left); - Result.Columns[2] = HMM_LinearCombineV4M4_P(&Right->Columns[2], Left); - Result.Columns[3] = HMM_LinearCombineV4M4_P(&Right->Columns[3], Left); - - return Result; -} - -HMM_Mat4 HMM_MulM4F(HMM_Mat4 Matrix, float Scalar) { - - HMM_Mat4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEScalar = _mm_set1_ps(Scalar); - Result.Columns[0].SSE = _mm_mul_ps(Matrix.Columns[0].SSE, SSEScalar); - Result.Columns[1].SSE = _mm_mul_ps(Matrix.Columns[1].SSE, SSEScalar); - Result.Columns[2].SSE = _mm_mul_ps(Matrix.Columns[2].SSE, SSEScalar); - Result.Columns[3].SSE = _mm_mul_ps(Matrix.Columns[3].SSE, SSEScalar); -#else - Result.Elements[0][0] = Matrix.Elements[0][0] * Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] * Scalar; - Result.Elements[0][2] = Matrix.Elements[0][2] * Scalar; - Result.Elements[0][3] = Matrix.Elements[0][3] * Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] * Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] * Scalar; - Result.Elements[1][2] = Matrix.Elements[1][2] * Scalar; - Result.Elements[1][3] = Matrix.Elements[1][3] * Scalar; - Result.Elements[2][0] = Matrix.Elements[2][0] * Scalar; - Result.Elements[2][1] = Matrix.Elements[2][1] * Scalar; - Result.Elements[2][2] = Matrix.Elements[2][2] * Scalar; - Result.Elements[2][3] = Matrix.Elements[2][3] * Scalar; - Result.Elements[3][0] = Matrix.Elements[3][0] * Scalar; - Result.Elements[3][1] = Matrix.Elements[3][1] * Scalar; - Result.Elements[3][2] = Matrix.Elements[3][2] * Scalar; - Result.Elements[3][3] = Matrix.Elements[3][3] * Scalar; -#endif - - return Result; -} - -HMM_Vec4 HMM_MulM4V4_P(HMM_Mat4 *Matrix, HMM_Vec4 *Vector) -{ - return HMM_LinearCombineV4M4_P(Vector, Matrix); -} - -HMM_Vec4 HMM_MulM4V4(HMM_Mat4 Matrix, HMM_Vec4 Vector) { - return HMM_LinearCombineV4M4(Vector, Matrix); -} - -HMM_Mat4 HMM_DivM4F(HMM_Mat4 Matrix, float Scalar) { - - HMM_Mat4 Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEScalar = _mm_set1_ps(Scalar); - Result.Columns[0].SSE = _mm_div_ps(Matrix.Columns[0].SSE, SSEScalar); - Result.Columns[1].SSE = _mm_div_ps(Matrix.Columns[1].SSE, SSEScalar); - Result.Columns[2].SSE = _mm_div_ps(Matrix.Columns[2].SSE, SSEScalar); - Result.Columns[3].SSE = _mm_div_ps(Matrix.Columns[3].SSE, SSEScalar); -#else - Result.Elements[0][0] = Matrix.Elements[0][0] / Scalar; - Result.Elements[0][1] = Matrix.Elements[0][1] / Scalar; - Result.Elements[0][2] = Matrix.Elements[0][2] / Scalar; - Result.Elements[0][3] = Matrix.Elements[0][3] / Scalar; - Result.Elements[1][0] = Matrix.Elements[1][0] / Scalar; - Result.Elements[1][1] = Matrix.Elements[1][1] / Scalar; - Result.Elements[1][2] = Matrix.Elements[1][2] / Scalar; - Result.Elements[1][3] = Matrix.Elements[1][3] / Scalar; - Result.Elements[2][0] = Matrix.Elements[2][0] / Scalar; - Result.Elements[2][1] = Matrix.Elements[2][1] / Scalar; - Result.Elements[2][2] = Matrix.Elements[2][2] / Scalar; - Result.Elements[2][3] = Matrix.Elements[2][3] / Scalar; - Result.Elements[3][0] = Matrix.Elements[3][0] / Scalar; - Result.Elements[3][1] = Matrix.Elements[3][1] / Scalar; - Result.Elements[3][2] = Matrix.Elements[3][2] / Scalar; - Result.Elements[3][3] = Matrix.Elements[3][3] / Scalar; -#endif - - return Result; -} - -float HMM_DeterminantM4(HMM_Mat4 Matrix) { - - HMM_Vec3 C01 = HMM_Cross(Matrix.Columns[0].XYZ, Matrix.Columns[1].XYZ); - HMM_Vec3 C23 = HMM_Cross(Matrix.Columns[2].XYZ, Matrix.Columns[3].XYZ); - HMM_Vec3 B10 = HMM_SubV3(HMM_MulV3F(Matrix.Columns[0].XYZ, Matrix.Columns[1].W), HMM_MulV3F(Matrix.Columns[1].XYZ, Matrix.Columns[0].W)); - HMM_Vec3 B32 = HMM_SubV3(HMM_MulV3F(Matrix.Columns[2].XYZ, Matrix.Columns[3].W), HMM_MulV3F(Matrix.Columns[3].XYZ, Matrix.Columns[2].W)); - - return HMM_DotV3(C01, B32) + HMM_DotV3(C23, B10); -} - -// Returns a general-purpose inverse of an HMM_Mat4. Note that special-purpose inverses of many transformations -// are available and will be more efficient. -HMM_Mat4 HMM_InvGeneralM4(HMM_Mat4 Matrix) { - - HMM_Vec3 C01 = HMM_Cross(Matrix.Columns[0].XYZ, Matrix.Columns[1].XYZ); - HMM_Vec3 C23 = HMM_Cross(Matrix.Columns[2].XYZ, Matrix.Columns[3].XYZ); - HMM_Vec3 B10 = HMM_SubV3(HMM_MulV3F(Matrix.Columns[0].XYZ, Matrix.Columns[1].W), HMM_MulV3F(Matrix.Columns[1].XYZ, Matrix.Columns[0].W)); - HMM_Vec3 B32 = HMM_SubV3(HMM_MulV3F(Matrix.Columns[2].XYZ, Matrix.Columns[3].W), HMM_MulV3F(Matrix.Columns[3].XYZ, Matrix.Columns[2].W)); - - float InvDeterminant = 1.0f / (HMM_DotV3(C01, B32) + HMM_DotV3(C23, B10)); - C01 = HMM_MulV3F(C01, InvDeterminant); - C23 = HMM_MulV3F(C23, InvDeterminant); - B10 = HMM_MulV3F(B10, InvDeterminant); - B32 = HMM_MulV3F(B32, InvDeterminant); - - HMM_Mat4 Result; - Result.Columns[0] = HMM_V4V(HMM_AddV3(HMM_Cross(Matrix.Columns[1].XYZ, B32), HMM_MulV3F(C23, Matrix.Columns[1].W)), -HMM_DotV3(Matrix.Columns[1].XYZ, C23)); - Result.Columns[1] = HMM_V4V(HMM_SubV3(HMM_Cross(B32, Matrix.Columns[0].XYZ), HMM_MulV3F(C23, Matrix.Columns[0].W)), +HMM_DotV3(Matrix.Columns[0].XYZ, C23)); - Result.Columns[2] = HMM_V4V(HMM_AddV3(HMM_Cross(Matrix.Columns[3].XYZ, B10), HMM_MulV3F(C01, Matrix.Columns[3].W)), -HMM_DotV3(Matrix.Columns[3].XYZ, C01)); - Result.Columns[3] = HMM_V4V(HMM_SubV3(HMM_Cross(B10, Matrix.Columns[2].XYZ), HMM_MulV3F(C01, Matrix.Columns[2].W)), +HMM_DotV3(Matrix.Columns[2].XYZ, C01)); - - return HMM_TransposeM4(Result); -} - -/* - * Common graphics transformations - */ - -// Produces a right-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_RH_NO(float Left, float Right, float Bottom, float Top, float Near, float Far) { - - HMM_Mat4 Result = {0}; - - Result.Elements[0][0] = 2.0f / (Right - Left); - Result.Elements[1][1] = 2.0f / (Top - Bottom); - Result.Elements[2][2] = 2.0f / (Near - Far); - Result.Elements[3][3] = 1.0f; - - Result.Elements[3][0] = (Left + Right) / (Left - Right); - Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top); - Result.Elements[3][2] = (Near + Far) / (Near - Far); - - return Result; -} - -// Produces a right-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_RH_ZO(float Left, float Right, float Bottom, float Top, float Near, float Far) { - - HMM_Mat4 Result = {0}; - - Result.Elements[0][0] = 2.0f / (Right - Left); - Result.Elements[1][1] = 2.0f / (Top - Bottom); - Result.Elements[2][2] = 1.0f / (Near - Far); - Result.Elements[3][3] = 1.0f; - - Result.Elements[3][0] = (Left + Right) / (Left - Right); - Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top); - Result.Elements[3][2] = (Near) / (Near - Far); - - return Result; -} - -// Produces a left-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_LH_NO(float Left, float Right, float Bottom, float Top, float Near, float Far) { - - HMM_Mat4 Result = HMM_Orthographic_RH_NO(Left, Right, Bottom, Top, Near, Far); - Result.Elements[2][2] = -Result.Elements[2][2]; - - return Result; -} - -// Produces a left-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_LH_ZO(float Left, float Right, float Bottom, float Top, float Near, float Far) { - - HMM_Mat4 Result = HMM_Orthographic_RH_ZO(Left, Right, Bottom, Top, Near, Far); - Result.Elements[2][2] = -Result.Elements[2][2]; - - return Result; -} - -// Returns an inverse for the given orthographic projection matrix. Works for all orthographic -// projection matrices, regardless of handedness or NDC convention. -HMM_Mat4 HMM_InvOrthographic(HMM_Mat4 OrthoMatrix) { - - HMM_Mat4 Result = {0}; - Result.Elements[0][0] = 1.0f / OrthoMatrix.Elements[0][0]; - Result.Elements[1][1] = 1.0f / OrthoMatrix.Elements[1][1]; - Result.Elements[2][2] = 1.0f / OrthoMatrix.Elements[2][2]; - Result.Elements[3][3] = 1.0f; - - Result.Elements[3][0] = -OrthoMatrix.Elements[3][0] * Result.Elements[0][0]; - Result.Elements[3][1] = -OrthoMatrix.Elements[3][1] * Result.Elements[1][1]; - Result.Elements[3][2] = -OrthoMatrix.Elements[3][2] * Result.Elements[2][2]; - - return Result; -} - -HMM_Mat4 HMM_Orthographic_DX(float l, float r, float b, float t, float near, float far) -{ - return HMM_Orthographic_LH_ZO(l,r,b,t,near,far); -} - -HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far) -{ - return HMM_Orthographic_LH_NO(l,r,b,t,near,far); -} - -HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far) -{ - HMM_Mat4 adjust = {0}; - adjust.e[0][0] = 1; - adjust.e[1][1] = 1; - adjust.e[2][2] = 0.5; - adjust.e[3][2] = 0.5; - adjust.e[3][3] = 1; - HMM_Mat4 opengl = HMM_Orthographic_LH_ZO(l, r, b, t, near, far); - return HMM_MulM4(opengl, adjust); -} - -HMM_Mat4 HMM_Perspective_Metal(float FOV, float AspectRatio, float Near, float Far) -{ - HMM_Mat4 adjust = {0}; - adjust.e[0][0] = 1; - adjust.e[1][1] = 1; - adjust.e[2][2] = 0.5; - adjust.e[3][2] = 0.5; - adjust.e[3][3] = 1; - HMM_Mat4 opengl = HMM_Perspective_LH_NO(FOV, AspectRatio, Near, Far); - return HMM_MulM4(opengl,adjust); - -} - -HMM_Mat4 HMM_Perspective_RH_NO(float FOV, float AspectRatio, float Near, float Far) { - - HMM_Mat4 Result = {0}; - - // See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml - - float Cotangent = 1.0f / HMM_TanF(FOV / 2.0f); - Result.Elements[0][0] = Cotangent / AspectRatio; - Result.Elements[1][1] = Cotangent; - Result.Elements[2][3] = -1.0f; - - Result.Elements[2][2] = (Near + Far) / (Near - Far); - Result.Elements[3][2] = (2.0f * Near * Far) / (Near - Far); - - return Result; -} - -HMM_Mat4 HMM_Perspective_RH_ZO(float FOV, float AspectRatio, float Near, float Far) { - - HMM_Mat4 Result = {0}; - - // See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml - - float Cotangent = 1.0f / HMM_TanF(FOV / 2.0f); - Result.Elements[0][0] = Cotangent / AspectRatio; - Result.Elements[1][1] = Cotangent; - Result.Elements[2][3] = -1.0f; - - Result.Elements[2][2] = (Far) / (Near - Far); - Result.Elements[3][2] = (Near * Far) / (Near - Far); - - return Result; -} - -HMM_Mat4 HMM_Perspective_LH_NO(float FOV, float AspectRatio, float Near, float Far) { - - HMM_Mat4 Result = HMM_Perspective_RH_NO(FOV, AspectRatio, Near, Far); - Result.Elements[2][2] = -Result.Elements[2][2]; - Result.Elements[2][3] = -Result.Elements[2][3]; - - return Result; -} - -HMM_Mat4 HMM_Perspective_LH_ZO(float FOV, float AspectRatio, float Near, float Far) { - - HMM_Mat4 Result = HMM_Perspective_RH_ZO(FOV, AspectRatio, Near, Far); - Result.Elements[2][2] = -Result.Elements[2][2]; - Result.Elements[2][3] = -Result.Elements[2][3]; - - return Result; -} - -HMM_Mat4 HMM_InvPerspective_RH(HMM_Mat4 PerspectiveMatrix) { - - HMM_Mat4 Result = {0}; - Result.Elements[0][0] = 1.0f / PerspectiveMatrix.Elements[0][0]; - Result.Elements[1][1] = 1.0f / PerspectiveMatrix.Elements[1][1]; - Result.Elements[2][2] = 0.0f; - - Result.Elements[2][3] = 1.0f / PerspectiveMatrix.Elements[3][2]; - Result.Elements[3][3] = PerspectiveMatrix.Elements[2][2] * Result.Elements[2][3]; - Result.Elements[3][2] = PerspectiveMatrix.Elements[2][3]; - - return Result; -} - -HMM_Mat4 HMM_InvPerspective_LH(HMM_Mat4 PerspectiveMatrix) { - - HMM_Mat4 Result = {0}; - Result.Elements[0][0] = 1.0f / PerspectiveMatrix.Elements[0][0]; - Result.Elements[1][1] = 1.0f / PerspectiveMatrix.Elements[1][1]; - Result.Elements[2][2] = 0.0f; - - Result.Elements[2][3] = 1.0f / PerspectiveMatrix.Elements[3][2]; - Result.Elements[3][3] = PerspectiveMatrix.Elements[2][2] * -Result.Elements[2][3]; - Result.Elements[3][2] = PerspectiveMatrix.Elements[2][3]; - - return Result; -} - -HMM_Mat4 HMM_Translate(HMM_Vec3 Translation) { - - HMM_Mat4 Result = HMM_M4D(1.0f); - Result.Elements[3][0] = Translation.X; - Result.Elements[3][1] = Translation.Y; - Result.Elements[3][2] = Translation.Z; - - return Result; -} - -HMM_Mat4 HMM_InvTranslate(HMM_Mat4 TranslationMatrix) { - - HMM_Mat4 Result = TranslationMatrix; - Result.Elements[3][0] = -Result.Elements[3][0]; - Result.Elements[3][1] = -Result.Elements[3][1]; - Result.Elements[3][2] = -Result.Elements[3][2]; - - return Result; -} - -HMM_Mat4 HMM_Rotate_RH(float Angle, HMM_Vec3 Axis) { - - HMM_Mat4 Result = HMM_M4D(1.0f); - - Axis = HMM_NormV3(Axis); - - float SinTheta = HMM_SinF(Angle); - float CosTheta = HMM_CosF(Angle); - float CosValue = 1.0f - CosTheta; - - Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta; - Result.Elements[0][1] = (Axis.X * Axis.Y * CosValue) + (Axis.Z * SinTheta); - Result.Elements[0][2] = (Axis.X * Axis.Z * CosValue) - (Axis.Y * SinTheta); - - Result.Elements[1][0] = (Axis.Y * Axis.X * CosValue) - (Axis.Z * SinTheta); - Result.Elements[1][1] = (Axis.Y * Axis.Y * CosValue) + CosTheta; - Result.Elements[1][2] = (Axis.Y * Axis.Z * CosValue) + (Axis.X * SinTheta); - - Result.Elements[2][0] = (Axis.Z * Axis.X * CosValue) + (Axis.Y * SinTheta); - Result.Elements[2][1] = (Axis.Z * Axis.Y * CosValue) - (Axis.X * SinTheta); - Result.Elements[2][2] = (Axis.Z * Axis.Z * CosValue) + CosTheta; - - return Result; -} - -HMM_Mat4 HMM_Rotate_LH(float Angle, HMM_Vec3 Axis) { - /* NOTE(lcf): Matrix will be inverse/transpose of RH. */ - return HMM_Rotate_RH(-Angle, Axis); -} - -HMM_Mat4 HMM_InvRotate(HMM_Mat4 RotationMatrix) { - return HMM_TransposeM4(RotationMatrix); -} - -HMM_Mat4 HMM_Scale(HMM_Vec3 Scale) { - - HMM_Mat4 Result = HMM_M4D(1.0f); - Result.Elements[0][0] = Scale.X; - Result.Elements[1][1] = Scale.Y; - Result.Elements[2][2] = Scale.Z; - - return Result; -} - -HMM_Mat4 HMM_InvScale(HMM_Mat4 ScaleMatrix) { - - HMM_Mat4 Result = ScaleMatrix; - Result.Elements[0][0] = 1.0f / Result.Elements[0][0]; - Result.Elements[1][1] = 1.0f / Result.Elements[1][1]; - Result.Elements[2][2] = 1.0f / Result.Elements[2][2]; - - return Result; -} - -HMM_Mat4 _HMM_LookAt(HMM_Vec3 F, HMM_Vec3 S, HMM_Vec3 U, HMM_Vec3 Eye) { - HMM_Mat4 Result; - - Result.Elements[0][0] = S.X; - Result.Elements[0][1] = U.X; - Result.Elements[0][2] = -F.X; - Result.Elements[0][3] = 0.0f; - - Result.Elements[1][0] = S.Y; - Result.Elements[1][1] = U.Y; - Result.Elements[1][2] = -F.Y; - Result.Elements[1][3] = 0.0f; - - Result.Elements[2][0] = S.Z; - Result.Elements[2][1] = U.Z; - Result.Elements[2][2] = -F.Z; - Result.Elements[2][3] = 0.0f; - - Result.Elements[3][0] = -HMM_DotV3(S, Eye); - Result.Elements[3][1] = -HMM_DotV3(U, Eye); - Result.Elements[3][2] = HMM_DotV3(F, Eye); - Result.Elements[3][3] = 1.0f; - - return Result; -} - -HMM_Mat4 HMM_LookAt_RH(HMM_Vec3 Eye, HMM_Vec3 Center, HMM_Vec3 Up) { - - HMM_Vec3 F = HMM_NormV3(HMM_SubV3(Center, Eye)); - HMM_Vec3 S = HMM_NormV3(HMM_Cross(F, Up)); - HMM_Vec3 U = HMM_Cross(S, F); - - return _HMM_LookAt(F, S, U, Eye); -} - -HMM_Mat4 HMM_LookAt_LH(HMM_Vec3 Eye, HMM_Vec3 Center, HMM_Vec3 Up) { - - HMM_Vec3 F = HMM_NormV3(HMM_SubV3(Eye, Center)); - HMM_Vec3 S = HMM_NormV3(HMM_Cross(F, Up)); - HMM_Vec3 U = HMM_Cross(S, F); - - return _HMM_LookAt(F, S, U, Eye); -} - -HMM_Mat4 HMM_InvLookAt(HMM_Mat4 Matrix) { - HMM_Mat4 Result; - - HMM_Mat3 Rotation = {0}; - Rotation.Columns[0] = Matrix.Columns[0].XYZ; - Rotation.Columns[1] = Matrix.Columns[1].XYZ; - Rotation.Columns[2] = Matrix.Columns[2].XYZ; - Rotation = HMM_TransposeM3(Rotation); - - Result.Columns[0] = HMM_V4V(Rotation.Columns[0], 0.0f); - Result.Columns[1] = HMM_V4V(Rotation.Columns[1], 0.0f); - Result.Columns[2] = HMM_V4V(Rotation.Columns[2], 0.0f); - Result.Columns[3] = HMM_MulV4F(Matrix.Columns[3], -1.0f); - Result.Elements[3][0] = -1.0f * Matrix.Elements[3][0] / - (Rotation.Elements[0][0] + Rotation.Elements[0][1] + Rotation.Elements[0][2]); - Result.Elements[3][1] = -1.0f * Matrix.Elements[3][1] / - (Rotation.Elements[1][0] + Rotation.Elements[1][1] + Rotation.Elements[1][2]); - Result.Elements[3][2] = -1.0f * Matrix.Elements[3][2] / - (Rotation.Elements[2][0] + Rotation.Elements[2][1] + Rotation.Elements[2][2]); - Result.Elements[3][3] = 1.0f; - - return Result; -} - -/* - * Quaternion operations - */ - -HMM_Vec3 HMM_QVRot(HMM_Vec3 v, HMM_Quat q) -{ - HMM_Vec3 t = HMM_MulV3F(HMM_Cross(q.XYZ, v), 2); - HMM_Vec3 r = HMM_AddV3(v, HMM_MulV3F(t, q.W)); - r = HMM_AddV3(r, HMM_Cross(q.XYZ, t)); - return r; -} - -HMM_Quat HMM_Q(float X, float Y, float Z, float W) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_setr_ps(X, Y, Z, W); -#else - Result.X = X; - Result.Y = Y; - Result.Z = Z; - Result.W = W; -#endif - - return Result; -} - -HMM_Quat HMM_QV4(HMM_Vec4 Vector) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = Vector.SSE; -#else - Result.X = Vector.X; - Result.Y = Vector.Y; - Result.Z = Vector.Z; - Result.W = Vector.W; -#endif - - return Result; -} - -HMM_Quat HMM_AddQ(HMM_Quat Left, HMM_Quat Right) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_add_ps(Left.SSE, Right.SSE); -#else - - Result.X = Left.X + Right.X; - Result.Y = Left.Y + Right.Y; - Result.Z = Left.Z + Right.Z; - Result.W = Left.W + Right.W; -#endif - - return Result; -} - -HMM_Quat HMM_SubQ(HMM_Quat Left, HMM_Quat Right) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - Result.SSE = _mm_sub_ps(Left.SSE, Right.SSE); -#else - Result.X = Left.X - Right.X; - Result.Y = Left.Y - Right.Y; - Result.Z = Left.Z - Right.Z; - Result.W = Left.W - Right.W; -#endif - - return Result; -} - -HMM_Quat HMM_MulQ(HMM_Quat Left, HMM_Quat Right) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(0, 0, 0, 0)), _mm_setr_ps(0.f, -0.f, 0.f, -0.f)); - __m128 SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(0, 1, 2, 3)); - __m128 SSEResultThree = _mm_mul_ps(SSEResultTwo, SSEResultOne); - - SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(1, 1, 1, 1)), _mm_setr_ps(0.f, 0.f, -0.f, -0.f)); - SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(1, 0, 3, 2)); - SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); - - SSEResultOne = _mm_xor_ps(_mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(2, 2, 2, 2)), _mm_setr_ps(-0.f, 0.f, 0.f, -0.f)); - SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultThree = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); - - SSEResultOne = _mm_shuffle_ps(Left.SSE, Left.SSE, _MM_SHUFFLE(3, 3, 3, 3)); - SSEResultTwo = _mm_shuffle_ps(Right.SSE, Right.SSE, _MM_SHUFFLE(3, 2, 1, 0)); - Result.SSE = _mm_add_ps(SSEResultThree, _mm_mul_ps(SSEResultTwo, SSEResultOne)); -#else - Result.X = Right.Elements[3] * +Left.Elements[0]; - Result.Y = Right.Elements[2] * -Left.Elements[0]; - Result.Z = Right.Elements[1] * +Left.Elements[0]; - Result.W = Right.Elements[0] * -Left.Elements[0]; - - Result.X += Right.Elements[2] * +Left.Elements[1]; - Result.Y += Right.Elements[3] * +Left.Elements[1]; - Result.Z += Right.Elements[0] * -Left.Elements[1]; - Result.W += Right.Elements[1] * -Left.Elements[1]; - - Result.X += Right.Elements[1] * -Left.Elements[2]; - Result.Y += Right.Elements[0] * +Left.Elements[2]; - Result.Z += Right.Elements[3] * +Left.Elements[2]; - Result.W += Right.Elements[2] * -Left.Elements[2]; - - Result.X += Right.Elements[0] * +Left.Elements[3]; - Result.Y += Right.Elements[1] * +Left.Elements[3]; - Result.Z += Right.Elements[2] * +Left.Elements[3]; - Result.W += Right.Elements[3] * +Left.Elements[3]; -#endif - - return Result; -} - -HMM_Quat HMM_MulQF(HMM_Quat Left, float Multiplicative) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Multiplicative); - Result.SSE = _mm_mul_ps(Left.SSE, Scalar); -#else - Result.X = Left.X * Multiplicative; - Result.Y = Left.Y * Multiplicative; - Result.Z = Left.Z * Multiplicative; - Result.W = Left.W * Multiplicative; -#endif - - return Result; -} - -HMM_Quat HMM_DivQF(HMM_Quat Left, float Divnd) { - - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 Scalar = _mm_set1_ps(Divnd); - Result.SSE = _mm_div_ps(Left.SSE, Scalar); -#else - Result.X = Left.X / Divnd; - Result.Y = Left.Y / Divnd; - Result.Z = Left.Z / Divnd; - Result.W = Left.W / Divnd; -#endif - - return Result; -} - -float HMM_DotQ(HMM_Quat Left, HMM_Quat Right) { - - float Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSEResultOne = _mm_mul_ps(Left.SSE, Right.SSE); - __m128 SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(2, 3, 0, 1)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - SSEResultTwo = _mm_shuffle_ps(SSEResultOne, SSEResultOne, _MM_SHUFFLE(0, 1, 2, 3)); - SSEResultOne = _mm_add_ps(SSEResultOne, SSEResultTwo); - _mm_store_ss(&Result, SSEResultOne); -#else - Result = ((Left.X * Right.X) + (Left.Z * Right.Z)) + ((Left.Y * Right.Y) + (Left.W * Right.W)); -#endif - - return Result; -} - -HMM_Quat HMM_InvQ(HMM_Quat Left) { - - HMM_Quat Result; - Result.X = -Left.X; - Result.Y = -Left.Y; - Result.Z = -Left.Z; - Result.W = Left.W; - - return HMM_DivQF(Result, (HMM_DotQ(Left, Left))); -} - -HMM_Quat HMM_NormQ(HMM_Quat Quat) { - - /* NOTE(lcf): Take advantage of SSE implementation in HMM_NormV4 */ - HMM_Vec4 Vec = {Quat.X, Quat.Y, Quat.Z, Quat.W}; - Vec = HMM_NormV4(Vec); - HMM_Quat Result = {Vec.X, Vec.Y, Vec.Z, Vec.W}; - - return Result; -} - -HMM_Quat _HMM_MixQ(HMM_Quat Left, float MixLeft, HMM_Quat Right, float MixRight) { - HMM_Quat Result; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 ScalarLeft = _mm_set1_ps(MixLeft); - __m128 ScalarRight = _mm_set1_ps(MixRight); - __m128 SSEResultOne = _mm_mul_ps(Left.SSE, ScalarLeft); - __m128 SSEResultTwo = _mm_mul_ps(Right.SSE, ScalarRight); - Result.SSE = _mm_add_ps(SSEResultOne, SSEResultTwo); -#else - Result.X = Left.X * MixLeft + Right.X * MixRight; - Result.Y = Left.Y * MixLeft + Right.Y * MixRight; - Result.Z = Left.Z * MixLeft + Right.Z * MixRight; - Result.W = Left.W * MixLeft + Right.W * MixRight; -#endif - - return Result; -} - -HMM_Quat HMM_NLerp(HMM_Quat Left, float Time, HMM_Quat Right) { - - HMM_Quat Result = _HMM_MixQ(Left, 1.0f - Time, Right, Time); - Result = HMM_NormQ(Result); - - return Result; -} - -HMM_Quat HMM_SLerp(HMM_Quat Left, float Time, HMM_Quat Right) { - - HMM_Quat Result; - - float Cos_Theta = HMM_DotQ(Left, Right); - - if (Cos_Theta < 0.0f) { /* NOTE(lcf): Take shortest path on Hyper-sphere */ - Cos_Theta = -Cos_Theta; - Right = HMM_Q(-Right.X, -Right.Y, -Right.Z, -Right.W); - } - - /* NOTE(lcf): Use Normalized Linear interpolation when vectors are roughly not L.I. */ - if (Cos_Theta > 0.9995f) { - Result = HMM_NLerp(Left, Time, Right); - } else { - float Angle = HMM_ACosF(Cos_Theta); - float MixLeft = HMM_SinF((1.0f - Time) * Angle); - float MixRight = HMM_SinF(Time * Angle); - - Result = _HMM_MixQ(Left, MixLeft, Right, MixRight); - Result = HMM_NormQ(Result); - } - - return Result; -} - -HMM_Mat4 HMM_QToM4(HMM_Quat Left) { - - HMM_Mat4 Result; - - HMM_Quat NormalizedQ = HMM_NormQ(Left); - - float XX, YY, ZZ, - XY, XZ, YZ, - WX, WY, WZ; - - XX = NormalizedQ.X * NormalizedQ.X; - YY = NormalizedQ.Y * NormalizedQ.Y; - ZZ = NormalizedQ.Z * NormalizedQ.Z; - XY = NormalizedQ.X * NormalizedQ.Y; - XZ = NormalizedQ.X * NormalizedQ.Z; - YZ = NormalizedQ.Y * NormalizedQ.Z; - WX = NormalizedQ.W * NormalizedQ.X; - WY = NormalizedQ.W * NormalizedQ.Y; - WZ = NormalizedQ.W * NormalizedQ.Z; - - Result.Elements[0][0] = 1.0f - 2.0f * (YY + ZZ); - Result.Elements[0][1] = 2.0f * (XY + WZ); - Result.Elements[0][2] = 2.0f * (XZ - WY); - Result.Elements[0][3] = 0.0f; - - Result.Elements[1][0] = 2.0f * (XY - WZ); - Result.Elements[1][1] = 1.0f - 2.0f * (XX + ZZ); - Result.Elements[1][2] = 2.0f * (YZ + WX); - Result.Elements[1][3] = 0.0f; - - Result.Elements[2][0] = 2.0f * (XZ + WY); - Result.Elements[2][1] = 2.0f * (YZ - WX); - Result.Elements[2][2] = 1.0f - 2.0f * (XX + YY); - Result.Elements[2][3] = 0.0f; - - Result.Elements[3][0] = 0.0f; - Result.Elements[3][1] = 0.0f; - Result.Elements[3][2] = 0.0f; - Result.Elements[3][3] = 1.0f; - - return Result; -} - -// this is right handed -HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s) -{ - HMM_Mat4 l; - float *lm = (float*)&l; - - lm[0] = (1 - 2 * q.y*q.y - 2 * q.z*q.z) * s.x; - lm[1] = (2 * q.x*q.y + 2 * q.z*q.w) * s.x; - lm[2] = (2 * q.x*q.z - 2 * q.y*q.w) * s.x; - lm[3] = 0.f; - - lm[4] = (2 * q.x*q.y - 2 * q.z*q.w) * s.y; - lm[5] = (1 - 2 * q.x*q.x - 2 * q.z*q.z) * s.y; - lm[6] = (2 * q.y*q.z + 2 * q.x*q.w) * s.y; - lm[7] = 0.f; - - lm[8] = (2 * q.x*q.z + 2 * q.y*q.w) * s.z; - lm[9] = (2 * q.y*q.z - 2 * q.x*q.w) * s.z; - lm[10] = (1 - 2 * q.x*q.x - 2 * q.y*q.y) * s.z; - lm[11] = 0.f; - - lm[12] = t.x; - lm[13] = t.y; - lm[14] = t.z; - lm[15] = 1.f; - - return l; -} - -HMM_Mat3 HMM_M3TRS(HMM_Vec2 pos, float angle, HMM_Vec2 s) -{ - HMM_Mat3 m; - float *lm = (float*)&m; - lm[0] = s.x*cos(angle); - lm[1] = s.x * sin(angle); - lm[2] = 0; - - lm[3] = -s.y*sin(angle); - lm[4] = s.y*cos(angle); - lm[5] = 0; - - lm[6] = pos.x; - lm[7] = pos.y; - lm[8] = 1; - return m; -} - -// This method taken from Mike Day at Insomniac Games. -// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf -// -// Note that as mentioned at the top of the paper, the paper assumes the matrix -// would be *post*-multiplied to a vector to rotate it, meaning the matrix is -// the transpose of what we're dealing with. But, because our matrices are -// stored in column-major order, the indices *appear* to match the paper. -// -// For example, m12 in the paper is row 1, column 2. We need to transpose it to -// row 2, column 1. But, because the column comes first when referencing -// elements, it looks like M.Elements[1][2]. -// -// Don't be confused! Or if you must be confused, at least trust this -// comment. :) -HMM_Quat HMM_M4ToQ_RH(HMM_Mat4 M) { - float T; - HMM_Quat Q; - - if (M.Elements[2][2] < 0.0f) { - if (M.Elements[0][0] > M.Elements[1][1]) { - - T = 1 + M.Elements[0][0] - M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_Q( - T, - M.Elements[0][1] + M.Elements[1][0], - M.Elements[2][0] + M.Elements[0][2], - M.Elements[1][2] - M.Elements[2][1]); - } else { - - T = 1 - M.Elements[0][0] + M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_Q( - M.Elements[0][1] + M.Elements[1][0], - T, - M.Elements[1][2] + M.Elements[2][1], - M.Elements[2][0] - M.Elements[0][2]); - } - } else { - if (M.Elements[0][0] < -M.Elements[1][1]) { - - T = 1 - M.Elements[0][0] - M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_Q( - M.Elements[2][0] + M.Elements[0][2], - M.Elements[1][2] + M.Elements[2][1], - T, - M.Elements[0][1] - M.Elements[1][0]); - } else { - - T = 1 + M.Elements[0][0] + M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_Q( - M.Elements[1][2] - M.Elements[2][1], - M.Elements[2][0] - M.Elements[0][2], - M.Elements[0][1] - M.Elements[1][0], - T); - } - } - - Q = HMM_MulQF(Q, 0.5f / HMM_SqrtF(T)); - - return Q; -} - -HMM_Quat HMM_M4ToQ_LH(HMM_Mat4 M) { - float T; - HMM_Quat Q; - - if (M.Elements[2][2] < 0.0f) { - if (M.Elements[0][0] > M.Elements[1][1]) { - - T = 1 + M.Elements[0][0] - M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_Q( - T, - M.Elements[0][1] + M.Elements[1][0], - M.Elements[2][0] + M.Elements[0][2], - M.Elements[2][1] - M.Elements[1][2]); - } else { - - T = 1 - M.Elements[0][0] + M.Elements[1][1] - M.Elements[2][2]; - Q = HMM_Q( - M.Elements[0][1] + M.Elements[1][0], - T, - M.Elements[1][2] + M.Elements[2][1], - M.Elements[0][2] - M.Elements[2][0]); - } - } else { - if (M.Elements[0][0] < -M.Elements[1][1]) { - - T = 1 - M.Elements[0][0] - M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_Q( - M.Elements[2][0] + M.Elements[0][2], - M.Elements[1][2] + M.Elements[2][1], - T, - M.Elements[1][0] - M.Elements[0][1]); - } else { - - T = 1 + M.Elements[0][0] + M.Elements[1][1] + M.Elements[2][2]; - Q = HMM_Q( - M.Elements[2][1] - M.Elements[1][2], - M.Elements[0][2] - M.Elements[2][0], - M.Elements[1][0] - M.Elements[0][2], - T); - } - } - - Q = HMM_MulQF(Q, 0.5f / HMM_SqrtF(T)); - - return Q; -} - -float HMM_Q_Roll(HMM_Quat q) -{ - return atan2(2.0*(q.x*q.y + q.w*q.z), q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z); -} - -float HMM_Q_Pitch(HMM_Quat q) -{ - return asin(-2.0*(q.x*q.z - q.w*q.y)); -} - -float HMM_Q_Yaw(HMM_Quat q) -{ - return atan2(2.0*(q.y*q.z + q.w*q.x), q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z); -} - -HMM_Quat HMM_QFromAxisAngle_RH(HMM_Vec3 Axis, float AngleOfRotation) { - - HMM_Quat Result; - - HMM_Vec3 AxisNormalized = HMM_NormV3(Axis); - float SineOfRotation = HMM_SinF(AngleOfRotation / 2.0f); - - Result.XYZ = HMM_MulV3F(AxisNormalized, SineOfRotation); - Result.W = HMM_CosF(AngleOfRotation / 2.0f); - - return Result; -} - -HMM_Quat HMM_QFromAxisAngle_LH(HMM_Vec3 Axis, float AngleOfRotation) { - - return HMM_QFromAxisAngle_RH(Axis, -AngleOfRotation); -} - -HMM_Mat3 HMM_Mat4ToMat3(HMM_Mat4 m4) -{ - HMM_Mat3 result = { - .Elements = { - m4.Elements[0][0], m4.Elements[0][1], m4.Elements[0][2], - m4.Elements[1][0], m4.Elements[1][1], m4.Elements[1][2], - m4.Elements[2][0], m4.Elements[2][1], m4.Elements[2][2] - } - }; - return result; -} diff --git a/source/HandmadeMath.h b/source/HandmadeMath.h deleted file mode 100644 index f262d457..00000000 --- a/source/HandmadeMath.h +++ /dev/null @@ -1,673 +0,0 @@ -/* - HandmadeMath.h v2.0.0 - - This is a single header file with a bunch of useful types and functions for - games and graphics. Consider it a lightweight alternative to GLM that works - both C and C++. - - ============================================================================= - CONFIG - ============================================================================= - - By default, all angles in Handmade Math are specified in radians. However, it - can be configured to use degrees or turns instead. Use one of the following - defines to specify the default unit for angles: - - #define HANDMADE_MATH_USE_RADIANS - #define HANDMADE_MATH_USE_DEGREES - #define HANDMADE_MATH_USE_TURNS - - Regardless of the default angle, you can use the following functions to - specify an angle in a particular unit: - - HMM_AngleRad(radians) - HMM_AngleDeg(degrees) - HMM_AngleTurn(turns) - - The definitions of these functions change depending on the default unit. - - ----------------------------------------------------------------------------- - - Handmade Math ships with SSE (SIMD) implementations of several common - operations. To disable the use of SSE intrinsics, you must define - HANDMADE_MATH_NO_SSE before including this file: - - #define HANDMADE_MATH_NO_SSE - #include "HandmadeMath.h" - - ----------------------------------------------------------------------------- - - To use Handmade Math without the C runtime library, you must provide your own - implementations of basic math functions. Otherwise, HandmadeMath.h will use - the runtime library implementation of these functions. - - Define HANDMADE_MATH_PROVIDE_MATH_FUNCTIONS and provide your own - implementations of HMM_SINF, HMM_COSF, HMM_TANF, HMM_ACOSF, and HMM_SQRTF - before including HandmadeMath.h, like so: - - #define HANDMADE_MATH_PROVIDE_MATH_FUNCTIONS - #define HMM_SINF MySinF - #define HMM_COSF MyCosF - #define HMM_TANF MyTanF - #define HMM_ACOSF MyACosF - #define HMM_SQRTF MySqrtF - #include "HandmadeMath.h" - - By default, it is assumed that your math functions take radians. To use - different units, you must define HMM_ANGLE_USER_TO_INTERNAL and - HMM_ANGLE_INTERNAL_TO_USER. For example, if you want to use degrees in your - code but your math functions use turns: - - #define HMM_ANGLE_USER_TO_INTERNAL(a) ((a)*HMM_DegToTurn) - #define HMM_ANGLE_INTERNAL_TO_USER(a) ((a)*HMM_TurnToDeg) - - ============================================================================= - - LICENSE - - This software is in the public domain. Where that dedictaion is not - recognized, you are granted a perpetual, irrevocable license to copy, - distribute, and modify this file as you see fit. - - ============================================================================= - - CREDITS - - Originally written by Zakary Strange. - - Functionality: - Zakary Strange (strangezak@protonmail.com && @strangezak) - Matt Mascarenhas (@miblo_) - Aleph - FieryDrake (@fierydrake) - Gingerbill (@TheGingerBill) - Ben Visness (@bvisness) - Trinton Bullard (@Peliex_Dev) - @AntonDan - Logan Forman (@dev_dwarf) - - Fixes: - Jeroen van Rijn (@J_vanRijn) - Kiljacken (@Kiljacken) - Insofaras (@insofaras) - Daniel Gibson (@DanielGibson) -*/ - -#ifndef HANDMADE_MATH_H -#define HANDMADE_MATH_H - -#if !defined(HANDMADE_MATH_NO_SIMD) - #if defined(__ARM_NEON) || defined(__ARM_NEON__) - #define HANDMADE_MATH__USE_NEON 1 - #include - #elif defined(_MSC_VER) - #if defined(_M_AMD64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) - #define HANDMADE_MATH__USE_SSE 1 - #include - #endif - #elif defined(__SSE__) - #define HANDMADE_MATH__USE_SSE 1 - #include - #endif -#endif - -#ifdef _MSC_VER -#pragma warning(disable : 4201) -#endif - -#if defined(__GNUC__) || defined(__clang__) -#define HMM_DEPRECATED(msg) __attribute__((deprecated(msg))) -#elif defined(_MSC_VER) -#define HMM_DEPRECATED(msg) __declspec(deprecated(msg)) -#else -#define HMM_DEPRECATED(msg) -#endif - -#if !defined(HANDMADE_MATH_USE_DEGREES) && !defined(HANDMADE_MATH_USE_TURNS) && !defined(HANDMADE_MATH_USE_RADIANS) -#define HANDMADE_MATH_USE_RADIANS -#endif - -#define HMM_PI 3.14159265358979323846 -#define HMM_PI32 3.14159265359f -#define HMM_DEG180 180.0 -#define HMM_DEG18032 180.0f -#define HMM_TURNHALF 0.5 -#define HMM_TURNHALF32 0.5f -#define HMM_RadToDeg ((float)(HMM_DEG180 / HMM_PI)) -#define HMM_RadToTurn ((float)(HMM_TURNHALF / HMM_PI)) -#define HMM_DegToRad ((float)(HMM_PI / HMM_DEG180)) -#define HMM_DegToTurn ((float)(HMM_TURNHALF / HMM_DEG180)) -#define HMM_TurnToRad ((float)(HMM_PI / HMM_TURNHALF)) -#define HMM_TurnToDeg ((float)(HMM_DEG180 / HMM_TURNHALF)) - -#if defined(HANDMADE_MATH_USE_RADIANS) -#define HMM_AngleRad(a) (a) -#define HMM_AngleDeg(a) ((a)*HMM_DegToRad) -#define HMM_AngleTurn(a) ((a)*HMM_TurnToRad) -#elif defined(HANDMADE_MATH_USE_DEGREES) -#define HMM_AngleRad(a) ((a)*HMM_RadToDeg) -#define HMM_AngleDeg(a) (a) -#define HMM_AngleTurn(a) ((a)*HMM_TurnToDeg) -#elif defined(HANDMADE_MATH_USE_TURNS) -#define HMM_AngleRad(a) ((a)*HMM_RadToTurn) -#define HMM_AngleDeg(a) ((a)*HMM_DegToTurn) -#define HMM_AngleTurn(a) (a) -#endif - -#if !defined(HANDMADE_MATH_PROVIDE_MATH_FUNCTIONS) -#include -#define HMM_SINF sinf -#define HMM_COSF cosf -#define HMM_TANF tanf -#define HMM_SQRTF sqrtf -#define HMM_ACOSF acosf -#endif - -#if !defined(HMM_ANGLE_USER_TO_INTERNAL) -#define HMM_ANGLE_USER_TO_INTERNAL(a) (HMM_ToRad(a)) -#endif - -#if !defined(HMM_ANGLE_INTERNAL_TO_USER) -#if defined(HANDMADE_MATH_USE_RADIANS) -#define HMM_ANGLE_INTERNAL_TO_USER(a) (a) -#elif defined(HANDMADE_MATH_USE_DEGREES) -#define HMM_ANGLE_INTERNAL_TO_USER(a) ((a)*HMM_RadToDeg) -#elif defined(HANDMADE_MATH_USE_TURNS) -#define HMM_ANGLE_INTERNAL_TO_USER(a) ((a)*HMM_RadToTurn) -#endif -#endif - -#define HMM_MIN(a, b) ((a) > (b) ? (b) : (a)) -#define HMM_MAX(a, b) ((a) < (b) ? (b) : (a)) -#define HMM_ABS(a) ((a) > 0 ? (a) : -(a)) -#define HMM_MOD(a, m) (((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m))) -#define HMM_SQUARE(x) ((x) * (x)) - -#define HMMFMT_VEC3 "[%g,%g,%g]" -#define HMMPRINT_VEC3(vec) vec.x, vec.y, vec.z - -#define FMT_VEC4 "[%g,%g,%g,%g]" -#define PRINT_VEC4(vec) vec.x, vec.y, vec.z, vec.w - -#define FMT_M4 "[%g,%g,%g,%g\n%g,%g,%g,%g\n%g,%g,%g,%g\n%g,%g,%g,%g]" -#define PRINT_M4(m) m.e[0][0], m.e[0][1], m.e[0][2], m.e[0][3], m.e[1][0], m.e[1][1], m.e[1][2], m.e[1][3], m.e[2][0], m.e[2][1], m.e[2][2], m.e[2][3], m.e[3][0], m.e[3][1], m.e[3][2], m.e[3][3] - -typedef union HMM_Vec2 { - struct - { - float X, Y; - }; - - struct { - float x, y; - }; - - struct - { - float U, V; - }; - - struct - { - float Left, Right; - }; - - struct - { - float Width, Height; - }; - - float Elements[2]; - float e[2]; - -} HMM_Vec2; - -typedef union HMM_Vec3 { - struct - { - float X, Y, Z; - }; - - struct { float x, y, z; }; - - struct - { - float U, V, W; - }; - - struct - { - float R, G, B; - }; - - struct - { - HMM_Vec2 XY; - float _Ignored0; - }; - - struct - { - HMM_Vec2 xy; - float _Ignored4; - }; - - struct - { - float _Ignored1; - HMM_Vec2 YZ; - }; - - struct - { - HMM_Vec2 UV; - float _Ignored2; - }; - - struct - { - float _Ignored3; - HMM_Vec2 VW; - }; - - struct - { - HMM_Vec2 cp; - float _Ignored5; - }; - - float Elements[3]; - float e[3]; - -} HMM_Vec3; - -typedef union HMM_Quat { - struct - { - union { - HMM_Vec3 XYZ; - struct - { - float X, Y, Z; - }; - }; - - float W; - }; - - struct {float x, y, z, w;}; - - float Elements[4]; - float e[4]; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSE; -#endif -} HMM_Quat; - - -typedef union HMM_Vec4 { - struct - { - union { - HMM_Vec3 XYZ; - struct - { - float X, Y, Z; - }; - HMM_Vec3 xyz; - }; - - float W; - }; - struct - { - union { - HMM_Vec3 RGB; - struct - { - float R, G, B; - }; - }; - - float A; - }; - - struct - { - HMM_Vec2 XY; - float _Ignored0; - float _Ignored1; - }; - - struct { - HMM_Vec2 xy; - float _ig0; - float _ig1; - }; - - struct { - HMM_Vec2 _2; - float _ig2; - float _ig3; - }; - - struct { - HMM_Vec3 _3; - float _ig4; - }; - - struct - { - float _Ignored2; - HMM_Vec2 YZ; - float _Ignored3; - }; - - struct - { - float _Ignored4; - float _Ignored5; - HMM_Vec2 ZW; - }; - - struct - { - HMM_Vec2 cp; - HMM_Vec2 wh; - }; - - HMM_Quat quat; - struct {float x, y, z, w; }; - struct {float r, g, b, a; }; - struct {float u0, u1, v0, v1;}; - - float Elements[4]; - float e[4]; - -#ifdef HANDMADE_MATH__USE_SSE - __m128 SSE; - #endif - #ifdef HANDMADE_MATH__USE_NEON - float32x4_t NEON; - #endif -} HMM_Vec4; - -typedef union HMM_Mat2 { - float Elements[2][2]; - HMM_Vec2 Columns[2]; - -} HMM_Mat2; - -typedef union HMM_Mat3 { - float Elements[3][3]; - HMM_Vec3 Columns[3]; - -} HMM_Mat3; - -typedef union HMM_Mat4 { - float Elements[4][4]; - HMM_Vec4 Columns[4]; - HMM_Vec4 col[4]; - float e[4][4]; - float em[16]; -} HMM_Mat4; - -extern const HMM_Vec2 v2zero; -extern const HMM_Vec2 v2one; -extern const HMM_Vec3 v3zero; -extern const HMM_Vec3 v3one; -extern const HMM_Vec4 v4zero; - -typedef signed int HMM_Bool; - -extern const HMM_Vec3 vX; -extern const HMM_Vec3 vY; -extern const HMM_Vec3 vZ; - -extern const HMM_Vec3 vUP; -extern const HMM_Vec3 vDOWN; -extern const HMM_Vec3 vFWD; -extern const HMM_Vec3 vBKWD; -extern const HMM_Vec3 vLEFT; -extern const HMM_Vec3 vRIGHT; - -extern const HMM_Mat4 MAT1; - -extern const HMM_Quat QUAT1; - -/* - * Angle unit conversion functions - */ -float HMM_ToRad(float Angle); -float HMM_ToDeg(float Angle); -float HMM_ToTurn(float Angle); - -/* - * Floating-point math functions - */ -float HMM_SinF(float Angle); -float HMM_CosF(float Angle); -float HMM_TanF(float Angle); -float HMM_ACosF(float Arg); -float HMM_SqrtF(float Float); -float HMM_InvSqrtF(float Float); - -/* - * Utility functions - */ -float HMM_Lerp(float A, float Time, float B); -float HMM_Clamp(float Min, float Value, float Max); -float frand(float max); - -/* - * Vector initialization - */ -HMM_Vec2 HMM_V2(float X, float Y); -HMM_Vec3 HMM_V3(float X, float Y, float Z); -HMM_Vec3 HMM_V3i(float i); -HMM_Vec4 HMM_V4(float X, float Y, float Z, float W); -HMM_Vec4 HMM_V4V(HMM_Vec3 Vector, float W); - -/* - * Binary vector operations - */ -HMM_Vec2 HMM_AddV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Vec3 HMM_AddV3(HMM_Vec3 Left, HMM_Vec3 Right); -HMM_Vec4 HMM_AddV4(HMM_Vec4 Left, HMM_Vec4 Right); -HMM_Vec2 HMM_SubV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Vec3 HMM_SubV3(HMM_Vec3 Left, HMM_Vec3 Right); -HMM_Vec4 HMM_SubV4(HMM_Vec4 Left, HMM_Vec4 Right); -HMM_Vec2 HMM_MulV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Vec2 HMM_MulV2F(HMM_Vec2 Left, float Right); -HMM_Vec3 HMM_MulV3(HMM_Vec3 Left, HMM_Vec3 Right); -HMM_Vec3 HMM_MulV3F(HMM_Vec3 Left, float Right); -HMM_Vec4 HMM_MulV4(HMM_Vec4 Left, HMM_Vec4 Right); -HMM_Vec4 HMM_MulV4F(HMM_Vec4 Left, float Right); -HMM_Vec2 HMM_DivV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Vec2 HMM_DivV2F(HMM_Vec2 Left, float Right); -HMM_Vec3 HMM_DivV3(HMM_Vec3 Left, HMM_Vec3 Right); -HMM_Vec3 HMM_DivV3F(HMM_Vec3 Left, float Right); -HMM_Vec4 HMM_DivV4(HMM_Vec4 Left, HMM_Vec4 Right); -HMM_Vec4 HMM_DivV4F(HMM_Vec4 Left, float Right); -HMM_Bool HMM_EqV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Bool HMM_EqV3(HMM_Vec3 Left, HMM_Vec3 Right); -HMM_Bool HMM_EqV4(HMM_Vec4 Left, HMM_Vec4 Right); -float HMM_DotV2(HMM_Vec2 Left, HMM_Vec2 Right); -HMM_Vec2 HMM_ProjV2(HMM_Vec2 a, HMM_Vec2 b); -float HMM_DotV3(HMM_Vec3 Left, HMM_Vec3 Right); -float HMM_DotV4(HMM_Vec4 Left, HMM_Vec4 Right); -HMM_Vec3 HMM_Cross(HMM_Vec3 Left, HMM_Vec3 Right); - -/* - * Unary vector operations - */ -float HMM_LenSqrV2(HMM_Vec2 A); -float HMM_LenSqrV3(HMM_Vec3 A); -float HMM_LenSqrV4(HMM_Vec4 A); -float HMM_LenV2(HMM_Vec2 A); -float HMM_AngleV2(HMM_Vec2 a, HMM_Vec2 b); -float HMM_DistV2(HMM_Vec2 a, HMM_Vec2 b); -HMM_Vec2 HMM_V2Rotate(HMM_Vec2 v, float angle); -float HMM_LenV3(HMM_Vec3 A); -float HMM_DistV3(HMM_Vec3 a, HMM_Vec3 b); -float HMM_AngleV3(HMM_Vec3 a, HMM_Vec3 b); -float HMM_LenV4(HMM_Vec4 A); -float HMM_AngleV4(HMM_Vec4 a, HMM_Vec4 b); -HMM_Vec2 HMM_NormV2(HMM_Vec2 A); -HMM_Vec3 HMM_NormV3(HMM_Vec3 A); -HMM_Vec4 HMM_NormV4(HMM_Vec4 A); - -/* - * Utility vector functions - */ -HMM_Vec2 HMM_LerpV2(HMM_Vec2 A, float Time, HMM_Vec2 B); -HMM_Vec3 HMM_LerpV3(HMM_Vec3 A, float Time, HMM_Vec3 B); -HMM_Vec4 HMM_LerpV4(HMM_Vec4 A, float Time, HMM_Vec4 B); - -/* - * SSE stuff - */ -HMM_Vec4 HMM_LinearCombineV4M4(HMM_Vec4 Left, HMM_Mat4 Right); - -/* - * 2x2 Matrices - */ -HMM_Mat2 HMM_M2(void); -HMM_Mat2 HMM_M2D(float Diagonal); -HMM_Mat2 HMM_TransposeM2(HMM_Mat2 Matrix); -HMM_Mat2 HMM_RotateM2(float angle); -HMM_Mat2 HMM_AddM2(HMM_Mat2 Left, HMM_Mat2 Right); -HMM_Mat2 HMM_SubM2(HMM_Mat2 Left, HMM_Mat2 Right); -HMM_Vec2 HMM_MulM2V2(HMM_Mat2 Matrix, HMM_Vec2 Vector); -HMM_Mat2 HMM_MulM2(HMM_Mat2 Left, HMM_Mat2 Right); -HMM_Mat2 HMM_MulM2F(HMM_Mat2 Matrix, float Scalar); -HMM_Mat2 HMM_DivM2F(HMM_Mat2 Matrix, float Scalar); -float HMM_DeterminantM2(HMM_Mat2 Matrix); -HMM_Mat2 HMM_InvGeneralM2(HMM_Mat2 Matrix); - -/* - * 3x3 Matrices - */ -HMM_Mat3 HMM_M3(void); -HMM_Mat3 HMM_M3D(float Diagonal); -HMM_Mat3 HMM_Translate2D(HMM_Vec2 p); -HMM_Mat3 HMM_RotateM3(float angle); -HMM_Mat3 HMM_ScaleM3(HMM_Vec2 s); -HMM_Mat3 HMM_TransposeM3(HMM_Mat3 Matrix); -HMM_Mat3 HMM_AddM3(HMM_Mat3 Left, HMM_Mat3 Right); -HMM_Mat3 HMM_SubM3(HMM_Mat3 Left, HMM_Mat3 Right); -HMM_Vec3 HMM_MulM3V3(HMM_Mat3 Matrix, HMM_Vec3 Vector); -HMM_Mat3 HMM_MulM3(HMM_Mat3 Left, HMM_Mat3 Right); -HMM_Mat3 HMM_MulM3F(HMM_Mat3 Matrix, float Scalar); -HMM_Mat3 HMM_DivM3F(HMM_Mat3 Matrix, float Scalar); -HMM_Mat2 HMM_ScaleM2(HMM_Vec2 Scale); -float HMM_DeterminantM3(HMM_Mat3 Matrix); -HMM_Mat3 HMM_M2Basis(HMM_Mat2 basis); -HMM_Mat3 HMM_InvGeneralM3(HMM_Mat3 Matrix); - -/* - * 4x4 Matrices - */ -HMM_Mat4 HMM_M4(void); -HMM_Mat4 HMM_M4D(float Diagonal); -HMM_Mat4 HMM_TransposeM4(HMM_Mat4 Matrix); -HMM_Mat4 HMM_AddM4(HMM_Mat4 Left, HMM_Mat4 Right); -HMM_Mat4 HMM_SubM4(HMM_Mat4 Left, HMM_Mat4 Right); -HMM_Mat4 HMM_MulM4(HMM_Mat4 Left, HMM_Mat4 Right); -HMM_Mat4 HMM_MulM4_P(HMM_Mat4 *Left, HMM_Mat4 *Right); -HMM_Mat4 HMM_MulM4F(HMM_Mat4 Matrix, float Scalar); -HMM_Vec4 HMM_MulM4V4(HMM_Mat4 Matrix, HMM_Vec4 Vector); -HMM_Vec4 HMM_MulM4V4_P(HMM_Mat4 *Matrix, HMM_Vec4 *Vector); -HMM_Mat4 HMM_DivM4F(HMM_Mat4 Matrix, float Scalar); -float HMM_DeterminantM4(HMM_Mat4 Matrix); - -// Returns a general-purpose inverse of an HMM_Mat4. Note that special-purpose inverses of many transformations -// are available and will be more efficient. -HMM_Mat4 HMM_InvGeneralM4(HMM_Mat4 Matrix); - -/* - * Common graphics transformations - */ - -// Produces a right-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_RH_NO(float Left, float Right, float Bottom, float Top, float Near, float Far); - -// Produces a right-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_RH_ZO(float Left, float Right, float Bottom, float Top, float Near, float Far); - -// Produces a left-handed orthographic projection matrix with Z ranging from -1 to 1 (the GL convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_LH_NO(float Left, float Right, float Bottom, float Top, float Near, float Far); - -// Produces a left-handed orthographic projection matrix with Z ranging from 0 to 1 (the DirectX convention). -// Left, Right, Bottom, and Top specify the coordinates of their respective clipping planes. -// Near and Far specify the distances to the near and far clipping planes. -HMM_Mat4 HMM_Orthographic_LH_ZO(float Left, float Right, float Bottom, float Top, float Near, float Far); - -// Returns an inverse for the given orthographic projection matrix. Works for all orthographic -// projection matrices, regardless of handedness or NDC convention. -HMM_Mat4 HMM_InvOrthographic(HMM_Mat4 OrthoMatrix); -HMM_Mat4 HMM_Perspective_RH_NO(float FOV, float AspectRatio, float Near, float Far); -HMM_Mat4 HMM_Perspective_RH_ZO(float FOV, float AspectRatio, float Near, float Far); -HMM_Mat4 HMM_Perspective_LH_NO(float FOV, float AspectRatio, float Near, float Far); -HMM_Mat4 HMM_Perspective_LH_ZO(float FOV, float AspectRatio, float Near, float Far); - -HMM_Mat4 HMM_Perspective_Metal(float FOV, float AspectRation, float Near, float Far); -HMM_Mat4 HMM_Orthographic_Metal(float l, float r, float b, float t, float near, float far); - -HMM_Mat4 HMM_Orthographic_DX(float l, float r, float b, float t, float near, float far); -HMM_Mat4 HMM_Orthographic_GL(float l, float r, float b, float t, float near, float far); - -HMM_Mat4 HMM_InvPerspective_RH(HMM_Mat4 PerspectiveMatrix); -HMM_Mat4 HMM_InvPerspective_LH(HMM_Mat4 PerspectiveMatrix); -HMM_Mat4 HMM_Translate(HMM_Vec3 Translation); -HMM_Mat4 HMM_InvTranslate(HMM_Mat4 TranslationMatrix); -HMM_Mat4 HMM_Rotate_RH(float Angle, HMM_Vec3 Axis); -HMM_Mat4 HMM_Rotate_LH(float Angle, HMM_Vec3 Axis); -HMM_Mat4 HMM_InvRotate(HMM_Mat4 RotationMatrix); -HMM_Mat4 HMM_Scale(HMM_Vec3 Scale); -HMM_Mat4 HMM_InvScale(HMM_Mat4 ScaleMatrix); -HMM_Mat4 _HMM_LookAt(HMM_Vec3 F, HMM_Vec3 S, HMM_Vec3 U, HMM_Vec3 Eye); -HMM_Mat4 HMM_LookAt_RH(HMM_Vec3 Eye, HMM_Vec3 Center, HMM_Vec3 Up); -HMM_Mat4 HMM_LookAt_LH(HMM_Vec3 Eye, HMM_Vec3 Center, HMM_Vec3 Up); -HMM_Mat4 HMM_InvLookAt(HMM_Mat4 Matrix); - -/* - * Quaternion operations - */ -HMM_Vec3 HMM_QVRot(HMM_Vec3 v, HMM_Quat q) -; -HMM_Quat HMM_Q(float X, float Y, float Z, float W); -HMM_Quat HMM_QV4(HMM_Vec4 Vector); -HMM_Quat HMM_AddQ(HMM_Quat Left, HMM_Quat Right); -HMM_Quat HMM_SubQ(HMM_Quat Left, HMM_Quat Right); -HMM_Quat HMM_MulQ(HMM_Quat Left, HMM_Quat Right); -HMM_Quat HMM_MulQF(HMM_Quat Left, float Multiplicative); -HMM_Quat HMM_DivQF(HMM_Quat Left, float Divnd); -float HMM_DotQ(HMM_Quat Left, HMM_Quat Right); -HMM_Quat HMM_InvQ(HMM_Quat Left); -HMM_Quat HMM_NormQ(HMM_Quat Quat); -HMM_Quat _HMM_MixQ(HMM_Quat Left, float MixLeft, HMM_Quat Right, float MixRight); -HMM_Quat HMM_NLerp(HMM_Quat Left, float Time, HMM_Quat Right); -HMM_Quat HMM_SLerp(HMM_Quat Left, float Time, HMM_Quat Right); -HMM_Mat4 HMM_QToM4(HMM_Quat Left); -HMM_Mat4 HMM_M4TRS(HMM_Vec3 t, HMM_Quat q, HMM_Vec3 s); -HMM_Mat3 HMM_M3TRS(HMM_Vec2 t, float angle, HMM_Vec2 s); -HMM_Mat3 HMM_Mat4ToMat3(HMM_Mat4 m); - -HMM_Quat HMM_M4ToQ_RH(HMM_Mat4 M); -HMM_Quat HMM_M4ToQ_LH(HMM_Mat4 M); -HMM_Quat HMM_QFromAxisAngle_RH(HMM_Vec3 Axis, float AngleOfRotation); -HMM_Quat HMM_QFromAxisAngle_LH(HMM_Vec3 Axis, float AngleOfRotation); - -float HMM_Q_Roll(HMM_Quat q); -float HMM_Q_Yaw(HMM_Quat q); -float HMM_Q_Pitch(HMM_Quat q); - -#endif /* HANDMADE_MATH_H */ diff --git a/source/cell.h b/source/cell.h index 00d112a4..b5099aab 100644 --- a/source/cell.h +++ b/source/cell.h @@ -1,5 +1,5 @@ -#ifndef PROSPERON_H -#define PROSPERON_H +#ifndef CELL_H +#define CELL_H #include #include "quickjs.h" @@ -113,6 +113,11 @@ void actor_clock(cell_rt *actor, JSValue fn); int JS_ArrayLength(JSContext *js, JSValue a); +int js2bool(JSContext *js, JSValue v); +JSValue bool2js(JSContext *js, int b); +double js2number(JSContext *js, JSValue v); +JSValue number2js(JSContext *js, double g); + #ifdef __cplusplus } #endif diff --git a/source/jsffi.c b/source/jsffi.c index b7339258..ebd9ac98 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -81,18 +81,13 @@ double rand_range(JSContext *js, double min, double max) return genRand(mrand) * (max-min)+min; } -typedef struct texture_vertex { - float x, y, z; - float u, v; - uint8_t r, g, b,a; -} texture_vertex; - #define JS_GETNUM(JS,VAL,I,TO,TYPE) { \ JSValue val = JS_GetPropertyUint32(JS,VAL,I); \ TO = js2##TYPE(JS, val); \ JS_FreeValue(JS, val); } \ int js2bool(JSContext *js, JSValue v) { return JS_ToBool(js,v); } +JSValue bool2js(JSContext *js, int b) { return JS_NewBool(js,b); } JSValue number2js(JSContext *js, double g) { return JS_NewFloat64(js,g); } double js2number(JSContext *js, JSValue v) { @@ -102,47 +97,6 @@ double js2number(JSContext *js, JSValue v) { return g; } -JSValue js_getpropertyuint32(JSContext *js, JSValue v, unsigned int i) -{ - JSValue ret = JS_GetPropertyUint32(js,v,i); - JS_FreeValue(js,ret); - return ret; -} - -double js_getnum_uint32(JSContext *js, JSValue v, unsigned int i) -{ - JSValue val = JS_GetPropertyUint32(js,v,i); - double ret = js2number(js, val); - JS_FreeValue(js,val); - return ret; -} - -double js_getnum_str(JSContext *js, JSValue v, const char *str) -{ - JSValue val = JS_GetPropertyStr(js,v,str); - double ret = js2number(js,val); - JS_FreeValue(js,val); - return ret; -} - -#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -#define JS_GETATOM(JS, TARGET, VALUE, ATOM, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -int JS_GETBOOL(JSContext *js, JSValue v, const char *prop) -{ - JSValue __v = JS_GetPropertyStr(js,v,prop); - int r = JS_ToBool(js,__v); - JS_FreeValue(js,__v); - return r; -} - JSValue js_getproperty(JSContext *js, JSValue v, const char *prop) { JSValue ret = JS_GetPropertyStr(js, v, prop); @@ -176,28 +130,6 @@ JSValue make_quad_indices_buffer(JSContext *js, int quads) return JS_DupValue(js,rt->idx_buffer); } - - -typedef struct lrtb lrtb; - -lrtb js2lrtb(JSContext *js, JSValue v) -{ - lrtb ret = {0}; - JS_GETATOM(js,ret.l,v,l,number) - JS_GETATOM(js,ret.r,v,r,number) - JS_GETATOM(js,ret.b,v,b,number) - JS_GETATOM(js,ret.t,v,t,number) - return ret; -} - -JSValue vec22js(JSContext *js,HMM_Vec2 v) -{ - JSValue array = JS_NewArray(js); - JS_SetPropertyUint32(js, array,0,number2js(js,v.x)); - JS_SetPropertyUint32(js, array,1,number2js(js,v.y)); - return array; -} - char *js2strdup(JSContext *js, JSValue v) { const char *str = JS_ToCString(js, v); char *ret = strdup(str); @@ -216,340 +148,6 @@ double js2angle(JSContext *js,JSValue v) { return n * HMM_TurnToRad; } -typedef HMM_Vec4 colorf; - -colorf js2color(JSContext *js,JSValue v) { - if (JS_IsNull(v)) return (colorf){1,1,1,1}; - - colorf color = {1,1,1,1}; // Default to white - - if (JS_IsArray(js, v)) { - // Handle array format: [r, g, b, a] - JSValue c[4]; - for (int i = 0; i < 4; i++) c[i] = JS_GetPropertyUint32(js,v,i); - - color.r = js2number(js,c[0]); - color.g = js2number(js,c[1]); - color.b = js2number(js,c[2]); - color.a = JS_IsNull(c[3]) ? 1.0 : js2number(js,c[3]); - - for (int i = 0; i < 4; i++) JS_FreeValue(js,c[i]); - } else if (JS_IsObject(v)) { - JS_GETPROP(js, color.r, v, r, number) - JS_GETPROP(js, color.g, v, g, number) - JS_GETPROP(js, color.b, v, b, number) - JS_GETPROP(js, color.a, v, a, number) - } - - return color; -} - -JSValue color2js(JSContext *js, colorf color) -{ - JSValue arr = JS_NewArray(js); - JS_SetPropertyUint32(js, arr,0,number2js(js,(double)color.r)); - JS_SetPropertyUint32(js, arr,1,number2js(js,(double)color.g)); - JS_SetPropertyUint32(js, arr,2,number2js(js,(double)color.b)); - JS_SetPropertyUint32(js, arr,3,number2js(js,(double)color.a)); - return arr; -} - -HMM_Vec2 js2vec2(JSContext *js,JSValue v) -{ - HMM_Vec2 v2; - - // Check if it's an array - if (JS_IsArray(js, v)) { - v2.X = js_getnum_uint32(js,v,0); - v2.Y = js_getnum_uint32(js,v,1); - } else { - // Try to get x,y properties from object - JSValue x_val = JS_GetPropertyStr(js, v, "x"); - JSValue y_val = JS_GetPropertyStr(js, v, "y"); - - v2.X = js2number(js, x_val); - v2.Y = js2number(js, y_val); - - JS_FreeValue(js, x_val); - JS_FreeValue(js, y_val); - } - - return v2; -} - -HMM_Vec3 js2vec3(JSContext *js,JSValue v) -{ - HMM_Vec3 v3; - v3.x = js_getnum_uint32(js, v,0); - v3.y = js_getnum_uint32(js, v,1); - v3.z = js_getnum_uint32(js, v,2); - return v3; -} - -float *js2floats(JSContext *js, JSValue v, size_t *len) -{ - *len = JS_ArrayLength(js,v); - float *arr = malloc(sizeof(float)* *len); - for (int i = 0; i < *len; i++) - arr[i] = js_getnum_uint32(js,v,i); - return arr; -} - -double *js2doubles(JSContext *js, JSValue v, size_t *len) -{ - *len = JS_ArrayLength(js,v); - double *arr = malloc(sizeof(double)* *len); - for (int i = 0; i < *len; i++) - arr[i] = js_getnum_uint32(js,v,i); - return arr; -} - -HMM_Vec3 js2vec3f(JSContext *js, JSValue v) -{ - HMM_Vec3 vec; - if (JS_IsArray(js, v)) - return js2vec3(js,v); - else - vec.x = vec.y = vec.z = js2number(js,v); - return vec; -} - -JSValue vec32js(JSContext *js, HMM_Vec3 v) -{ - JSValue array = JS_NewArray(js); - JS_SetPropertyUint32(js, array,0,number2js(js,v.x)); - JS_SetPropertyUint32(js, array,1,number2js(js,v.y)); - JS_SetPropertyUint32(js, array,2,number2js(js,v.z)); - return array; -} - -JSValue vec3f2js(JSContext *js, HMM_Vec3 v) -{ - return vec32js(js,v); -} - -JSValue quat2js(JSContext *js, HMM_Quat q) -{ - JSValue arr = JS_NewArray(js); - JS_SetPropertyUint32(js, arr, 0, number2js(js,q.x)); - JS_SetPropertyUint32(js, arr,1,number2js(js,q.y)); - JS_SetPropertyUint32(js, arr,2,number2js(js,q.z)); - JS_SetPropertyUint32(js, arr,3,number2js(js,q.w)); - return arr; -} - -HMM_Vec4 js2vec4(JSContext *js, JSValue v) -{ - HMM_Vec4 v4; - for (int i = 0; i < 4; i++) - v4.e[i] = js_getnum_uint32(js, v,i); - return v4; -} - -double arr_vec_length(JSContext *js,JSValue v) -{ - int len = JS_ArrayLength(js,v); - switch(len) { - case 2: return HMM_LenV2(js2vec2(js,v)); - case 3: return HMM_LenV3(js2vec3(js,v)); - case 4: return HMM_LenV4(js2vec4(js,v)); - } - - double sum = 0; - for (int i = 0; i < len; i++) - sum += pow(js_getnum_uint32(js, v, i), 2); - - return sqrt(sum); -} - -HMM_Quat js2quat(JSContext *js,JSValue v) -{ - return js2vec4(js,v).quat; -} - -JSValue vec42js(JSContext *js, HMM_Vec4 v) -{ - JSValue array = JS_NewArray(js); - for (int i = 0; i < 4; i++) - JS_SetPropertyUint32(js, array,i,number2js(js,v.e[i])); - return array; -} - -HMM_Vec2 *js2cpvec2arr(JSContext *js,JSValue v) { - HMM_Vec2 *arr = NULL; - int n = JS_ArrayLength(js,v); - arrsetlen(arr,n); - - for (int i = 0; i < n; i++) - arr[i] = js2vec2(js,js_getpropertyuint32(js, v, i)); - - return arr; -} - -JSValue vecarr2js(JSContext *js,HMM_Vec2 *points, int n) { - JSValue array = JS_NewArray(js); - for (int i = 0; i < n; i++) - JS_SetPropertyUint32(js, array,i,vec22js(js,points[i])); - - return array; -} - -rect js2rect(JSContext *js,JSValue v) { - if (JS_IsNull(v)) return (rect){0,0,1,1}; - rect rect; - JS_GETATOM(js,rect.x,v,x,number) - JS_GETATOM(js,rect.y,v,y,number) - JS_GETATOM(js,rect.w,v,width,number) - JS_GETATOM(js,rect.h,v,height,number) - float anchor_x, anchor_y; - JS_GETATOM(js, anchor_x, v, anchor_x, number) - JS_GETATOM(js, anchor_y, v, anchor_y, number) - - rect.y -= anchor_y*rect.h; - rect.x -= anchor_x*rect.w; - - return rect; -} - -irect js2irect(JSContext *js, JSValue v) -{ - if (JS_IsNull(v)) return (irect){0,0,1,1}; - irect rect; - JS_GETATOM(js,rect.x,v,x,number) - JS_GETATOM(js,rect.y,v,y,number) - JS_GETATOM(js,rect.w,v,width,number) - JS_GETATOM(js,rect.h,v,height,number) - float anchor_x, anchor_y; - JS_GETATOM(js, anchor_x, v, anchor_x, number) - JS_GETATOM(js, anchor_y, v, anchor_y, number) - - rect.y -= anchor_y*rect.h; - rect.x -= anchor_x*rect.w; - - return rect; -} - -JSValue rect2js(JSContext *js,rect rect) { - JSValue obj = JS_NewObject(js); - JS_SetPropertyStr(js, obj, "x", number2js(js, rect.x)); - JS_SetPropertyStr(js, obj, "y", number2js(js, rect.y)); - JS_SetPropertyStr(js, obj, "width", number2js(js, rect.w)); - JS_SetPropertyStr(js, obj, "height", number2js(js, rect.h)); - return obj; -} - -static JSValue floats2array(JSContext *js, float *vals, size_t len) { - JSValue arr = JS_NewArray(js); - for (size_t i = 0; i < len; i++) { - JS_SetPropertyUint32(js, arr, i, number2js(js, vals[i])); - } - return arr; -} - -#define JS_HMM_FN(OP, HMM, SIGN) \ -JSC_CCALL(array_##OP, \ - int len = JS_ArrayLength(js,self); \ - if (!JS_IsArray(js, argv[0])) { \ - double n = js2number(js,argv[0]); \ - JSValue arr = JS_NewArray(js); \ - for (int i = 0; i < len; i++) \ - JS_SetPropertyUint32(js, arr, i, number2js(js,js_getnum_uint32(js, self,i) SIGN n)); \ - return arr; \ - } \ - switch(len) { \ - case 2: \ - return vec22js(js,HMM_##HMM##V2(js2vec2(js,self), js2vec2(js,argv[0]))); \ - case 3: \ - return vec32js(js, HMM_##HMM##V3(js2vec3(js,self), js2vec3(js,argv[0]))); \ - case 4: \ - return vec42js(js,HMM_##HMM##V4(js2vec4(js,self), js2vec4(js,argv[0]))); \ - } \ - \ - JSValue arr = JS_NewArray(js); \ - for (int i = 0; i < len; i++) { \ - double a = js_getnum_uint32(js, self,i); \ - double b = js_getnum_uint32(js, argv[0],i); \ - JS_SetPropertyUint32(js, arr, i, number2js(js,a SIGN b)); \ - } \ - return arr; \ -) \ - -JS_HMM_FN(add, Add, +) -JS_HMM_FN(sub, Sub, -) -JS_HMM_FN(div, Div, /) -JS_HMM_FN(scale, Mul, *) - -JSC_CCALL(array_lerp, - double t = js2number(js,argv[1]); - int len = JS_ArrayLength(js,self); - JSValue arr = JS_NewArray(js); - - for (int i = 0; i < len; i++) { - double from = js_getnum_uint32(js, self, i); - double to = js_getnum_uint32(js, argv[0], i); - JS_SetPropertyUint32(js, arr, i, number2js(js,(to - from) * t + from)); - } - return arr; -) - -JSValue js_array_get_x(JSContext *js, JSValue self) { return JS_GetPropertyUint32(js,self,0); } -JSValue js_array_set_x(JSContext *js, JSValue self, JSValue val) { JS_SetPropertyUint32(js,self,0,val); return JS_NULL; } - -JSValue js_array_get_y(JSContext *js, JSValue self) { return JS_GetPropertyUint32(js,self,1); } -JSValue js_array_set_y(JSContext *js, JSValue self, JSValue val) { JS_SetPropertyUint32(js,self,1,val); return JS_NULL; } - -// Single-value accessors - -JSValue js_array_get_r(JSContext *js, JSValue self) -{ return JS_GetPropertyUint32(js, self, 0); } - -JSValue js_array_set_r(JSContext *js, JSValue self, JSValue val) -{ JS_SetPropertyUint32(js, self, 0, val); return JS_NULL; } - -JSValue js_array_get_g(JSContext *js, JSValue self) -{ return JS_GetPropertyUint32(js, self, 1); } - -JSValue js_array_set_g(JSContext *js, JSValue self, JSValue val) -{ JS_SetPropertyUint32(js, self, 1, val); return JS_NULL; } - -JSValue js_array_get_b(JSContext *js, JSValue self) -{ return JS_GetPropertyUint32(js, self, 2); } - -JSValue js_array_set_b(JSContext *js, JSValue self, JSValue val) -{ JS_SetPropertyUint32(js, self, 2, val); return JS_NULL; } - -JSValue js_array_get_a(JSContext *js, JSValue self) -{ return JS_GetPropertyUint32(js, self, 3); } - -JSValue js_array_set_a(JSContext *js, JSValue self, JSValue val) -{ JS_SetPropertyUint32(js, self, 3, val); return JS_NULL; } - -// Multi-value accessors -static const JSCFunctionListEntry js_array_funcs[] = { - PROTO_FUNC_DEF(array, add, 1), - PROTO_FUNC_DEF(array, sub, 1), - PROTO_FUNC_DEF(array, div,1), - PROTO_FUNC_DEF(array, scale, 1), - PROTO_FUNC_DEF(array, lerp, 2), - JS_CGETSET_DEF("x", js_array_get_x,js_array_set_x), - JS_CGETSET_DEF("y", js_array_get_y, js_array_set_y), - JS_CGETSET_DEF("r", js_array_get_r, js_array_set_r), - JS_CGETSET_DEF("g", js_array_get_g, js_array_set_g), - JS_CGETSET_DEF("b", js_array_get_b, js_array_set_b), - JS_CGETSET_DEF("a", js_array_get_a, js_array_set_a), -}; - -JSC_CCALL(number_lerp, - double a = js2number(js,self); - double b = js2number(js,argv[0]); - double t = js2number(js,argv[1]); - return number2js(js, (b-a)*t+a); -) - -static const JSCFunctionListEntry js_number_funcs[] = { - PROTO_FUNC_DEF(number, lerp, 2), -}; - static uint32_t rng_state = 123456789; static uint32_t xorshift32(){ uint32_t x = rng_state; @@ -601,73 +199,10 @@ JSC_CCALL(os_srand, m_seedRand(mrand, js2number(js,argv[0])); ) -JSC_CCALL(os_make_line_prim, - return JS_NULL; - /* - JSValue prim = JS_NewObject(js); - HMM_Vec2 *v = js2cpvec2arr(js,argv[0]); - - parsl_context *par_ctx = parsl_create_context((parsl_config){ - .thickness = js2number(js,argv[1]), - .flags= PARSL_FLAG_ANNOTATIONS, - .u_mode = js2number(js,argv[2]) - }); - - uint16_t spine_lens[] = {arrlen(v)}; - - parsl_mesh *m = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){ - .num_vertices = arrlen(v), - .num_spines = 1, - .vertices = v, - .spine_lengths = spine_lens, - .closed = JS_ToBool(js,argv[3]) - }); - - JS_SetPropertyStr(js, prim, "pos", make_gpu_buffer(js,m->positions,sizeof(*m->positions)*m->num_vertices, 0, 2,1,0)); - - JS_SetPropertyStr(js, prim, "indices", make_gpu_buffer(js,m->triangle_indices,sizeof(*m->triangle_indices)*m->num_triangles*3, JS_TYPED_ARRAY_UINT32, 1,1,1)); - - float uv[m->num_vertices*2]; - for (int i = 0; i < m->num_vertices; i++) { - uv[i*2] = m->annotations[i].u_along_curve; - uv[i*2+1] = m->annotations[i].v_across_curve; - } - - JS_SetPropertyStr(js, prim, "uv", make_gpu_buffer(js, uv, sizeof(uv), 0,2,1,0)); - JS_SetPropertyStr(js,prim,"vertices", number2js(js,m->num_vertices)); - JS_SetPropertyStr(js,prim,"num_indices", number2js(js,m->num_triangles*3)); - JS_SetPropertyStr(js,prim,"first_index", number2js(js,0)); - - parsl_destroy_context(par_ctx); - - return prim; - */ -) - static const JSCFunctionListEntry js_util_funcs[] = { MIST_FUNC_DEF(os, guid, 0), }; -JSC_CCALL(graphics_hsl_to_rgb, - float h, s, l; - JS_ToFloat64(js, &h, argv[0]); - JS_ToFloat64(js, &s, argv[1]); - JS_ToFloat64(js, &l, argv[2]); - float c = (1 - abs(2 * l - 1)) * s; - float x = c * (1 - abs(fmod((h/60),2) - 1)); - float m = l - c / 2; - float r = 0, g = 0, b = 0; - - if (h < 60) { r = c; g = x; } - else if (h < 120) { r = x; g = c; } - else if (h < 180) { g = c; b = x; } - else if (h < 240) { g = x; b = c; } - else if (h < 300) { r = x; b = c; } - else { r = c; b = x; } - - return color2js(js, (colorf){r+m, g+m, b+m, 1}); -) - static void *get_main_module_handle() { #if defined(_WIN32) return GetModuleHandle(NULL); @@ -803,18 +338,6 @@ void ffi_load(JSContext *js) JSValue prosp = JS_NewObject(js); JS_SetPropertyStr(js,globalThis,"prosperon", prosp); - JSValue jsarray = JS_GetPropertyStr(js,globalThis, "Array"); - JSValue array_proto = JS_GetPropertyStr(js,jsarray, "prototype"); - JS_SetPropertyFunctionList(js, array_proto, js_array_funcs, countof(js_array_funcs)); - JS_FreeValue(js,jsarray); - JS_FreeValue(js,array_proto); - - JSValue jsnumber = JS_GetPropertyStr(js,globalThis, "Number"); - JSValue number_proto = JS_GetPropertyStr(js,jsnumber, "prototype"); - JS_SetPropertyFunctionList(js, number_proto, js_number_funcs, countof(js_number_funcs)); - JS_FreeValue(js,jsnumber); - JS_FreeValue(js,number_proto); - JSValue hidden_fn = JS_NewObject(js); // Add functions that should only be accessible to engine.js diff --git a/source/jsffi.h b/source/jsffi.h index 39789132..76459698 100644 --- a/source/jsffi.h +++ b/source/jsffi.h @@ -2,102 +2,7 @@ #define FFI_H #include "cell.h" -#include "HandmadeMath.h" -#include "render.h" -#define JS_SetProperty(js, tar, str, val) JS_SetPropertyStr(js, tar, #str, val) -#define JS_GetProperty(js, tar, atom) JS_GetPropertyStr(js, tar, #atom) - -// Core FFI functions void ffi_load(JSContext *js); -int js_print_exception(JSContext *js, JSValue v); - -// Global trace flag -extern int trace; - -// Common type definitions - rect and colorf are defined in render.h - -// Common conversion functions used across modules -JSValue rect2js(JSContext *js, rect r); -JSValue vec22js(JSContext *js, HMM_Vec2 v); -JSValue vec32js(JSContext *js, HMM_Vec3 v); -JSValue vec42js(JSContext *js, HMM_Vec4 v); -JSValue quat2js(JSContext *js, HMM_Quat q); -JSValue color2js(JSContext *js, colorf c); -JSValue number2js(JSContext *js, double d); -JSValue angle2js(JSContext *js, double a); - -rect js2rect(JSContext *js, JSValue v); -HMM_Vec2 js2vec2(JSContext *js, JSValue v); -HMM_Vec3 js2vec3(JSContext *js, JSValue v); -HMM_Vec4 js2vec4(JSContext *js, JSValue v); -HMM_Quat js2quat(JSContext *js, JSValue v); -colorf js2color(JSContext *js, JSValue v); -double js2number(JSContext *js, JSValue v); -double js2angle(JSContext *js, JSValue v); - -// Forward declaration for MTRand from prosperon.h -typedef struct tagMTRand MTRand; - -// Random number generation functions -double genRand(MTRand *mrand); -int64_t genRandLong(MTRand *mrand); -void m_seedRand(MTRand *mrand, uint64_t seed); -double rand_range(JSContext *js, double min, double max); - -// Common data structures -struct lrtb { - float l; - float r; - float t; - float b; -}; -typedef struct lrtb lrtb; -typedef struct text_vert text_vert; - -// Common macros for property access -#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -#define JS_GETATOM(JS, TARGET, VALUE, ATOM, TYPE) {\ -JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \ -TARGET = js2##TYPE(JS, __##PROP##__v); \ -JS_FreeValue(JS,__##PROP##__v); }\ - -// Common conversion functions -lrtb js2lrtb(JSContext *js, JSValue v); -int js2bool(JSContext *js, JSValue v); -JSValue make_gpu_buffer(JSContext *js, void *data, size_t size, int type, int elements, int copy, int index); -JSValue make_quad_indices_buffer(JSContext *js, int quads); - -// SDL type conversion functions -SDL_Window *js2SDL_Window(JSContext *js, JSValue v); -JSValue SDL_Window2js(JSContext *js, SDL_Window *w); - -// X-macro enum definition system for string<->enum conversion -#define ENUM_MAPPING_TABLE(ENUM) \ - static const struct { int value; const char *name; } ENUM##_mapping[] - -#define JS2ENUM(NAME) \ -int js2##NAME(JSContext *js, JSValue v) { \ - if (JS_IsNull(v)) return 0; \ - const char *str = JS_ToCString(js, v); \ - if (!str) return 0; \ - for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ - if(!strcmp(NAME##_mapping[i].name, str)) { \ - JS_FreeCString(js, str); \ - return NAME##_mapping[i].value; \ - } \ - JS_FreeCString(js, str); \ - return 0; \ -} \ -JSValue NAME##2js(JSContext *js, int enumval) { \ - for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ - if(NAME##_mapping[i].value == enumval) \ - return JS_NewString(js, NAME##_mapping[i].name); \ - return JS_NULL; \ -} #endif diff --git a/source/qjs_actor.c b/source/qjs_actor.c index a9b5a2d0..f44f176a 100644 --- a/source/qjs_actor.c +++ b/source/qjs_actor.c @@ -1,5 +1,4 @@ #include "qjs_actor.h" -#include "jsffi.h" #include "qjs_macros.h" #include "qjs_wota.h" #include "cell.h" diff --git a/source/qjs_debug.c b/source/qjs_debug.c index 9f959ba0..83a323a9 100644 --- a/source/qjs_debug.c +++ b/source/qjs_debug.c @@ -1,5 +1,5 @@ +#include "cell.h" #include "qjs_macros.h" -#include "jsffi.h" JSC_CCALL(debug_stack_depth, return number2js(js,js_debugger_stack_depth(js))) JSC_CCALL(debug_build_backtrace, return js_debugger_build_backtrace(js,NULL)) diff --git a/source/qjs_fd.c b/source/qjs_fd.c index c985ce4b..89213a82 100644 --- a/source/qjs_fd.c +++ b/source/qjs_fd.c @@ -1,5 +1,4 @@ #include "cell.h" -#include "jsffi.h" #include #include diff --git a/source/qjs_fit.c b/source/qjs_fit.c index b144ab45..845bf1c3 100644 --- a/source/qjs_fit.c +++ b/source/qjs_fit.c @@ -1,4 +1,4 @@ -#include "jsffi.h" +#include "cell.h" #include #include diff --git a/source/qjs_js.c b/source/qjs_js.c index 8f4c530c..3b9bbbfc 100644 --- a/source/qjs_js.c +++ b/source/qjs_js.c @@ -1,4 +1,3 @@ -#include "jsffi.h" #include "cell.h" JSC_CCALL(os_gc, JS_RunGC(JS_GetRuntime(js)) ) diff --git a/source/qjs_kim.c b/source/qjs_kim.c index 7280a5d8..a1460a50 100644 --- a/source/qjs_kim.c +++ b/source/qjs_kim.c @@ -1,5 +1,4 @@ #include "cell.h" -#include "jsffi.h" #include #include diff --git a/source/qjs_macros.h b/source/qjs_macros.h index 7b8218f2..8c1b0b0a 100644 --- a/source/qjs_macros.h +++ b/source/qjs_macros.h @@ -158,3 +158,43 @@ JS_SetClassProto(js, js_##TYPE##_id, TYPE##_proto); \ #define countof(x) (sizeof(x)/sizeof((x)[0])) +// Common macros for property access +#define JS_GETPROP(JS, TARGET, VALUE, PROP, TYPE) {\ +JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#PROP); \ +TARGET = js2##TYPE(JS, __##PROP##__v); \ +JS_FreeValue(JS,__##PROP##__v); }\ + +#define JS_GETATOM(JS, TARGET, VALUE, ATOM, TYPE) {\ +JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \ +TARGET = js2##TYPE(JS, __##PROP##__v); \ +JS_FreeValue(JS,__##PROP##__v); }\ + +// X-macro enum definition system for string<->enum conversion +#define ENUM_MAPPING_TABLE(ENUM) \ + static const struct { int value; const char *name; } ENUM##_mapping[] + +#define JS2ENUM(NAME) \ +int js2##NAME(JSContext *js, JSValue v) { \ + if (JS_IsNull(v)) return 0; \ + const char *str = JS_ToCString(js, v); \ + if (!str) return 0; \ + for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ + if(!strcmp(NAME##_mapping[i].name, str)) { \ + JS_FreeCString(js, str); \ + return NAME##_mapping[i].value; \ + } \ + JS_FreeCString(js, str); \ + return 0; \ +} \ +JSValue NAME##2js(JSContext *js, int enumval) { \ + for(int i = 0; i < sizeof(NAME##_mapping)/sizeof(NAME##_mapping[0]); i++) \ + if(NAME##_mapping[i].value == enumval) \ + return JS_NewString(js, NAME##_mapping[i].name); \ + return JS_NULL; \ +} + +#define CELL_USE_FUNCS(FUNCS) \ +JSValue CELL_USE_NAME(JSContext *js) { \ + JSValue mod = JS_NewObject(js); \ + JS_SetPropertyFunctionList(js, mod, FUNCS, countof(FUNCS)); \ + return mod; } diff --git a/source/qjs_math.c b/source/qjs_math.c deleted file mode 100644 index 64b5504b..00000000 --- a/source/qjs_math.c +++ /dev/null @@ -1,491 +0,0 @@ -#include "jsffi.h" -#include "qjs_macros.h" - -#include -#include -#include "HandmadeMath.h" -#include "cell.h" - - -// Utility function to get number from array index -static double js_getnum_uint32(JSContext *js, JSValue v, unsigned int i) -{ - JSValue val = JS_GetPropertyUint32(js,v,i); - double ret = js2number(js, val); - JS_FreeValue(js,val); - return ret; -} - -// Convert JS array to float array -static float *js2floats(JSContext *js, JSValue v, size_t *len) -{ - *len = JS_ArrayLength(js,v); - float *arr = malloc(sizeof(float)* *len); - for (int i = 0; i < *len; i++) - arr[i] = js_getnum_uint32(js,v,i); - return arr; -} - -// Convert float array to JS array -static JSValue floats2array(JSContext *js, float *vals, size_t len) { - JSValue arr = JS_NewArray(js); - for (size_t i = 0; i < len; i++) { - JS_SetPropertyUint32(js, arr, i, number2js(js, vals[i])); - } - return arr; -} - -// Calculate vector length -static double arr_vec_length(JSContext *js,JSValue v) -{ - int len = JS_ArrayLength(js,v); - switch(len) { - case 2: return HMM_LenV2(js2vec2(js,v)); - case 3: return HMM_LenV3(js2vec3(js,v)); - case 4: return HMM_LenV4(js2vec4(js,v)); - } - - double sum = 0; - for (int i = 0; i < len; i++) - sum += pow(js_getnum_uint32(js, v, i), 2); - - return sqrt(sum); -} - - -// GCD helper function -static int gcd(int a, int b) { - if (b == 0) - return a; - return gcd(b, a % b); -} - -// MATH FUNCTIONS - - - -JSC_CCALL(math_rotate, - HMM_Vec2 vec = js2vec2(js,argv[0]); - double angle = js2angle(js, argv[1]); - HMM_Vec2 pivot = JS_IsNull(argv[2]) ? v2zero : js2vec2(js,argv[2]); - vec = HMM_SubV2(vec,pivot); - - float r = HMM_LenV2(vec); - angle += atan2f(vec.y, vec.x); - - vec.x = r * cosf(angle); - vec.y = r * sinf(angle); - - vec = HMM_AddV2(vec,pivot); - - return vec22js(js, vec); -) - -JSC_CCALL(math_norm, - int len = JS_ArrayLength(js,argv[0]); - - switch(len) { - case 2: return vec22js(js,HMM_NormV2(js2vec2(js,argv[0]))); - case 3: return vec32js(js, HMM_NormV3(js2vec3(js,argv[0]))); - case 4: return vec42js(js,HMM_NormV4(js2vec4(js,argv[0]))); - } - - double length = arr_vec_length(js,argv[0]); - JSValue newarr = JS_NewArray(js); - - for (int i = 0; i < len; i++) - JS_SetPropertyUint32(js, newarr, i, number2js(js,js_getnum_uint32(js, argv[0],i)/length)); - - ret = newarr; -) - -JSC_CCALL(math_angle_between, - int len = JS_ArrayLength(js,argv[0]); - switch(len) { - case 2: return angle2js(js,HMM_AngleV2(js2vec2(js,argv[0]), js2vec2(js,argv[1]))); - case 3: return angle2js(js,HMM_AngleV3(js2vec3(js,argv[0]), js2vec3(js,argv[1]))); - case 4: return angle2js(js,HMM_AngleV4(js2vec4(js,argv[0]), js2vec4(js,argv[1]))); - } - return JS_ThrowReferenceError(js, "Input array must have a length between 2 and 4."); -) - -JSC_CCALL(math_lerp, - double s = js2number(js,argv[0]); - double f = js2number(js,argv[1]); - double t = js2number(js,argv[2]); - - ret = number2js(js,(f-s)*t+s); -) - -JSC_CCALL(math_gcd, ret = number2js(js,gcd(js2number(js,argv[0]), js2number(js,argv[1]))); ) - -JSC_CCALL(math_lcm, - double a = js2number(js,argv[0]); - double b = js2number(js,argv[1]); - ret = number2js(js,(a*b)/gcd(a,b)); -) - -JSC_CCALL(math_clamp, - double x = js2number(js,argv[0]); - double l = js2number(js,argv[1]); - double h = js2number(js,argv[2]); - return number2js(js,x > h ? h : x < l ? l : x); -) - -JSC_CCALL(math_angledist, - double a1 = js2number(js,argv[0]); - double a2 = js2number(js,argv[1]); - a1 = fmod(a1,1); - a2 = fmod(a2,1); - double dist = a2-a1; - if (dist == 0) return number2js(js,dist); - if (dist > 0) { - if (dist > 0.5) return number2js(js,dist-1); - return number2js(js,dist); - } - - if (dist < -0.5) return number2js(js,dist+1); - - return number2js(js,dist); -) - -JSC_CCALL(math_jitter, - double n = js2number(js,argv[0]); - double pct = js2number(js,argv[1]); - - return number2js(js,n + (rand_range(js,-pct,pct)*n)); -) - -JSC_CCALL(math_mean, - double len = JS_ArrayLength(js,argv[0]); - double sum = 0; - for (int i = 0; i < len; i++) - sum += js_getnum_uint32(js, argv[0], i); - - return number2js(js,sum/len); -) - -JSC_CCALL(math_sum, - double sum = 0.0; - int len = JS_ArrayLength(js,argv[0]); - for (int i = 0; i < len; i++) - sum += js_getnum_uint32(js, argv[0], i); - - return number2js(js,sum); -) - -JSC_CCALL(math_sigma, - int len = JS_ArrayLength(js,argv[0]); - double sum = 0; - for (int i = 0; i < len; i++) - sum += js_getnum_uint32(js, argv[0], i); - - double mean = sum/(double)len; - sum = 0; - for (int i = 0; i < len; i++) - sum += pow(js_getnum_uint32(js, argv[0], i) - mean, 2); - - return number2js(js,sqrt(sum/len)); -) - -JSC_CCALL(math_median, - int len = JS_ArrayLength(js,argv[0]); - double vals[len]; - for (int i = 0; i < len; i++) - vals[i] = js_getnum_uint32(js, argv[0], i); - - // Simple bubble sort for median calculation - for (int i = 0; i < len-1; i++) { - for (int j = 0; j < len-i-1; j++) { - if (vals[j] > vals[j+1]) { - double temp = vals[j]; - vals[j] = vals[j+1]; - vals[j+1] = temp; - } - } - } - - if (len % 2 == 0) - return number2js(js,(vals[len/2-1] + vals[len/2]) / 2.0); - else - return number2js(js,vals[len/2]); -) - -JSC_CCALL(math_length, return number2js(js,arr_vec_length(js,argv[0])); ) - -JSC_CCALL(math_from_to, - double start = js2number(js,argv[0]); - double end = js2number(js,argv[1]); - double step = js2number(js,argv[2]); - int inclusive = JS_ToBool(js,argv[3]); - int arr = JS_ToBool(js,argv[4]); - - JSValue jsarr = JS_NewArray(js); - int i = 0; - for (double val = start; val <= end; val += step) { - if (val == end && !inclusive) break; - JS_SetPropertyUint32(js, jsarr, i++, number2js(js, val)); - } - - return jsarr; -) - - -JSC_CCALL(math_dot, - size_t alen, blen; - float *a = js2floats(js,argv[0], &alen); - float *b = js2floats(js,argv[1], &blen); - float dot = 0; - size_t len = alen < blen? alen : blen; - for (size_t i = 0; i < len; i++) - dot += a[i] * b[i]; - - free(a); - free(b); - return number2js(js,dot); -) - -JSC_CCALL(math_project, - size_t alen, blen; - float *a = js2floats(js, argv[0], &alen); - float *b = js2floats(js, argv[1], &blen); - - if (!a || !b) { - free(a); - free(b); - return JS_NULL; - } - - // We'll work up to the smaller length - size_t len = (alen < blen) ? alen : blen; - if (len == 0) { - free(a); - free(b); - return JS_NULL; - } - - // Compute dot products: a·b and b·b - float ab = 0, bb = 0; - for (size_t i = 0; i < len; i++) { - ab += a[i] * b[i]; - bb += b[i] * b[i]; - } - - // Build the result array - float *proj = (float*)malloc(sizeof(float) * len); - if (!proj) { - free(a); - free(b); - return JS_EXCEPTION; // or some error - } - - float scale = (bb != 0.0f) ? (ab / bb) : 0.0f; - for (size_t i = 0; i < len; i++) - proj[i] = scale * b[i]; - - ret = floats2array(js, proj, len); - - free(a); - free(b); - free(proj); -) - -JSC_CCALL(math_midpoint, - size_t alen, blen; - float *a = js2floats(js, argv[0], &alen); - float *b = js2floats(js, argv[1], &blen); - - if (!a || !b) { - free(a); - free(b); - return JS_NULL; - } - - size_t len = (alen < blen) ? alen : blen; - if (len == 0) { - free(a); - free(b); - return JS_NULL; - } - - float *m = (float*)malloc(sizeof(float) * len); - if (!m) { - free(a); - free(b); - return JS_EXCEPTION; - } - - for (size_t i = 0; i < len; i++) - m[i] = (a[i] + b[i]) * 0.5f; - - ret = floats2array(js, m, len); - - free(a); - free(b); - free(m); -) - -JSC_CCALL(math_reflect, - size_t alen, blen; - float *a = js2floats(js, argv[0], &alen); - float *b = js2floats(js, argv[1], &blen); - - if (!a || !b) { - free(a); - free(b); - return JS_NULL; - } - - size_t len = (alen < blen) ? alen : blen; - if (len == 0) { - free(a); - free(b); - return JS_NULL; - } - - // Reflect vector a across normal b - // reflection = a - 2 * (a·b) * b - float ab = 0, bb = 0; - for (size_t i = 0; i < len; i++) { - ab += a[i] * b[i]; - bb += b[i] * b[i]; - } - - float *result = (float*)malloc(sizeof(float) * len); - if (!result) { - free(a); - free(b); - return JS_EXCEPTION; - } - - float scale = (bb != 0.0f) ? (2.0f * ab / bb) : 0.0f; - for (size_t i = 0; i < len; i++) - result[i] = a[i] - scale * b[i]; - - ret = floats2array(js, result, len); - - free(a); - free(b); - free(result); -) - -JSC_CCALL(math_direction, - size_t alen, blen; - float *a = js2floats(js, argv[0], &alen); - float *b = js2floats(js, argv[1], &blen); - - if (!a || !b) { - free(a); - free(b); - return JS_NULL; - } - - size_t len = (alen < blen) ? alen : blen; - if (len == 0) { - free(a); - free(b); - return JS_NULL; - } - - // Direction vector from a to b (normalized) - float *dir = (float*)malloc(sizeof(float) * len); - if (!dir) { - free(a); - free(b); - return JS_EXCEPTION; - } - - float mag = 0; - for (size_t i = 0; i < len; i++) { - dir[i] = b[i] - a[i]; - mag += dir[i] * dir[i]; - } - - mag = sqrtf(mag); - if (mag > 0.0f) { - for (size_t i = 0; i < len; i++) - dir[i] /= mag; - } - - ret = floats2array(js, dir, len); - - free(a); - free(b); - free(dir); -) - -JSC_CCALL(math_angle, - size_t len; - float *v = js2floats(js, argv[0], &len); - - if (!v || len < 2) { - free(v); - return JS_NULL; - } - - // Return angle in radians for 2D vector - ret = number2js(js, atan2f(v[1], v[0])); - - free(v); -) - -JSC_CCALL(math_distance, - size_t alen, blen; - float *a = js2floats(js, argv[0], &alen); - float *b = js2floats(js, argv[1], &blen); - - if (!a || !b) { - free(a); - free(b); - return JS_NULL; - } - - size_t len = (alen < blen) ? alen : blen; - if (len == 0) { - free(a); - free(b); - return JS_NULL; - } - - float distSq = 0.0f; - for (size_t i = 0; i < len; i++) { - float diff = b[i] - a[i]; - distSq += diff * diff; - } - float dist = sqrtf(distSq); - - free(a); - free(b); - return number2js(js, dist); -) - -static const JSCFunctionListEntry js_math_funcs[] = { - MIST_FUNC_DEF(math, dot,2), - MIST_FUNC_DEF(math, project,2), - MIST_FUNC_DEF(math, rotate, 3), - MIST_FUNC_DEF(math, midpoint, 2), - MIST_FUNC_DEF(math, reflect, 2), - MIST_FUNC_DEF(math, distance, 2), - MIST_FUNC_DEF(math, direction, 2), - MIST_FUNC_DEF(math, angle, 1), - MIST_FUNC_DEF(math, norm, 1), - MIST_FUNC_DEF(math, angle_between, 2), - MIST_FUNC_DEF(math, lerp, 3), - MIST_FUNC_DEF(math, gcd, 2), - MIST_FUNC_DEF(math, lcm, 2), - MIST_FUNC_DEF(math, clamp, 3), - MIST_FUNC_DEF(math, angledist, 2), - MIST_FUNC_DEF(math, jitter, 2), - MIST_FUNC_DEF(math, mean, 1), - MIST_FUNC_DEF(math, sum, 1), - MIST_FUNC_DEF(math, sigma, 1), - MIST_FUNC_DEF(math, median, 1), - MIST_FUNC_DEF(math, length, 1), - MIST_FUNC_DEF(math, from_to, 5), -}; - -JSValue js_math_use(JSContext *js) { - JSValue mod = JS_NewObject(js); - JS_SetPropertyFunctionList(js,mod,js_math_funcs,countof(js_math_funcs)); - return mod; -} diff --git a/source/qjs_os.c b/source/qjs_os.c index bb85f195..bec4b7d5 100644 --- a/source/qjs_os.c +++ b/source/qjs_os.c @@ -1,6 +1,4 @@ #include "cell.h" -#include "jsffi.h" -#include "qjs_common.h" #include #include @@ -271,6 +269,16 @@ JSC_CCALL(os_trace_message, ) #endif +JSC_SCALL(os_system, + int err = system(str); + ret = number2js(js,err); +) + +JSC_SCALL(os_exit, + printf("exit\n"); + exit(0); +) + static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, platform, 0), MIST_FUNC_DEF(os, arch, 0), @@ -284,6 +292,8 @@ static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, mallinfo, 0), MIST_FUNC_DEF(os, buffer2string, 1), MIST_FUNC_DEF(os, frame, 0), + MIST_FUNC_DEF(os, system, 1), + MIST_FUNC_DEF(os, exit, 0), }; JSValue js_os_use(JSContext *js) { diff --git a/source/qjs_qop.c b/source/qjs_qop.c index daff457e..9988b2b8 100644 --- a/source/qjs_qop.c +++ b/source/qjs_qop.c @@ -1,6 +1,5 @@ #include "qop.h" #include "cell.h" -#include "jsffi.h" static JSClassID js_qop_archive_class_id; diff --git a/source/qjs_socket.c b/source/qjs_socket.c index b859922b..8e1cb906 100644 --- a/source/qjs_socket.c +++ b/source/qjs_socket.c @@ -1,5 +1,4 @@ #include "cell.h" -#include "jsffi.h" #ifdef _WIN32 #include diff --git a/source/qjs_soloud.c b/source/qjs_soloud.c index 311f7f85..09c99d6d 100644 --- a/source/qjs_soloud.c +++ b/source/qjs_soloud.c @@ -35,30 +35,6 @@ static JSClassDef js_##TYPE##_class = { \ JS_FreeValue(js, tmp); \ } \ -static double js2number(JSContext *js, JSValue v) -{ - double ret; - JS_ToFloat64(js, &ret, v); - return ret; -} - -static JSValue number2js(JSContext *js, double num) -{ - return JS_NewFloat64(js, num); -} - -static int js2bool(JSContext *js, JSValue v) -{ - int b; - JS_ToInt32(js, &b, v); - return b; -} - -static JSValue bool2js(JSContext *js, int b) -{ - return JS_NewBool(js,b); -} - typedef unsigned int voice; static Soloud *soloud; diff --git a/source/qjs_utf8.c b/source/qjs_utf8.c index 4ee0860c..6475621a 100644 --- a/source/qjs_utf8.c +++ b/source/qjs_utf8.c @@ -1,5 +1,4 @@ #include "cell.h" -#include "jsffi.h" #include #include diff --git a/source/qjs_wildstar.c b/source/qjs_wildstar.c index 803ad4a9..23ea7cc0 100644 --- a/source/qjs_wildstar.c +++ b/source/qjs_wildstar.c @@ -1,5 +1,5 @@ +#include "cell.h" #include "wildmatch.h" -#include "jsffi.h" #include "qjs_macros.h" JSC_CCALL(wildstar_match, diff --git a/tangletart.bat b/tangletart.bat deleted file mode 100644 index 9f38e8e7..00000000 --- a/tangletart.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -"%~dp0cell.exe" accio -pause