diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_ocean.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_ocean.c | 719 |
1 files changed, 360 insertions, 359 deletions
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 5379321239c..983ea7b4309 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -46,471 +46,472 @@ #ifdef WITH_OCEANSIM static void init_cache_data(Object *ob, struct OceanModifierData *omd) { - const char *relbase = modifier_path_relbase_from_global(ob); - - omd->oceancache = BKE_ocean_init_cache(omd->cachepath, relbase, - omd->bakestart, omd->bakeend, omd->wave_scale, - omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); + const char *relbase = modifier_path_relbase_from_global(ob); + + omd->oceancache = BKE_ocean_init_cache(omd->cachepath, + relbase, + omd->bakestart, + omd->bakeend, + omd->wave_scale, + omd->chop_amount, + omd->foam_coverage, + omd->foam_fade, + omd->resolution); } static void simulate_ocean_modifier(struct OceanModifierData *omd) { - BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount); + BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount); } #endif /* WITH_OCEANSIM */ - - /* Modifier Code */ static void initData(ModifierData *md) { #ifdef WITH_OCEANSIM - OceanModifierData *omd = (OceanModifierData *) md; + OceanModifierData *omd = (OceanModifierData *)md; - omd->resolution = 7; - omd->spatial_size = 50; + omd->resolution = 7; + omd->spatial_size = 50; - omd->wave_alignment = 0.0; - omd->wind_velocity = 30.0; + omd->wave_alignment = 0.0; + omd->wind_velocity = 30.0; - omd->damp = 0.5; - omd->smallest_wave = 0.01; - omd->wave_direction = 0.0; - omd->depth = 200.0; + omd->damp = 0.5; + omd->smallest_wave = 0.01; + omd->wave_direction = 0.0; + omd->depth = 200.0; - omd->wave_scale = 1.0; + omd->wave_scale = 1.0; - omd->chop_amount = 1.0; + omd->chop_amount = 1.0; - omd->foam_coverage = 0.0; + omd->foam_coverage = 0.0; - omd->seed = 0; - omd->time = 1.0; + omd->seed = 0; + omd->time = 1.0; - omd->size = 1.0; - omd->repeat_x = 1; - omd->repeat_y = 1; + omd->size = 1.0; + omd->repeat_x = 1; + omd->repeat_y = 1; - modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean"); + modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean"); - omd->cached = 0; - omd->bakestart = 1; - omd->bakeend = 250; - omd->oceancache = NULL; - omd->foam_fade = 0.98; - omd->foamlayername[0] = '\0'; /* layer name empty by default */ + omd->cached = 0; + omd->bakestart = 1; + omd->bakeend = 250; + omd->oceancache = NULL; + omd->foam_fade = 0.98; + omd->foamlayername[0] = '\0'; /* layer name empty by default */ - omd->ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(omd->ocean, omd); - simulate_ocean_modifier(omd); + omd->ocean = BKE_ocean_add(); + BKE_ocean_init_from_modifier(omd->ocean, omd); + simulate_ocean_modifier(omd); #else /* WITH_OCEANSIM */ - /* unused */ - (void)md; + /* unused */ + (void)md; #endif /* WITH_OCEANSIM */ } static void freeData(ModifierData *md) { #ifdef WITH_OCEANSIM - OceanModifierData *omd = (OceanModifierData *) md; - - BKE_ocean_free(omd->ocean); - if (omd->oceancache) - BKE_ocean_free_cache(omd->oceancache); -#else /* WITH_OCEANSIM */ - /* unused */ - (void)md; + OceanModifierData *omd = (OceanModifierData *)md; + + BKE_ocean_free(omd->ocean); + if (omd->oceancache) + BKE_ocean_free_cache(omd->oceancache); +#else /* WITH_OCEANSIM */ + /* unused */ + (void)md; #endif /* WITH_OCEANSIM */ } static void copyData(const ModifierData *md, ModifierData *target, const int flag) { #ifdef WITH_OCEANSIM -#if 0 - const OceanModifierData *omd = (const OceanModifierData *) md; -#endif - OceanModifierData *tomd = (OceanModifierData *) target; - - modifier_copyData_generic(md, target, flag); - - /* The oceancache object will be recreated for this copy - * automatically when cached=true */ - tomd->oceancache = NULL; - - tomd->ocean = BKE_ocean_add(); - BKE_ocean_init_from_modifier(tomd->ocean, tomd); - simulate_ocean_modifier(tomd); -#else /* WITH_OCEANSIM */ - /* unused */ - (void)md; - (void)target; - (void)flag; +# if 0 + const OceanModifierData *omd = (const OceanModifierData *) md; +# endif + OceanModifierData *tomd = (OceanModifierData *)target; + + modifier_copyData_generic(md, target, flag); + + /* The oceancache object will be recreated for this copy + * automatically when cached=true */ + tomd->oceancache = NULL; + + tomd->ocean = BKE_ocean_add(); + BKE_ocean_init_from_modifier(tomd->ocean, tomd); + simulate_ocean_modifier(tomd); +#else /* WITH_OCEANSIM */ + /* unused */ + (void)md; + (void)target; + (void)flag; #endif /* WITH_OCEANSIM */ } #ifdef WITH_OCEANSIM -static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks) +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *md, + CustomData_MeshMasks *r_cddata_masks) { - OceanModifierData *omd = (OceanModifierData *)md; + OceanModifierData *omd = (OceanModifierData *)md; - if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { - r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */ - } + if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { + r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */ + } } -#else /* WITH_OCEANSIM */ -static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *UNUSED(r_cddata_masks)) +#else /* WITH_OCEANSIM */ +static void requiredDataMask(Object *UNUSED(ob), + ModifierData *UNUSED(md), + CustomData_MeshMasks *UNUSED(r_cddata_masks)) { } #endif /* WITH_OCEANSIM */ static bool dependsOnNormals(ModifierData *md) { - OceanModifierData *omd = (OceanModifierData *)md; - return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE); + OceanModifierData *omd = (OceanModifierData *)md; + return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE); } #ifdef WITH_OCEANSIM typedef struct GenerateOceanGeometryData { - MVert *mverts; - MPoly *mpolys; - MLoop *mloops; - MLoopUV *mloopuvs; - - int res_x, res_y; - int rx, ry; - float ox, oy; - float sx, sy; - float ix, iy; + MVert *mverts; + MPoly *mpolys; + MLoop *mloops; + MLoopUV *mloopuvs; + + int res_x, res_y; + int rx, ry; + float ox, oy; + float sx, sy; + float ix, iy; } GenerateOceanGeometryData; -static void generate_ocean_geometry_vertices( - void *__restrict userdata, - const int y, - const ParallelRangeTLS *__restrict UNUSED(tls)) +static void generate_ocean_geometry_vertices(void *__restrict userdata, + const int y, + const ParallelRangeTLS *__restrict UNUSED(tls)) { - GenerateOceanGeometryData *gogd = userdata; - int x; - - for (x = 0; x <= gogd->res_x; x++) { - const int i = y * (gogd->res_x + 1) + x; - float *co = gogd->mverts[i].co; - co[0] = gogd->ox + (x * gogd->sx); - co[1] = gogd->oy + (y * gogd->sy); - co[2] = 0.0f; - } + GenerateOceanGeometryData *gogd = userdata; + int x; + + for (x = 0; x <= gogd->res_x; x++) { + const int i = y * (gogd->res_x + 1) + x; + float *co = gogd->mverts[i].co; + co[0] = gogd->ox + (x * gogd->sx); + co[1] = gogd->oy + (y * gogd->sy); + co[2] = 0.0f; + } } -static void generate_ocean_geometry_polygons( - void *__restrict userdata, - const int y, - const ParallelRangeTLS *__restrict UNUSED(tls)) +static void generate_ocean_geometry_polygons(void *__restrict userdata, + const int y, + const ParallelRangeTLS *__restrict UNUSED(tls)) { - GenerateOceanGeometryData *gogd = userdata; - int x; - - for (x = 0; x < gogd->res_x; x++) { - const int fi = y * gogd->res_x + x; - const int vi = y * (gogd->res_x + 1) + x; - MPoly *mp = &gogd->mpolys[fi]; - MLoop *ml = &gogd->mloops[fi * 4]; - - ml->v = vi; - ml++; - ml->v = vi + 1; - ml++; - ml->v = vi + 1 + gogd->res_x + 1; - ml++; - ml->v = vi + gogd->res_x + 1; - ml++; - - mp->loopstart = fi * 4; - mp->totloop = 4; - - mp->flag |= ME_SMOOTH; - } + GenerateOceanGeometryData *gogd = userdata; + int x; + + for (x = 0; x < gogd->res_x; x++) { + const int fi = y * gogd->res_x + x; + const int vi = y * (gogd->res_x + 1) + x; + MPoly *mp = &gogd->mpolys[fi]; + MLoop *ml = &gogd->mloops[fi * 4]; + + ml->v = vi; + ml++; + ml->v = vi + 1; + ml++; + ml->v = vi + 1 + gogd->res_x + 1; + ml++; + ml->v = vi + gogd->res_x + 1; + ml++; + + mp->loopstart = fi * 4; + mp->totloop = 4; + + mp->flag |= ME_SMOOTH; + } } -static void generate_ocean_geometry_uvs( - void *__restrict userdata, - const int y, - const ParallelRangeTLS *__restrict UNUSED(tls)) +static void generate_ocean_geometry_uvs(void *__restrict userdata, + const int y, + const ParallelRangeTLS *__restrict UNUSED(tls)) { - GenerateOceanGeometryData *gogd = userdata; - int x; + GenerateOceanGeometryData *gogd = userdata; + int x; - for (x = 0; x < gogd->res_x; x++) { - const int i = y * gogd->res_x + x; - MLoopUV *luv = &gogd->mloopuvs[i * 4]; + for (x = 0; x < gogd->res_x; x++) { + const int i = y * gogd->res_x + x; + MLoopUV *luv = &gogd->mloopuvs[i * 4]; - luv->uv[0] = x * gogd->ix; - luv->uv[1] = y * gogd->iy; - luv++; + luv->uv[0] = x * gogd->ix; + luv->uv[1] = y * gogd->iy; + luv++; - luv->uv[0] = (x + 1) * gogd->ix; - luv->uv[1] = y * gogd->iy; - luv++; + luv->uv[0] = (x + 1) * gogd->ix; + luv->uv[1] = y * gogd->iy; + luv++; - luv->uv[0] = (x + 1) * gogd->ix; - luv->uv[1] = (y + 1) * gogd->iy; - luv++; + luv->uv[0] = (x + 1) * gogd->ix; + luv->uv[1] = (y + 1) * gogd->iy; + luv++; - luv->uv[0] = x * gogd->ix; - luv->uv[1] = (y + 1) * gogd->iy; - luv++; - } + luv->uv[0] = x * gogd->ix; + luv->uv[1] = (y + 1) * gogd->iy; + luv++; + } } static Mesh *generate_ocean_geometry(OceanModifierData *omd) { - Mesh *result; + Mesh *result; - GenerateOceanGeometryData gogd; + GenerateOceanGeometryData gogd; - int num_verts; - int num_polys; + int num_verts; + int num_polys; - const bool use_threading = omd->resolution > 4; + const bool use_threading = omd->resolution > 4; - gogd.rx = omd->resolution * omd->resolution; - gogd.ry = omd->resolution * omd->resolution; - gogd.res_x = gogd.rx * omd->repeat_x; - gogd.res_y = gogd.ry * omd->repeat_y; + gogd.rx = omd->resolution * omd->resolution; + gogd.ry = omd->resolution * omd->resolution; + gogd.res_x = gogd.rx * omd->repeat_x; + gogd.res_y = gogd.ry * omd->repeat_y; - num_verts = (gogd.res_x + 1) * (gogd.res_y + 1); - num_polys = gogd.res_x * gogd.res_y; + num_verts = (gogd.res_x + 1) * (gogd.res_y + 1); + num_polys = gogd.res_x * gogd.res_y; - gogd.sx = omd->size * omd->spatial_size; - gogd.sy = omd->size * omd->spatial_size; - gogd.ox = -gogd.sx / 2.0f; - gogd.oy = -gogd.sy / 2.0f; + gogd.sx = omd->size * omd->spatial_size; + gogd.sy = omd->size * omd->spatial_size; + gogd.ox = -gogd.sx / 2.0f; + gogd.oy = -gogd.sy / 2.0f; - gogd.sx /= gogd.rx; - gogd.sy /= gogd.ry; + gogd.sx /= gogd.rx; + gogd.sy /= gogd.ry; - result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys); + result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys); - gogd.mverts = result->mvert; - gogd.mpolys = result->mpoly; - gogd.mloops = result->mloop; + gogd.mverts = result->mvert; + gogd.mpolys = result->mpoly; + gogd.mloops = result->mloop; - ParallelRangeSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = use_threading; + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.use_threading = use_threading; - /* create vertices */ - BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings); + /* create vertices */ + BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings); - /* create faces */ - BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings); + /* create faces */ + BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings); - BKE_mesh_calc_edges(result, false, false); + BKE_mesh_calc_edges(result, false, false); - /* add uvs */ - if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) { - gogd.mloopuvs = CustomData_add_layer(&result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4); + /* add uvs */ + if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) { + gogd.mloopuvs = CustomData_add_layer( + &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4); - if (gogd.mloopuvs) { /* unlikely to fail */ - gogd.ix = 1.0 / gogd.rx; - gogd.iy = 1.0 / gogd.ry; + if (gogd.mloopuvs) { /* unlikely to fail */ + gogd.ix = 1.0 / gogd.rx; + gogd.iy = 1.0 / gogd.ry; - BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings); - } - } + BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings); + } + } - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; - return result; + return result; } static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { - OceanModifierData *omd = (OceanModifierData *) md; - int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph); - Object *ob = ctx->object; - bool allocated_ocean = false; - - Mesh *result = NULL; - OceanResult ocr; - - MVert *mverts; - - int cfra_for_cache; - int i, j; - - /* use cached & inverted value for speed - * expanded this would read... - * - * (axis / (omd->size * omd->spatial_size)) + 0.5f) */ -#define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f) - - const float size_co_inv = 1.0f / (omd->size * omd->spatial_size); - - /* can happen in when size is small, avoid bad array lookups later and quit now */ - if (!isfinite(size_co_inv)) { - return mesh; - } - - /* do ocean simulation */ - if (omd->cached == true) { - if (!omd->oceancache) { - init_cache_data(ob, omd); - } - BKE_ocean_simulate_cache(omd->oceancache, cfra_scene); - } - else { - /* omd->ocean is NULL on an original object (in contrast to an evaluated one). - * We can create a new one, but we have to free it as well once we're done. - * This function is only called on an original object when applying the modifier - * using the 'Apply Modifier' button, and thus it is not called frequently for - * simulation. */ - allocated_ocean |= BKE_ocean_ensure(omd); - simulate_ocean_modifier(omd); - } - - if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) { - result = generate_ocean_geometry(omd); - BKE_mesh_ensure_normals(result); - } - else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { - BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE); - } - - cfra_for_cache = cfra_scene; - CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend); - cfra_for_cache -= omd->bakestart; /* shift to 0 based */ - - mverts = result->mvert; - - /* add vcols before displacement - allows lookup based on position */ - - if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { - if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) { - const int num_polys = result->totpoly; - const int num_loops = result->totloop; - MLoop *mloops = result->mloop; - MLoopCol *mloopcols = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername); - - if (mloopcols) { /* unlikely to fail */ - MPoly *mpolys = result->mpoly; - MPoly *mp; - - for (i = 0, mp = mpolys; i < num_polys; i++, mp++) { - MLoop *ml = &mloops[mp->loopstart]; - MLoopCol *mlcol = &mloopcols[mp->loopstart]; - - for (j = mp->totloop; j--; ml++, mlcol++) { - const float *vco = mverts[ml->v].co; - const float u = OCEAN_CO(size_co_inv, vco[0]); - const float v = OCEAN_CO(size_co_inv, vco[1]); - float foam; - - if (omd->oceancache && omd->cached == true) { - BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); - foam = ocr.foam; - CLAMP(foam, 0.0f, 1.0f); - } - else { - BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); - foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); - } - - mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255); - /* This needs to be set (render engine uses) */ - mlcol->a = 255; - } - } - } - } - } - - - /* displace the geometry */ - - /* Note: tried to parallelized that one and previous foam loop, but gives 20% slower results... odd. */ - { - const int num_verts = result->totvert; - - for (i = 0; i < num_verts; i++) { - float *vco = mverts[i].co; - const float u = OCEAN_CO(size_co_inv, vco[0]); - const float v = OCEAN_CO(size_co_inv, vco[1]); - - if (omd->oceancache && omd->cached == true) { - BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); - } - else { - BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); - } - - vco[2] += ocr.disp[1]; - - if (omd->chop_amount > 0.0f) { - vco[0] += ocr.disp[0]; - vco[1] += ocr.disp[2]; - } - } - } - - if (allocated_ocean) { - BKE_ocean_free(omd->ocean); - omd->ocean = NULL; - } - -#undef OCEAN_CO - - return result; + OceanModifierData *omd = (OceanModifierData *)md; + int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph); + Object *ob = ctx->object; + bool allocated_ocean = false; + + Mesh *result = NULL; + OceanResult ocr; + + MVert *mverts; + + int cfra_for_cache; + int i, j; + + /* use cached & inverted value for speed + * expanded this would read... + * + * (axis / (omd->size * omd->spatial_size)) + 0.5f) */ +# define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f) + + const float size_co_inv = 1.0f / (omd->size * omd->spatial_size); + + /* can happen in when size is small, avoid bad array lookups later and quit now */ + if (!isfinite(size_co_inv)) { + return mesh; + } + + /* do ocean simulation */ + if (omd->cached == true) { + if (!omd->oceancache) { + init_cache_data(ob, omd); + } + BKE_ocean_simulate_cache(omd->oceancache, cfra_scene); + } + else { + /* omd->ocean is NULL on an original object (in contrast to an evaluated one). + * We can create a new one, but we have to free it as well once we're done. + * This function is only called on an original object when applying the modifier + * using the 'Apply Modifier' button, and thus it is not called frequently for + * simulation. */ + allocated_ocean |= BKE_ocean_ensure(omd); + simulate_ocean_modifier(omd); + } + + if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) { + result = generate_ocean_geometry(omd); + BKE_mesh_ensure_normals(result); + } + else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { + BKE_id_copy_ex(NULL, &mesh->id, (ID **)&result, LIB_ID_COPY_LOCALIZE); + } + + cfra_for_cache = cfra_scene; + CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend); + cfra_for_cache -= omd->bakestart; /* shift to 0 based */ + + mverts = result->mvert; + + /* add vcols before displacement - allows lookup based on position */ + + if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { + if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) { + const int num_polys = result->totpoly; + const int num_loops = result->totloop; + MLoop *mloops = result->mloop; + MLoopCol *mloopcols = CustomData_add_layer_named( + &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername); + + if (mloopcols) { /* unlikely to fail */ + MPoly *mpolys = result->mpoly; + MPoly *mp; + + for (i = 0, mp = mpolys; i < num_polys; i++, mp++) { + MLoop *ml = &mloops[mp->loopstart]; + MLoopCol *mlcol = &mloopcols[mp->loopstart]; + + for (j = mp->totloop; j--; ml++, mlcol++) { + const float *vco = mverts[ml->v].co; + const float u = OCEAN_CO(size_co_inv, vco[0]); + const float v = OCEAN_CO(size_co_inv, vco[1]); + float foam; + + if (omd->oceancache && omd->cached == true) { + BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); + foam = ocr.foam; + CLAMP(foam, 0.0f, 1.0f); + } + else { + BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); + foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); + } + + mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255); + /* This needs to be set (render engine uses) */ + mlcol->a = 255; + } + } + } + } + } + + /* displace the geometry */ + + /* Note: tried to parallelized that one and previous foam loop, but gives 20% slower results... odd. */ + { + const int num_verts = result->totvert; + + for (i = 0; i < num_verts; i++) { + float *vco = mverts[i].co; + const float u = OCEAN_CO(size_co_inv, vco[0]); + const float v = OCEAN_CO(size_co_inv, vco[1]); + + if (omd->oceancache && omd->cached == true) { + BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); + } + else { + BKE_ocean_eval_uv(omd->ocean, &ocr, u, v); + } + + vco[2] += ocr.disp[1]; + + if (omd->chop_amount > 0.0f) { + vco[0] += ocr.disp[0]; + vco[1] += ocr.disp[2]; + } + } + } + + if (allocated_ocean) { + BKE_ocean_free(omd->ocean); + omd->ocean = NULL; + } + +# undef OCEAN_CO + + return result; } #else /* WITH_OCEANSIM */ static Mesh *doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) { - return mesh; + return mesh; } #endif /* WITH_OCEANSIM */ -static Mesh *applyModifier( - ModifierData *md, const ModifierEvalContext *ctx, - Mesh *mesh) +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { - Mesh *result; + Mesh *result; - result = doOcean(md, ctx, mesh); + result = doOcean(md, ctx, mesh); - if (result != mesh) - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + if (result != mesh) + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; - return result; + return result; } - ModifierTypeInfo modifierType_Ocean = { - /* name */ "Ocean", - /* structName */ "OceanModifierData", - /* structSize */ sizeof(OceanModifierData), - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | - eModifierTypeFlag_SupportsEditmode | - eModifierTypeFlag_EnableInEditmode, - - /* copyData */ copyData, - /* deformMatrices_DM */ NULL, - - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, - - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachObjectLink */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* name */ "Ocean", + /* structName */ "OceanModifierData", + /* structSize */ sizeof(OceanModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_EnableInEditmode, + + /* copyData */ copyData, + /* deformMatrices_DM */ NULL, + + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ freeData, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ dependsOnNormals, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, + /* freeRuntimeData */ NULL, }; |