Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_ocean.c')
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c719
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,
};