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; }
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; }
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); }