#include #include #include #include #include #include #include #define PROGRAM_NAME "Symulator pól elektromagnetycznych" #include #define con_printf printf #define max2(a, b) ((a) > (b) ? (a) : (b)) #define max3(a, b, c) (max2(max2(a, b), c)) #define min2(a, b) ((a) < (b) ? (a) : (b)) #define min3(a, b, c) (min2(min2(a, b), c)) // main char *va(const char *fmt, ...); int64_t get_time(void); // math typedef float vec_t; typedef vec_t vec2_t[2]; typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; typedef vec_t mst2_t[4]; /* mst2_t is a 3x3 scale&translate matrix (only 4 components are needed): * [ dw 0 dx ] * [ 0 dh dy ] * [ 0 0 1 ] */ static inline void v2_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; } static inline void v3_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; R[2] = A[2]; } static inline void v4_copy(vec_t *R, vec_t *A) { R[0] = A[0]; R[1] = A[1]; R[2] = A[2]; R[3] = A[3]; } static inline void v2_set(vec_t *R, vec_t a, vec_t b) { R[0] = a; R[1] = b; } static inline void v3_set(vec_t *R, vec_t a, vec_t b, vec_t c) { R[0] = a; R[1] = b; R[2] = c; } static inline void v2_add(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] + B[0]; R[1] = A[1] + B[1]; } static inline void v2_sub(vec_t *R, vec_t *A, vec_t *B) { R[0] = A[0] - B[0]; R[1] = A[1] - B[1]; } static inline void v2_mul(vec_t *R, vec_t *A, vec_t b) { R[0] = A[0] * b; R[1] = A[1] * b; } static inline void mst2_set_identity(mst2_t R) { R[0] = 0; R[1] = 0; R[2] = 1; R[3] = 1; } static inline void mst2_set(mst2_t R, vec_t dx, vec_t dy, vec_t dw, vec_t dh) { R[0] = dx; R[1] = dy; R[2] = dw; R[3] = dh; } static inline void mst2_inv(mst2_t R, mst2_t A) { mst2_t copy = {A[0], A[1], A[2], A[3]}; R[0] = -copy[0] / copy[2]; R[1] = -copy[1] / copy[3]; R[2] = 1 / copy[2]; R[3] = 1 / copy[3]; } static inline void v2_mul_mst2(vec_t *R, vec_t *A, mst2_t M) { R[0] = M[0] + A[0] * M[2]; R[1] = M[1] + A[1] * M[3]; } static inline void v2_div_mst2(vec_t *R, vec_t *A, mst2_t M) { mst2_t inv; mst2_inv(inv, M); v2_mul_mst2(R, A, inv); } // v2_mul_mst2 but without translation static inline void v2_mul_mst2_nt(vec_t *R, vec_t *A, mst2_t M) { R[0] = A[0] * M[2]; R[1] = A[1] * M[3]; } // v2_div_mst2 but without translation static inline void v2_div_mst2_nt(vec_t *R, vec_t *A, mst2_t M) { mst2_t inv; mst2_inv(inv, M); v2_mul_mst2_nt(R, A, inv); } static inline void mst2_dump(mst2_t M) { printf("[%f\t%f\t%f]\n", M[2], 0.0, M[0]); printf("[%f\t%f\t%f]\n", 0.0, M[3], M[1]); printf("[%f\t%f\t%f]\n", 0.0, 0.0, 1.0); } // physics typedef struct { size_t width, height, depth; size_t zstr, ystr, xstr, size; // strides in no. of points (not bytes) size_t zstr1, ystr1, xstr1, size1; // same as above but for associated // scalar fields float spacing; // in meters } phy_field_info; typedef struct { float *E; float *H; } phy_field_em; /* typedef struct { int num; void *data; } phy_command; */ typedef struct { phy_field_info field_info; phy_field_em fields[3]; float *field_eps, *field_mu; //permittivity and permeability float time; SDL_mutex *rotate_lock; } phy_sim; void phy_sim_destroy(phy_sim *sim); int phy_sim_create(phy_sim *sim); void phy_sim_compute_const_fields(phy_sim *sim); void phy_sim_step(phy_sim *sim, float dt); int phy_thread(phy_sim *sim); // renderer extern float r_color_white[4]; extern float r_color_black[4]; extern float r_color_red[4]; extern float r_color_blue[4]; typedef struct r_window_s r_window; struct r_window_s { SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *font_texture; r_window *prev, *next; }; int r_init(void); void r_quit(void); r_window *r_window_create(void); void r_window_destroy(r_window *rw); void r_clear(r_window *rw, float *color); void r_flip(r_window *rw); void r_clip_enable(r_window *rw, float x, float y, float w, float h); void r_clip_disable(r_window *rw); void r_draw_line(r_window *rw, float x0, float y0, float x1, float y1, float *color); void r_draw_rect(r_window *rw, float x, float y, float w, float h, float *color); #define TEXT_CENTERX 0x0001 #define TEXT_RIGHTX 0x0002 float r_text_width(float h, char *text); void r_draw_text(r_window *rw, float x, float y, float h, char *text, float *color, int flags); typedef enum { XSECTION_XY, XSECTION_XZ, XSECTION_YZ } r_xsection_type; typedef struct { SDL_Texture *texture; float aspect_ratio; } r_xsection; void r_xsection_create(r_xsection *xsection); void r_xsection_destroy(r_xsection *xsection); int r_xsection_update(r_window *rw, r_xsection *xsection, phy_field_info *fi, float *field, r_xsection_type type, float frac); void r_xsection_draw(r_window *rw, r_xsection *xsection, float x, float y, float w, float h); // ui int ui_init(void); void ui_quit(void); void ui_renderer_window_register(r_window *rw); void ui_event(SDL_Event *event); void ui_draw(phy_sim *sim);