diff options
| author | Paweł Redman <pawel.redman@gmail.com> | 2016-04-02 15:56:38 +0200 | 
|---|---|---|
| committer | Paweł Redman <pawel.redman@gmail.com> | 2016-04-02 15:56:38 +0200 | 
| commit | e40ab41ae226e257d57a73c69d9bdd8d19f64cb5 (patch) | |
| tree | 9f2e4af0f58b6db4ae850939999c642357301003 /src | |
| parent | f8420e0a46e1069220dcd642bca30c3fcb8c1b91 (diff) | |
Better UI (E/H switching).
Diffstat (limited to 'src')
| -rw-r--r-- | src/physics.c | 19 | ||||
| -rw-r--r-- | src/physics.h | 1 | ||||
| -rw-r--r-- | src/renderer.c | 48 | ||||
| -rw-r--r-- | src/renderer.h | 20 | ||||
| -rw-r--r-- | src/ui.c | 133 | 
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); @@ -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;  | 
