typedef & PascalCase for ALL structs and enums
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
typedef struct play_audio_args {
|
||||
typedef struct PlayAudioArgs {
|
||||
/* default: false */
|
||||
bool repeat;
|
||||
/* crossfade between already playing audio on a given channel, if any */
|
||||
@ -18,21 +18,21 @@ typedef struct play_audio_args {
|
||||
/* range: -1.0 to 1.0f */
|
||||
/* default: 0.0f */
|
||||
float panning;
|
||||
} t_play_audio_args;
|
||||
} PlayAudioArgs;
|
||||
|
||||
|
||||
/* plays audio file at specified channel or anywhere if NULL is passed */
|
||||
/* path must contain valid file extension to infer which file format it is */
|
||||
/* supported formats: .ogg, .xm */
|
||||
/* preserves args that are already specified on the channel */
|
||||
TWN_API void play_audio(const char *path, const char *channel);
|
||||
TWN_API void audio_play(const char *path, const char *channel);
|
||||
|
||||
TWN_API void play_audio_ex(const char *path, const char *channel, t_play_audio_args args);
|
||||
TWN_API void audio_play_ex(const char *path, const char *channel, PlayAudioArgs args);
|
||||
|
||||
/* could be used for modifying args */
|
||||
/* warn: is only valid if no other calls to audio are made */
|
||||
TWN_API t_play_audio_args *get_audio_args(const char *channel);
|
||||
TWN_API PlayAudioArgs *audio_get_args(const char *channel);
|
||||
|
||||
TWN_API t_play_audio_args get_default_audio_args(void);
|
||||
TWN_API PlayAudioArgs audio_get_default_args(void);
|
||||
|
||||
#endif
|
||||
|
@ -8,15 +8,15 @@
|
||||
/* for example, perspective matrix only needs recaluclation on FOV change */
|
||||
|
||||
/* first person camera class */
|
||||
typedef struct camera {
|
||||
t_fvec3 pos; /* eye position */
|
||||
t_fvec3 target; /* normalized target vector */
|
||||
t_fvec3 up; /* normalized up vector */
|
||||
typedef struct Camera {
|
||||
Vec3 pos; /* eye position */
|
||||
Vec3 target; /* normalized target vector */
|
||||
Vec3 up; /* normalized up vector */
|
||||
float fov; /* field of view, in radians */
|
||||
} t_camera;
|
||||
} Camera;
|
||||
|
||||
TWN_API t_matrix4 camera_look_at(const t_camera *camera);
|
||||
TWN_API Matrix4 camera_look_at(const Camera *camera);
|
||||
|
||||
TWN_API t_matrix4 camera_perspective(const t_camera *const camera);
|
||||
TWN_API Matrix4 camera_perspective(const Camera *const camera);
|
||||
|
||||
#endif
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef struct context {
|
||||
struct input_state input;
|
||||
typedef struct Context {
|
||||
struct InputState input;
|
||||
|
||||
int64_t delta_time; /* preserves real time frame delta with no manipilation */
|
||||
uint64_t tick_count;
|
||||
@ -31,10 +31,10 @@ typedef struct context {
|
||||
bool is_running;
|
||||
bool window_size_has_changed;
|
||||
bool initialization_needed;
|
||||
} t_ctx;
|
||||
} Context;
|
||||
|
||||
#ifndef TWN_ENGINE_CONTEXT_C_H
|
||||
TWN_API extern t_ctx ctx;
|
||||
TWN_API extern Context ctx;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -12,16 +12,16 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
enum button_source {
|
||||
typedef enum ButtonSource {
|
||||
BUTTON_SOURCE_NOT_SET,
|
||||
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
||||
BUTTON_SOURCE_KEYBOARD_CHARACTER,
|
||||
BUTTON_SOURCE_GAMEPAD,
|
||||
BUTTON_SOURCE_MOUSE,
|
||||
};
|
||||
} ButtonSource;
|
||||
|
||||
|
||||
union button_code {
|
||||
union ButtonCode {
|
||||
SDL_Scancode scancode;
|
||||
SDL_Keycode keycode;
|
||||
SDL_GameControllerButton gamepad_button;
|
||||
@ -31,71 +31,71 @@ union button_code {
|
||||
|
||||
/* an input to which an action is bound */
|
||||
/* it is not limited to literal buttons */
|
||||
struct button {
|
||||
enum button_source source;
|
||||
union button_code code;
|
||||
};
|
||||
typedef struct Button {
|
||||
enum ButtonSource source;
|
||||
union ButtonCode code;
|
||||
} Button;
|
||||
|
||||
|
||||
/* represents the collective state of a group of buttons */
|
||||
/* that is, changes in the states of any of the bound buttons will affect it */
|
||||
struct action {
|
||||
typedef struct Action {
|
||||
size_t num_bindings;
|
||||
|
||||
/* if you bind more than NUM_KEYBIND_SLOTS (set in config.h) */
|
||||
/* it forgets the first button to add the new one at the end */
|
||||
struct button bindings[NUM_KEYBIND_SLOTS];
|
||||
/* it forgets the first Button to add the new one at the end */
|
||||
Button bindings[NUM_KEYBIND_SLOTS];
|
||||
|
||||
t_fvec2 position; /* set if applicable, e.g. mouse click */
|
||||
Vec2 position; /* set if applicable, e.g. mouse click */
|
||||
bool is_pressed;
|
||||
bool just_changed;
|
||||
};
|
||||
} Action;
|
||||
|
||||
|
||||
struct action_hash_item {
|
||||
typedef struct ActionHashItem {
|
||||
char *key;
|
||||
struct action value;
|
||||
};
|
||||
Action value;
|
||||
} ActionHashItem;
|
||||
|
||||
|
||||
struct input_state {
|
||||
struct action_hash_item *action_hash;
|
||||
typedef struct InputState {
|
||||
ActionHashItem *action_hash;
|
||||
const uint8_t *keyboard_state; /* array of booleans indexed by scancode */
|
||||
uint32_t mouse_state; /* SDL mouse button bitmask */
|
||||
t_vec2 mouse_window_position;
|
||||
t_vec2 mouse_relative_position;
|
||||
enum button_source last_active_source;
|
||||
Vec2i mouse_window_position;
|
||||
Vec2i mouse_relative_position;
|
||||
ButtonSource last_active_source;
|
||||
bool is_anything_just_pressed;
|
||||
};
|
||||
} InputState;
|
||||
|
||||
|
||||
TWN_API void input_state_init(struct input_state *input);
|
||||
TWN_API void input_state_deinit(struct input_state *input);
|
||||
TWN_API void input_state_update(struct input_state *input);
|
||||
TWN_API void input_state_init(InputState *input);
|
||||
TWN_API void input_state_deinit(InputState *input);
|
||||
TWN_API void input_state_update(InputState *input);
|
||||
|
||||
TWN_API void input_bind_action_scancode(struct input_state *input,
|
||||
TWN_API void input_bind_action_scancode(InputState *input,
|
||||
char *action_name,
|
||||
SDL_Scancode scancode);
|
||||
TWN_API void input_unbind_action_scancode(struct input_state *input,
|
||||
TWN_API void input_unbind_action_scancode(InputState *input,
|
||||
char *action_name,
|
||||
SDL_Scancode scancode);
|
||||
TWN_API void input_bind_action_mouse(struct input_state *input,
|
||||
TWN_API void input_bind_action_mouse(InputState *input,
|
||||
char *action_name,
|
||||
uint8_t mouse_button);
|
||||
TWN_API void input_unbind_action_mouse(struct input_state *input,
|
||||
TWN_API void input_unbind_action_mouse(InputState *input,
|
||||
char *action_name,
|
||||
uint8_t mouse_button);
|
||||
|
||||
TWN_API void input_add_action(struct input_state *input, char *action_name);
|
||||
TWN_API void input_delete_action(struct input_state *input, char *action_name);
|
||||
TWN_API void input_add_action(InputState *input, char *action_name);
|
||||
TWN_API void input_delete_action(InputState *input, char *action_name);
|
||||
|
||||
TWN_API bool input_is_action_pressed(struct input_state *input, char *action_name);
|
||||
TWN_API bool input_is_action_just_pressed(struct input_state *input, char *action_name);
|
||||
TWN_API bool input_is_action_just_released(struct input_state *input, char *action_name);
|
||||
TWN_API bool input_is_action_pressed(InputState *input, char *action_name);
|
||||
TWN_API bool input_is_action_just_pressed(InputState *input, char *action_name);
|
||||
TWN_API bool input_is_action_just_released(InputState *input, char *action_name);
|
||||
|
||||
TWN_API t_fvec2 input_get_action_position(struct input_state *input, char *action_name);
|
||||
TWN_API Vec2 input_get_action_position(InputState *input, char *action_name);
|
||||
|
||||
TWN_API void input_set_mouse_captured(struct input_state *input, bool value);
|
||||
TWN_API bool input_is_mouse_captured(struct input_state *input);
|
||||
TWN_API void input_set_mouse_captured(InputState *input, bool value);
|
||||
TWN_API bool input_is_mouse_captured(InputState *input);
|
||||
|
||||
#endif
|
||||
|
@ -10,67 +10,67 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct push_sprite_args {
|
||||
typedef struct PushSpriteArgs {
|
||||
char *path;
|
||||
t_frect rect;
|
||||
Rect rect;
|
||||
|
||||
m_option_list(
|
||||
t_frect, texture_region,
|
||||
t_color, color,
|
||||
Rect, texture_region,
|
||||
Color, color,
|
||||
float, rotation,
|
||||
bool, flip_x,
|
||||
bool, flip_y,
|
||||
bool, stretch )
|
||||
} t_push_sprite_args;
|
||||
} PushSpriteArgs;
|
||||
|
||||
/* pushes a sprite onto the sprite render queue */
|
||||
/* this is a simplified version of push_sprite_ex for the most common case. */
|
||||
/* it assumes you want no color modulation, no rotation, no flip */
|
||||
TWN_API void push_sprite(t_push_sprite_args args);
|
||||
#define m_sprite(...) (push_sprite((t_push_sprite_args){__VA_ARGS__}))
|
||||
TWN_API void push_sprite(PushSpriteArgs args);
|
||||
#define m_sprite(...) (push_sprite((PushSpriteArgs){__VA_ARGS__}))
|
||||
|
||||
/* pushes a filled rectangle onto the rectangle render queue */
|
||||
TWN_API void push_rectangle(t_frect rect, t_color color);
|
||||
TWN_API void push_rectangle(Rect rect, Color color);
|
||||
|
||||
/* pushes a filled circle onto the circle render queue */
|
||||
TWN_API void push_circle(t_fvec2 position, float radius, t_color color);
|
||||
TWN_API void push_circle(Vec2 position, float radius, Color color);
|
||||
|
||||
TWN_API void push_text(char *string, t_fvec2 position, int height_px, t_color color, const char *font_path);
|
||||
TWN_API void push_text(char *string, Vec2 position, int height_px, Color color, const char *font_path);
|
||||
TWN_API int get_text_width(char *string, int height_px, const char *font_path);
|
||||
|
||||
/* pushes a textured 3d triangle onto the render queue */
|
||||
/* vertices are in absolute coordinates, relative to world origin */
|
||||
/* texture coordinates are in pixels */
|
||||
TWN_API void unfurl_triangle(const char *path,
|
||||
t_fvec3 v0,
|
||||
t_fvec3 v1,
|
||||
t_fvec3 v2,
|
||||
t_shvec2 uv0,
|
||||
t_shvec2 uv1,
|
||||
t_shvec2 uv2);
|
||||
Vec3 v0,
|
||||
Vec3 v1,
|
||||
Vec3 v2,
|
||||
Vec2sh uv0,
|
||||
Vec2sh uv1,
|
||||
Vec2sh uv2);
|
||||
|
||||
// TODO: decide whether it's needed to begin with?
|
||||
// intended usage for it is baked lighting, i would think.
|
||||
/* pushes a colored textured 3d triangle onto the render queue */
|
||||
// void unfurl_colored_triangle(const char *path,
|
||||
// t_fvec3 v0,
|
||||
// t_fvec3 v1,
|
||||
// t_fvec3 v2,
|
||||
// t_shvec2 uv0,
|
||||
// t_shvec2 uv1,
|
||||
// t_shvec2 uv2,
|
||||
// t_color c0,
|
||||
// t_color c1,
|
||||
// t_color c2);
|
||||
// Vec3 v0,
|
||||
// Vec3 v1,
|
||||
// Vec3 v2,
|
||||
// Vec2sh uv0,
|
||||
// Vec2sh uv1,
|
||||
// Vec2sh uv2,
|
||||
// Color c0,
|
||||
// Color c1,
|
||||
// Color c2);
|
||||
|
||||
// TODO:
|
||||
// http://www.lighthouse3d.com/opengl/billboarding/index.php?billCheat2
|
||||
// void unfurl_billboard(const char *path,
|
||||
// t_fvec3 position,
|
||||
// t_fvec2 scaling,
|
||||
// t_frect uvs);
|
||||
// Vec2 position,
|
||||
// Vec2 scaling,
|
||||
// Rect uvs);
|
||||
|
||||
/* pushes a camera state to be used for all future unfurl_* commands */
|
||||
TWN_API void set_camera(const t_camera *camera);
|
||||
TWN_API void set_camera(const Camera *camera);
|
||||
|
||||
#endif
|
||||
|
@ -2,10 +2,10 @@
|
||||
#define TWN_TEXTURES_MODES_H
|
||||
|
||||
/* alpha channel information */
|
||||
enum texture_mode {
|
||||
typedef enum TextureMode {
|
||||
TEXTURE_MODE_OPAQUE, /* all pixels are solid */
|
||||
TEXTURE_MODE_SEETHROUGH, /* some pixels are alpha zero */
|
||||
TEXTURE_MODE_GHOSTLY, /* arbitrary alpha values */
|
||||
};
|
||||
} TextureMode;
|
||||
|
||||
#endif
|
||||
|
@ -80,54 +80,54 @@ TWN_API TWN_API bool strends(const char *str, const char *suffix);
|
||||
/* */
|
||||
|
||||
/* 32-bit color data */
|
||||
typedef struct color {
|
||||
typedef struct Color {
|
||||
_Alignas(4)
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
} t_color;
|
||||
} Color;
|
||||
|
||||
|
||||
/* a rectangle with the origin at the upper left (integer) */
|
||||
typedef struct rect {
|
||||
typedef struct Recti {
|
||||
_Alignas(16)
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t w;
|
||||
int32_t h;
|
||||
} t_rect;
|
||||
} Recti;
|
||||
|
||||
|
||||
/* a rectangle with the origin at the upper left (floating point) */
|
||||
typedef struct frect {
|
||||
typedef struct Rect {
|
||||
_Alignas(16)
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
} t_frect;
|
||||
} Rect;
|
||||
|
||||
|
||||
/* calculates the overlap of two rectangles and places it in result. */
|
||||
/* result may be NULL. if this is the case, it will simply be ignored. */
|
||||
/* returns true if the rectangles are indeed intersecting. */
|
||||
TWN_API bool overlap_rect(const t_rect *a, const t_rect *b, t_rect *result);
|
||||
TWN_API bool overlap_frect(const t_frect *a, const t_frect *b, t_frect *result);
|
||||
TWN_API bool overlap_rect(const Recti *a, const Recti *b, Recti *result);
|
||||
TWN_API bool overlap_frect(const Rect *a, const Rect *b, Rect *result);
|
||||
|
||||
/* returns true if two rectangles are intersecting */
|
||||
TWN_API bool intersect_rect(const t_rect *a, const t_rect *b);
|
||||
TWN_API bool intersect_frect(const t_frect *a, const t_frect *b);
|
||||
TWN_API bool intersect_rect(const Recti *a, const Recti *b);
|
||||
TWN_API bool intersect_frect(const Rect *a, const Rect *b);
|
||||
|
||||
/* TODO: generics and specials (see m_to_fvec2() for an example)*/
|
||||
TWN_API t_frect to_frect(t_rect rect);
|
||||
/* TODO: generics and specials (see m_vec2_from() for an example)*/
|
||||
TWN_API Rect to_frect(Recti rect);
|
||||
|
||||
TWN_API t_fvec2 frect_center(t_frect rect);
|
||||
TWN_API Vec2 frect_center(Rect rect);
|
||||
|
||||
|
||||
typedef struct matrix4 {
|
||||
t_fvec4 row[4];
|
||||
} t_matrix4;
|
||||
typedef struct Matrix4 {
|
||||
Vec4 row[4];
|
||||
} Matrix4;
|
||||
|
||||
|
||||
/* decrements an lvalue (which should be an int), stopping at 0 */
|
||||
@ -162,9 +162,9 @@ static inline float fast_sqrt(float x)
|
||||
}
|
||||
|
||||
|
||||
static inline t_fvec2 fast_cossine(float a) {
|
||||
static inline Vec2 fast_cossine(float a) {
|
||||
const float s = sinf(a);
|
||||
return (t_fvec2){
|
||||
return (Vec2){
|
||||
.x = fast_sqrt(1.0f - s * s) * (a >= (float)M_PI_2 && a < (float)(M_PI + M_PI_2) ? -1 : 1),
|
||||
.y = s
|
||||
};
|
||||
|
@ -6,92 +6,92 @@
|
||||
|
||||
|
||||
/* a point in some space (integer) */
|
||||
typedef struct vec2 {
|
||||
typedef struct Vec2i {
|
||||
_Alignas(8)
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} t_vec2;
|
||||
} Vec2i;
|
||||
|
||||
|
||||
/* a point in some space (floating point) */
|
||||
typedef struct fvec2 {
|
||||
typedef struct Vec2 {
|
||||
_Alignas(8)
|
||||
float x;
|
||||
float y;
|
||||
} t_fvec2;
|
||||
} Vec2;
|
||||
|
||||
|
||||
/* a point in some three dimension space (floating point) */
|
||||
/* y goes up, x goes to the right */
|
||||
typedef struct fvec3 {
|
||||
typedef struct Vec3 {
|
||||
_Alignas(16)
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} t_fvec3;
|
||||
} Vec3;
|
||||
|
||||
|
||||
/* a point in some three dimension space (floating point) */
|
||||
/* y goes up, x goes to the right */
|
||||
typedef struct fvec4 {
|
||||
typedef struct Vec4 {
|
||||
_Alignas(16)
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
} t_fvec4;
|
||||
} Vec4;
|
||||
|
||||
|
||||
/* a point in some space (short) */
|
||||
typedef struct shvec2 {
|
||||
typedef struct Vec2sh {
|
||||
_Alignas(4)
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} t_shvec2;
|
||||
} Vec2sh;
|
||||
|
||||
|
||||
/* aren't macros to prevent double evaluation with side effects */
|
||||
/* maybe could be inlined? i hope LTO will resolve this */
|
||||
static inline t_fvec2 fvec2_from_vec2(t_vec2 vec) {
|
||||
return (t_fvec2) {
|
||||
static inline Vec2 vec2_from_vec2i(Vec2i vec) {
|
||||
return (Vec2) {
|
||||
.x = (float)vec.x,
|
||||
.y = (float)vec.y,
|
||||
};
|
||||
}
|
||||
|
||||
static inline t_fvec2 fvec2_from_shvec2(t_shvec2 vec) {
|
||||
return (t_fvec2) {
|
||||
static inline Vec2 vec2_from_vec2sh(Vec2sh vec) {
|
||||
return (Vec2) {
|
||||
.x = (float)vec.x,
|
||||
.y = (float)vec.y,
|
||||
};
|
||||
}
|
||||
|
||||
static inline t_fvec3 fvec3_add(t_fvec3 a, t_fvec3 b) {
|
||||
return (t_fvec3) { a.x + b.x, a.y + b.y, a.z + b.z };
|
||||
static inline Vec3 vec3_add(Vec3 a, Vec3 b) {
|
||||
return (Vec3) { a.x + b.x, a.y + b.y, a.z + b.z };
|
||||
}
|
||||
|
||||
static inline t_fvec3 fvec3_sub(t_fvec3 a, t_fvec3 b) {
|
||||
return (t_fvec3) { a.x - b.x, a.y - b.y, a.z - b.z };
|
||||
static inline Vec3 vec3_sub(Vec3 a, Vec3 b) {
|
||||
return (Vec3) { a.x - b.x, a.y - b.y, a.z - b.z };
|
||||
}
|
||||
|
||||
static inline t_fvec2 fvec2_div(t_fvec2 a, t_fvec2 b) {
|
||||
return (t_fvec2) { a.x / b.x, a.y / b.y };
|
||||
static inline Vec2 vec2_div(Vec2 a, Vec2 b) {
|
||||
return (Vec2) { a.x / b.x, a.y / b.y };
|
||||
}
|
||||
|
||||
static inline t_fvec2 fvec2_scale(t_fvec2 a, float s) {
|
||||
return (t_fvec2) { a.x * s, a.y * s };
|
||||
static inline Vec2 vec2_scale(Vec2 a, float s) {
|
||||
return (Vec2) { a.x * s, a.y * s };
|
||||
}
|
||||
|
||||
static inline t_fvec3 fvec3_scale(t_fvec3 a, float s) {
|
||||
return (t_fvec3) { a.x * s, a.y * s, a.z * s };
|
||||
static inline Vec3 vec3_scale(Vec3 a, float s) {
|
||||
return (Vec3) { a.x * s, a.y * s, a.z * s };
|
||||
}
|
||||
|
||||
static inline float fvec3_dot(t_fvec3 a, t_fvec3 b) {
|
||||
static inline float vec3_dot(Vec3 a, Vec3 b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
static inline t_fvec3 fvec3_cross(t_fvec3 a, t_fvec3 b) {
|
||||
return (t_fvec3) {
|
||||
static inline Vec3 vec3_cross(Vec3 a, Vec3 b) {
|
||||
return (Vec3) {
|
||||
a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x,
|
||||
@ -99,66 +99,66 @@ static inline t_fvec3 fvec3_cross(t_fvec3 a, t_fvec3 b) {
|
||||
}
|
||||
|
||||
/* TODO: fast_sqrt version? */
|
||||
static inline t_fvec3 fvec3_norm(t_fvec3 a) {
|
||||
const float n = sqrtf(fvec3_dot(a, a));
|
||||
static inline Vec3 vec3_norm(Vec3 a) {
|
||||
const float n = sqrtf(vec3_dot(a, a));
|
||||
/* TODO: do we need truncating over epsilon as cglm does? */
|
||||
return fvec3_scale(a, 1.0f / n);
|
||||
return vec3_scale(a, 1.0f / n);
|
||||
}
|
||||
|
||||
static inline t_fvec3 fvec3_rotate(t_fvec3 v, float angle, t_fvec3 axis) {
|
||||
static inline Vec3 vec3_rotate(Vec3 v, float angle, Vec3 axis) {
|
||||
/* from cglm */
|
||||
t_fvec3 v1, v2, k;
|
||||
Vec3 v1, v2, k;
|
||||
float c, s;
|
||||
|
||||
c = cosf(angle);
|
||||
s = sinf(angle);
|
||||
|
||||
k = fvec3_norm(axis);
|
||||
k = vec3_norm(axis);
|
||||
|
||||
/* Right Hand, Rodrigues' rotation formula:
|
||||
v = v*cos(t) + (kxv)sin(t) + k*(k.v)(1 - cos(t))
|
||||
*/
|
||||
v1 = fvec3_scale(v, c);
|
||||
v1 = vec3_scale(v, c);
|
||||
|
||||
v2 = fvec3_cross(k, v);
|
||||
v2 = fvec3_scale(v2, s);
|
||||
v2 = vec3_cross(k, v);
|
||||
v2 = vec3_scale(v2, s);
|
||||
|
||||
v1 = fvec3_add(v1, v2);
|
||||
v1 = vec3_add(v1, v2);
|
||||
|
||||
v2 = fvec3_scale(k, fvec3_dot(k, v) * (1.0f - c));
|
||||
v = fvec3_add(v1, v2);
|
||||
v2 = vec3_scale(k, vec3_dot(k, v) * (1.0f - c));
|
||||
v = vec3_add(v1, v2);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#define m_to_fvec2(p_any_vec2) (_Generic((p_any_vec2), \
|
||||
t_vec2: fvec2_from_vec2, \
|
||||
t_shvec2: fvec2_from_shvec2 \
|
||||
#define m_vec2_from(p_any_vec2) (_Generic((p_any_vec2), \
|
||||
Vec2i: vec2_from_vec2i, \
|
||||
Vec2sh: vec2_from_vec2sh \
|
||||
)(p_any_vec2))
|
||||
|
||||
#define m_vec_sub(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
||||
t_fvec3: fvec3_sub \
|
||||
Vec3: vec3_sub \
|
||||
)(p_any_vec0, p_any_vec1))
|
||||
|
||||
#define m_vec_div(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
||||
t_fvec2: fvec2_div \
|
||||
Vec2: vec2_div \
|
||||
)(p_any_vec0, p_any_vec1))
|
||||
|
||||
#define m_vec_scale(p_any_vec, p_any_scalar) (_Generic((p_any_vec), \
|
||||
t_fvec2: fvec2_scale, \
|
||||
t_fvec3: fvec3_scale \
|
||||
#define m_vec_scale(p_any_vec, p_any_scalar) (_Generic((p_any_vec), \
|
||||
Vec2: vec2_scale, \
|
||||
Vec3: vec3_scale \
|
||||
)(p_any_vec, p_any_scalar))
|
||||
|
||||
#define m_vec_dot(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
||||
t_fvec3: fvec3_dot \
|
||||
Vec3: vec3_dot \
|
||||
)(p_any_vec0, p_any_vec1))
|
||||
|
||||
#define m_vec_cross(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
||||
t_fvec3: fvec3_cross \
|
||||
#define m_vec_cross(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
||||
Vec3: vec3_cross \
|
||||
)(p_any_vec0, p_any_vec1))
|
||||
|
||||
#define m_vec_norm(p_any_vec) (_Generic((p_any_vec), \
|
||||
t_fvec3: fvec3_norm \
|
||||
Vec3: vec3_norm \
|
||||
)(p_any_vec))
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user