Exemple #1
0
static void set_height_normalize_factor(struct Ocean *oc)
{
	float res = 1.0;
	float max_h = 0.0;

	int i, j;

	if (!oc->_do_disp_y) return;

	oc->normalize_factor = 1.0;

	BKE_simulate_ocean(oc, 0.0, 1.0, 0);

	BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);

	for (i = 0; i < oc->_M; ++i) {
		for (j = 0; j < oc->_N; ++j) {
			if (max_h < fabsf(oc->_disp_y[i * oc->_N + j])) {
				max_h = fabsf(oc->_disp_y[i * oc->_N + j]);
			}
		}
	}

	BLI_rw_mutex_unlock(&oc->oceanmutex);

	if (max_h == 0.0f)
		max_h = 0.00001f;  /* just in case ... */

	res = 1.0f / (max_h);

	oc->normalize_factor = res;
}
Exemple #2
0
void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
                    void *update_cb_data)
{
	/* note: some of these values remain uninitialized unless certain options
	 * are enabled, take care that BKE_ocean_eval_ij() initializes a member
	 * before use - campbell */
	OceanResult ocr;

	ImageFormatData imf = {0};

	int f, i = 0, x, y, cancel = 0;
	float progress;

	ImBuf *ibuf_foam, *ibuf_disp, *ibuf_normal;
	float *prev_foam;
	int res_x = och->resolution_x;
	int res_y = och->resolution_y;
	char string[FILE_MAX];

	if (!o) return;

	if (o->_do_jacobian) prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data");
	else prev_foam = NULL;

	BLI_srand(0);

	/* setup image format */
	imf.imtype = R_IMF_IMTYPE_OPENEXR;
	imf.depth =  R_IMF_CHAN_DEPTH_16;
	imf.exr_codec = R_IMF_EXR_CODEC_ZIP;

	for (f = och->start, i = 0; f <= och->end; f++, i++) {

		/* create a new imbuf to store image for this frame */
		ibuf_foam = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
		ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
		ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);

		BKE_simulate_ocean(o, och->time[i], och->wave_scale, och->chop_amount);

		/* add new foam */
		for (y = 0; y < res_y; y++) {
			for (x = 0; x < res_x; x++) {

				BKE_ocean_eval_ij(o, &ocr, x, y);

				/* add to the image */
				rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);

				if (o->_do_jacobian) {
					/* TODO, cleanup unused code - campbell */

					float /*r, */ /* UNUSED */ pr = 0.0f, foam_result;
					float neg_disp, neg_eplus;

					ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, och->foam_coverage);

					/* accumulate previous value for this cell */
					if (i > 0) {
						pr = prev_foam[res_x * y + x];
					}

					/* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */

					/* pr = pr * och->foam_fade; */		/* overall fade */

					/* remember ocean coord sys is Y up!
					 * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
					 */

#if 0
					vec[0] = ocr.disp[0];
					vec[1] = ocr.disp[2];
					hor_stretch = len_v2(vec);
					CLAMP(hor_stretch, 0.0, 1.0);
#endif

					neg_disp = ocr.disp[1] < 0.0f ? 1.0f + ocr.disp[1] : 1.0f;
					neg_disp = neg_disp < 0.0f ? 0.0f : neg_disp;

					/* foam, 'ocr.Eplus' only initialized with do_jacobian */
					neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
					neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;

#if 0
					if (ocr.disp[1] < 0.0 || r > och->foam_fade)
						pr *= och->foam_fade;


					pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
					pr = pr * neg_disp * neg_eplus;
#endif

					if (pr < 1.0f)
						pr *= pr;

					pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);

					/* A full clamping should not be needed! */
					foam_result = min_ff(pr + ocr.foam, 1.0f);

					prev_foam[res_x * y + x] = foam_result;

					/*foam_result = min_ff(foam_result, 1.0f); */

					value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
				}

				if (o->_do_normals) {
					rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal);
				}
			}
		}

		/* write the images */
		cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_DISPLACE);
		if (0 == BKE_imbuf_write(ibuf_disp, string, &imf))
			printf("Cannot save Displacement File Output to %s\n", string);

		if (o->_do_jacobian) {
			cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_FOAM);
			if (0 == BKE_imbuf_write(ibuf_foam, string, &imf))
				printf("Cannot save Foam File Output to %s\n", string);
		}

		if (o->_do_normals) {
			cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_NORMAL);
			if (0 == BKE_imbuf_write(ibuf_normal, string, &imf))
				printf("Cannot save Normal File Output to %s\n", string);
		}

		IMB_freeImBuf(ibuf_disp);
		IMB_freeImBuf(ibuf_foam);
		IMB_freeImBuf(ibuf_normal);

		progress = (f - och->start) / (float)och->duration;

		update_cb(update_cb_data, progress, &cancel);

		if (cancel) {
			if (prev_foam) MEM_freeN(prev_foam);
			return;
		}
	}

	if (prev_foam) MEM_freeN(prev_foam);
	och->baked = 1;
}
Exemple #3
0
static void simulate_ocean_modifier(struct OceanModifierData *omd)
{
	if (!omd || !omd->ocean) return;

	BKE_simulate_ocean(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
}