summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2016-04-02 15:56:38 +0200
committerPaweł Redman <pawel.redman@gmail.com>2016-04-02 15:56:38 +0200
commite40ab41ae226e257d57a73c69d9bdd8d19f64cb5 (patch)
tree9f2e4af0f58b6db4ae850939999c642357301003
parentf8420e0a46e1069220dcd642bca30c3fcb8c1b91 (diff)
Better UI (E/H switching).
-rw-r--r--src/physics.c19
-rw-r--r--src/physics.h1
-rw-r--r--src/renderer.c48
-rw-r--r--src/renderer.h20
-rw-r--r--src/ui.c133
5 files changed, 120 insertions, 101 deletions
diff --git a/src/physics.c b/src/physics.c
index 04c655c..7926478 100644
--- a/src/physics.c
+++ b/src/physics.c
@@ -34,7 +34,6 @@ void phy_sim_reset(phy_sim *sim)
sim->time = 0;
sim->running = false;
-
sim->frame_index = get_time();
}
@@ -47,11 +46,11 @@ int phy_sim_create(phy_sim *sim)
fi = &sim->field_info;
- fi->width = 50;
- fi->height = 50;
- fi->depth = 50;
+ fi->width = 100;
+ fi->height = 100;
+ fi->depth = 100;
fi->spacing = 1.5e10f / max3(fi->width, fi->height, fi->depth);
- sim->time_delta = 0.1;
+ sim->time_delta = 0.2;
fi->xstr = 3;
fi->ystr = fi->xstr * fi->width;
@@ -184,7 +183,8 @@ void phy_sim_add_sources_E(phy_sim *sim)
z = fi->depth / 2;
E = sim->fields[2].E + z * fi->zstr + y * fi->ystr + x * fi->xstr;
- E[0] += exp(-0.1f * pow(sim->time - 5.0f, 2)) * 5;
+ E[0] += sin(sim->time * 0.5) *
+ exp(-0.1f * pow(sim->time - 3.0f, 2)) * 50;
}
void phy_sim_add_sources_H(phy_sim *sim)
@@ -198,13 +198,15 @@ void phy_sim_add_sources_H(phy_sim *sim)
z = fi->depth / 2;
H = sim->fields[2].H + z * fi->zstr + y * fi->ystr + x * fi->xstr;
- H[1] -= exp(-0.1f * pow(sim->time - 4.5f, 2)) * 5;
+ H[1] -= exp(-0.1f * pow(sim->time - 5.0f - sim->time_delta / 2, 2)) * 5;
}
void phy_sim_step(phy_sim *sim) {
phy_field_info *fi = &sim->field_info;
phy_field_em *fields = sim->fields, tmp;
+ int64_t start_time;
+ start_time = get_time();
phy_sim_step_E(fi, sim->field_mu, sim->time_delta,
fields[2].E, fields[0].E, fields[1].H);
@@ -222,7 +224,8 @@ void phy_sim_step(phy_sim *sim) {
memcpy(fields + 2, &tmp, sizeof(phy_field_em));
sim->time += sim->time_delta;
- sim->frame_index = get_time();
+ sim->frame_index = get_time(); // for renderer
+ sim->step_real_time = get_time() - start_time;
SDL_mutexV(sim->rotate_lock);
}
diff --git a/src/physics.h b/src/physics.h
index 1ce2a9c..38a6100 100644
--- a/src/physics.h
+++ b/src/physics.h
@@ -36,6 +36,7 @@ typedef struct {
itc_chan ctl;
SDL_mutex *rotate_lock;
int64_t frame_index; // to avoid re-drawing the same fields
+ int64_t step_real_time;
} phy_sim;
void phy_sim_destroy(phy_sim *sim);
diff --git a/src/renderer.c b/src/renderer.c
index fb1647b..eee6e6d 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -359,39 +359,37 @@ void r_xsection_destroy(r_xsection *xsection)
SDL_DestroyTexture(xsection->texture);
}
-int r_xsection_update(r_window *rw, r_xsection *xsection,
- phy_field_info *fi, float *field, int64_t frame_index,
- r_xsection_type type, float frac)
+int r_xsection_update(r_window *rw, r_xsection *xsection, phy_sim *sim,
+ int flags, float frac)
{
+ phy_field_info *fi = &sim->field_info;
+ float *field;
size_t width, height, x, y, z;
uint8_t *pixels;
int pitch;
if (xsection->frame_index &&
- xsection->frame_index == frame_index &&
- xsection->last_frac == frac &&
- xsection->last_type == type)
+ xsection->frame_index == sim->frame_index &&
+ xsection->last_flags == flags &&
+ xsection->last_frac == frac)
return 0; // nothing's changed
- printf("r_xsection_update: tick %ld\n", frame_index);
-
- switch (type) {
- case XSECTION_XY:
+ if (flags & XSECTION_XY) {
width = fi->width;
height = fi->height;
- break;
-
- case XSECTION_XZ:
+ } else if (flags & XSECTION_XZ) {
width = fi->width;
height = fi->depth;
- break;
-
- case XSECTION_YZ:
+ } else {
width = fi->height;
height = fi->depth;
- break;
}
+ if (flags & XSECTION_E)
+ field = sim->fields[1].E;
+ else
+ field = sim->fields[1].H;
+
if (frac < 0.0f)
frac = 0.0f;
else if (frac > 1.0f)
@@ -404,8 +402,7 @@ int r_xsection_update(r_window *rw, r_xsection *xsection,
SDL_LockTexture(xsection->texture, NULL, (void**)&pixels, &pitch);
- switch (type) {
- case XSECTION_XY:
+ if (flags & XSECTION_XY) {
z = frac * fi->depth;
if (z >= fi->depth)
z = fi->depth - 1;
@@ -423,9 +420,7 @@ int r_xsection_update(r_window *rw, r_xsection *xsection,
pixel[1] = r_float_to_u8(point[1]);
pixel[2] = r_float_to_u8(point[2]);
}
- break;
-
- case XSECTION_XZ:
+ } else if (flags & XSECTION_XZ) {
y = frac * fi->height;
if (y >= fi->height)
y = fi->height - 1;
@@ -443,9 +438,7 @@ int r_xsection_update(r_window *rw, r_xsection *xsection,
pixel[1] = r_float_to_u8(point[1]);
pixel[2] = r_float_to_u8(point[2]);
}
- break;
-
- case XSECTION_YZ:
+ } else {
x = frac * fi->width;
if (x >= fi->width)
x = fi->width - 1;
@@ -463,16 +456,15 @@ int r_xsection_update(r_window *rw, r_xsection *xsection,
pixel[1] = r_float_to_u8(point[1]);
pixel[2] = r_float_to_u8(point[2]);
}
- break;
}
SDL_UnlockTexture(xsection->texture);
xsection->aspect_ratio = (float)width / height;
+ xsection->last_flags = flags;
xsection->last_frac = frac;
- xsection->last_type = type;
- xsection->frame_index = frame_index;
+ xsection->frame_index = sim->frame_index;
return 0;
}
diff --git a/src/renderer.h b/src/renderer.h
index ce373df..fadcd68 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -40,26 +40,28 @@ 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;
+
+#define XSECTION_XY 0x0001
+#define XSECTION_XZ 0x0002
+#define XSECTION_YZ 0x0004
+#define XSECTION_PLANES (XSECTION_XY|XSECTION_XZ|XSECTION_YZ)
+#define XSECTION_E 0x0008
+#define XSECTION_H 0x0010
+
typedef struct {
SDL_Texture *texture;
float aspect_ratio;
- r_xsection_type last_type;
+ int last_flags;
float last_frac;
int64_t frame_index;
} 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, int64_t frame_index,
- r_xsection_type type, float frac);
+int r_xsection_update(r_window *rw, r_xsection *xsection, phy_sim *sim,
+ int flags, float frac);
void r_xsection_draw(r_window *rw, r_xsection *xsection,
float x, float y, float w, float h);
diff --git a/src/ui.c b/src/ui.c
index 700950b..fac56ce 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -25,12 +25,11 @@ typedef struct {
phy_sim *sim;
bool dragging, selecting;
- r_xsection_type xsection_type;
+ int xsection_flags;
float xsection_frac;
bool select_valid;
vec3_t select;
- bool info_valid;
int64_t info_time;
char info[MAX_INFO];
@@ -137,7 +136,6 @@ void ui_infof(ui_window *uiw, const char *fmt, ...)
vsnprintf(uiw->simview.info, MAX_INFO, fmt, vl);
va_end(vl);
- uiw->simview.info_valid = true;
uiw->simview.info_time = get_time();
}
@@ -200,15 +198,21 @@ void ui_event_window(SDL_Event *event, ui_window *uiw)
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_1:
- sv->xsection_type = XSECTION_XY;
+ ui_infof(uiw, "Plaszczyzna przekroju: XY");
+ sv->xsection_flags &= ~XSECTION_PLANES;
+ sv->xsection_flags |= XSECTION_XY;
break;
case SDLK_2:
- sv->xsection_type = XSECTION_XZ;
+ ui_infof(uiw, "Plaszczyzna przekroju: XZ");
+ sv->xsection_flags &= ~XSECTION_PLANES;
+ sv->xsection_flags |= XSECTION_XZ;
break;
case SDLK_3:
- sv->xsection_type = XSECTION_YZ;
+ ui_infof(uiw, "Plaszczyzna przekroju: YZ");
+ sv->xsection_flags &= ~XSECTION_PLANES;
+ sv->xsection_flags |= XSECTION_YZ;
break;
case SDLK_w:
@@ -224,20 +228,36 @@ void ui_event_window(SDL_Event *event, ui_window *uiw)
break;
case SDLK_o:
+ ui_infof(uiw, "Symulacja wstrzymana");
itc_chan_push(&sv->sim->ctl, PHY_CMD_PAUSE, NULL);
break;
case SDLK_p:
+ ui_infof(uiw, "Symulacja wznowiona");
itc_chan_push(&sv->sim->ctl, PHY_CMD_RESUME, NULL);
break;
case SDLK_l:
+ ui_infof(uiw, "Pojedyńczy krok");
itc_chan_push(&sv->sim->ctl, PHY_CMD_STEP, NULL);
break;
case SDLK_r:
+ ui_infof(uiw, "Symulacja wyzerowana");
itc_chan_push(&sv->sim->ctl, PHY_CMD_RESET, NULL);
break;
+
+ case SDLK_4:
+ ui_infof(uiw, "Przekrój: pola elektrycznego");
+ sv->xsection_flags &= ~XSECTION_H;
+ sv->xsection_flags |= XSECTION_E;
+ break;
+
+ case SDLK_5:
+ ui_infof(uiw, "Przekrój: pola magnetycznego");
+ sv->xsection_flags &= ~XSECTION_E;
+ sv->xsection_flags |= XSECTION_H;
+ break;
}
}
}
@@ -287,7 +307,7 @@ void ui_animate_exp(float *val, float targ, float lambda, float dt)
*val = targ + (*val - targ) * exp(-lambda * dt);
}
-void ui_draw_simview_xsection(ui_window *uiw, float *field)
+void ui_draw_simview_xsection(ui_window *uiw)
{
ui_simview *sv = &uiw->simview;
phy_sim *sim = sv->sim;
@@ -295,8 +315,7 @@ void ui_draw_simview_xsection(ui_window *uiw, float *field)
vec2_t origin_s, scale_s;
SDL_mutexP(sim->rotate_lock);
- r_xsection_update(uiw->rw, &sv->xsection, &sim->field_info, field,
- sim->frame_index, sv->xsection_type,
+ r_xsection_update(uiw->rw, &sv->xsection, sim, sv->xsection_flags,
sv->xsection_frac);
SDL_mutexV(sim->rotate_lock);
@@ -336,22 +355,15 @@ void ui_draw_simview_selection(ui_window *uiw)
return;
}
- switch (sv->xsection_type) {
- case XSECTION_XY:
+ if (sv->xsection_flags & XSECTION_XY)
v3_set(sv->select,
select_2d[0], select_2d[1], sv->xsection_frac);
- break;
-
- case XSECTION_XZ:
+ else if (sv->xsection_flags & XSECTION_XZ)
v3_set(sv->select,
select_2d[0], sv->xsection_frac, select_2d[1]);
- break;
-
- case XSECTION_YZ:
+ else
v3_set(sv->select,
sv->xsection_frac, select_2d[0], select_2d[1]);
- break;
- }
sv->select_valid = true;
}
@@ -359,19 +371,12 @@ void ui_draw_simview_selection(ui_window *uiw)
if (!sv->select_valid)
return;
- switch (sv->xsection_type) {
- case XSECTION_XY:
+ if (sv->xsection_flags & XSECTION_XY)
v2_set(select_s, sv->select[0], sv->select[1]);
- break;
-
- case XSECTION_XZ:
+ else if (sv->xsection_flags & XSECTION_XZ)
v2_set(select_s, sv->select[0], sv->select[2]);
- break;
-
- case XSECTION_YZ:
+ else
v2_set(select_s, sv->select[1], sv->select[2]);
- break;
- }
v2_mul_mst2(select_s, select_s, sv->tf_x2s);
@@ -381,19 +386,28 @@ void ui_draw_simview_selection(ui_window *uiw)
theme.color_select);
}
-void ui_draw_simview_bars(ui_window *uiw, float dt)
+char *ui_draw_simview_top_bar_text(ui_simview *sv)
{
- const char *xsection_type_strings[] = {
- "Przekrój XY przez Z",
- "Przekrój XZ przez Y",
- "Przekrój YZ przez X"
- };
+ int flags = sv->xsection_flags;
+
+ va("Przekrój %s płaszczyzną %s=%f",
+ (flags & XSECTION_E ? "E" :
+ "H"),
+ (flags & XSECTION_XY ? "Z" :
+ flags & XSECTION_XZ ? "Y" :
+ "X"),
+ sv->xsection_frac);
+}
+void ui_draw_simview_bars(ui_window *uiw, float dt)
+{
ui_simview *sv = &uiw->simview;
phy_sim *sim = sv->sim;
phy_field_em *field_em = sim->fields + 1;
phy_field_info *fi = &sim->field_info;
+ SDL_mutexP(sim->rotate_lock);
+
// upper
sv->margin_top = theme.font_size;
@@ -401,13 +415,11 @@ void ui_draw_simview_bars(ui_window *uiw, float dt)
r_draw_rect(uiw->rw, 0, 0, uiw->w, theme.font_size, theme.color_main);
r_draw_text(uiw->rw, uiw->w, 0, theme.font_size,
- va("%.0fkl./s %04zu", 1.0f / dt, uiw->frame_count % 10000),
- theme.color_text_light, TEXT_RIGHTX);
+ va("%.0fkl./s", 1.0f / dt), theme.color_text_light,
+ TEXT_RIGHTX);
r_draw_text(uiw->rw, 0, 0, theme.font_size,
- va("%s = %f", xsection_type_strings[sv->xsection_type],
- sv->xsection_frac),
- theme.color_text, 0);
+ ui_draw_simview_top_bar_text(sv), theme.color_text, 0);
// lower
@@ -416,8 +428,15 @@ void ui_draw_simview_bars(ui_window *uiw, float dt)
uiw->w, theme.font_size, theme.color_main);
r_draw_text(uiw->rw, 0, uiw->h - theme.font_size,
- theme.font_size, va("t = %f", sim->time),
- theme.color_text, 0);
+ theme.font_size, va("t = %f, Δt = %f", sim->time,
+ sim->time_delta), theme.color_text, 0);
+
+ r_draw_text(uiw->rw, uiw->w, uiw->h - theme.font_size,
+ theme.font_size, va("%.3fs/krok",
+ (sim->step_real_time * 1.0e-9f)),
+ theme.color_text_light, TEXT_RIGHTX);
+
+
if (sv->select_valid) {
size_t x, y, z, offs;
@@ -447,21 +466,15 @@ void ui_draw_simview_bars(ui_window *uiw, float dt)
field_em->H[offs], field_em->H[offs + 1],
field_em->H[offs + 2]), theme.color_text, 0);
}
-}
+ SDL_mutexV(sim->rotate_lock);
+}
-void ui_draw_simview(ui_window *uiw, int64_t time, float dt)
+void ui_draw_simview_info(ui_window *uiw, int64_t time)
{
- ui_draw_simview_xsection(uiw, uiw->simview.sim->fields[1].E);
- ui_draw_simview_selection(uiw);
- ui_draw_simview_bars(uiw, dt);
-
- // status
-
- // info text
+ ui_simview *sv = &uiw->simview;
-/*
- if (sv->info_valid && sv->info_time + 2000000000ll > time)
+ if (sv->info_time && sv->info_time + 2000000000ll > time)
{
vec4_t color;
@@ -480,7 +493,15 @@ void ui_draw_simview(ui_window *uiw, int64_t time, float dt)
r_draw_text(uiw->rw, uiw->w / 2.0f, theme.font_size,
theme.font_size, sv->info, color, TEXT_CENTERX);
- }*/
+ }
+}
+
+void ui_draw_simview(ui_window *uiw, int64_t time, float dt)
+{
+ ui_draw_simview_xsection(uiw);
+ ui_draw_simview_selection(uiw);
+ ui_draw_simview_bars(uiw, dt);
+ ui_draw_simview_info(uiw, time);
}
void ui_draw_window(ui_window *uiw)
@@ -497,14 +518,14 @@ void ui_draw_window(ui_window *uiw)
v2_set(sv->origin, 0, 0);
v2_set(sv->scale, 1, 1);
- sv->xsection_type = XSECTION_XY;
+ sv->xsection_flags = XSECTION_XY | XSECTION_E;
sv->xsection_frac = 0.5f;
sv->select_valid = false;
sv->margin_top = theme.font_size;
sv->margin_bottom = 0;
- sv->info_valid = false;
+ sv->info_time = 0;
r_clear(uiw->rw, r_color_black);
return;