#ifndef DEFOCUS_BASE_H #define DEFOCUS_BASE_H #include #include /** @file base.h * @brief basic utilities */ /** @brief Result codes used throughout the codebase */ typedef enum { /** @brief operation successfull */ df_result_success = 0, /** @brief an opengl error occured */ df_result_gl_error = 1, /** @brief memory allocation failed */ df_result_out_of_memory = 2, /** @brief file i/o error */ df_result_io_error = 3, } df_result; /** @brief Used to silence warnings about unused variables */ #define DF_UNUSED(x) ((void)sizeof((x))) /** @brief Evaluates to the number of elements in a static array. */ #define DF_ARRAY_COUNT(a) (sizeof((a)) / sizeof((a)[0])) /** @brief Zero a memory range */ #define DF_ZERO_MEMORY(ptr, n) memset((ptr), 0, (n)) /** @brief Zero a struct */ #define DF_ZERO_STRUCT(ptr) DF_ZERO_MEMORY(ptr, sizeof(*(ptr))) /** @brief Zero an array */ #define DF_ZERO_ARRAY(a, n) DF_ZERO_MEMORY(a, sizeof((a)[0]) * (n)) /* Simple logging function */ #ifndef DF_ENABLE_LOGGING #define DF_ENABLE_LOGGING 1 #endif enum { df_log_level_verbose = 0, df_log_level_info = 1, df_log_level_warn = 2, df_log_level_error = 3, }; #if DF_ENABLE_LOGGING /** @brief The actual log implementation. * * There should be no need to call this directly. * * Instead use one of: * - df_log_verbose() * - df_log_info() * - df_log_warn() * - df_log_error() * @param level the log level. Used to filter the messages. * @param file file name of the log location * @param line line number of the log location * @param fmt format string of the message. */ void df_log_impl(int level, const char *file, int line, const char *fmt, ...); #define df_log_verbose(...) df_log_impl(df_log_level_verbose, __FILE__, __LINE__, __VA_ARGS__) #define df_log_info(...) df_log_impl(df_log_level_info, __FILE__, __LINE__, __VA_ARGS__) #define df_log_warn(...) df_log_impl(df_log_level_warn, __FILE__, __LINE__, __VA_ARGS__) #define df_log_error(...) df_log_impl(df_log_level_error, __FILE__, __LINE__, __VA_ARGS__) #else /* DF_ENABLE_LOGGING = 0 */ #define df_log_verbose(fmt, ...) #define df_log_info(fmt, ...) #define df_log_warn(fmt, ...) #define df_log_error(fmt, ...) #endif /* Basic types */ /** @brief RGBA color */ typedef union { struct { uint8_t r; uint8_t g; uint8_t b; uint8_t a; }; uint8_t e[4]; } df_color; /** @brief Linear interpolation between two colors. * * @param a first color * @param b second color * @param t interpolation factor * @return a + (b - a) * t */ df_color df_lerp_color(df_color a, df_color b, double t); /** @brief 2d vector */ typedef union { struct { float x; float y; }; struct { float u; float v; }; float e[2]; } df_v2; /** @brief 3d vector */ typedef union { struct { float x; float y; float z; }; float e[3]; } df_v3; /** @brief Add two 3d vectors */ df_v3 df_add_v3(df_v3 a, df_v3 b); /** @brief Subtract two 3d vectors */ df_v3 df_sub_v3(df_v3 a, df_v3 b); /** @brief Calculate the dot product of 3d vectors a and b. */ float df_dot_v3(df_v3 a, df_v3 b); /** @brief Multiply a 3d vector with a scalar. */ df_v3 df_mul_v3(float t, df_v3 v); /** @brief Returns the normalized version of a 3d vector v */ df_v3 df_normalize_v3(df_v3 v); /** @brief A plane in 3d space. * * Expressed as the set of all points p for which * dot((p - base), normal) = 0 */ typedef struct { df_v3 base; df_v3 normal; } df_plane; /** @brief A line in 3d space. * * Expressed as the vector equation p = base + t * direction. */ typedef struct { df_v3 base; df_v3 direction; } df_line; /** @brief The three possible result types of a line-plane intersection test. */ typedef enum { /** The line and plane intersect in one point */ df_line_plane_intersection_vector, /** The line is contained in the plane */ df_line_plane_intersection_contained, /** The line and plane don't intersect (-> they are parallel) */ df_line_plane_intersection_none, } df_line_plane_intersection_type; /** @brief Result of a line-plane intersection test. * The contained vector is only valid if @c type = @c df_line_plane_intersection_vector. */ typedef struct { df_line_plane_intersection_type type; df_v3 vec; } df_line_plane_intersection; /** @brief Calculate the intersection between a line and a plane in 3d space */ df_line_plane_intersection df_calc_line_plane_intersection(df_line line, df_plane plane); #endif