Blender  V3.3
MOD_ocean.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright Blender Foundation. All rights reserved. */
3 
8 #include "BLI_utildefines.h"
9 
10 #include "BLI_math.h"
11 #include "BLI_math_inline.h"
12 #include "BLI_task.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "DNA_customdata_types.h"
17 #include "DNA_defaults.h"
18 #include "DNA_mesh_types.h"
19 #include "DNA_meshdata_types.h"
20 #include "DNA_modifier_types.h"
21 #include "DNA_object_types.h"
22 #include "DNA_scene_types.h"
23 #include "DNA_screen_types.h"
24 
25 #include "BKE_context.h"
26 #include "BKE_lib_id.h"
27 #include "BKE_mesh.h"
28 #include "BKE_modifier.h"
29 #include "BKE_ocean.h"
30 #include "BKE_screen.h"
31 
32 #include "UI_interface.h"
33 #include "UI_resources.h"
34 
35 #include "RNA_access.h"
36 #include "RNA_prototypes.h"
37 
38 #include "BLO_read_write.h"
39 
40 #include "WM_types.h" /* For UI free bake operator. */
41 
42 #include "DEG_depsgraph_query.h"
43 
44 #include "MOD_modifiertypes.h"
45 #include "MOD_ui_common.h"
46 
47 #ifdef WITH_OCEANSIM
48 static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution)
49 {
50  const char *relbase = BKE_modifier_path_relbase_from_global(ob);
51 
53  relbase,
54  omd->bakestart,
55  omd->bakeend,
56  omd->wave_scale,
57  omd->chop_amount,
58  omd->foam_coverage,
59  omd->foam_fade,
60  resolution);
61 }
62 
63 static void simulate_ocean_modifier(struct OceanModifierData *omd)
64 {
65  BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
66 }
67 #endif /* WITH_OCEANSIM */
68 
69 /* Modifier Code */
70 
71 static void initData(ModifierData *md)
72 {
73 #ifdef WITH_OCEANSIM
75 
77 
79 
80  BKE_modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean");
81 
82  omd->ocean = BKE_ocean_add();
84  simulate_ocean_modifier(omd);
85  }
86 #else /* WITH_OCEANSIM */
87  UNUSED_VARS(md);
88 #endif /* WITH_OCEANSIM */
89 }
90 
91 static void freeData(ModifierData *md)
92 {
93 #ifdef WITH_OCEANSIM
95 
96  BKE_ocean_free(omd->ocean);
97  if (omd->oceancache) {
99  }
100 #else /* WITH_OCEANSIM */
101  /* unused */
102  (void)md;
103 #endif /* WITH_OCEANSIM */
104 }
105 
106 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
107 {
108 #ifdef WITH_OCEANSIM
109 # if 0
110  const OceanModifierData *omd = (const OceanModifierData *)md;
111 # endif
112  OceanModifierData *tomd = (OceanModifierData *)target;
113 
114  BKE_modifier_copydata_generic(md, target, flag);
115 
116  /* The oceancache object will be recreated for this copy
117  * automatically when cached=true */
118  tomd->oceancache = NULL;
119 
120  tomd->ocean = BKE_ocean_add();
121  if (BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution)) {
122  simulate_ocean_modifier(tomd);
123  }
124 #else /* WITH_OCEANSIM */
125  /* unused */
126  (void)md;
127  (void)target;
128  (void)flag;
129 #endif /* WITH_OCEANSIM */
130 }
131 
132 #ifdef WITH_OCEANSIM
133 static void requiredDataMask(Object *UNUSED(ob),
134  ModifierData *md,
135  CustomData_MeshMasks *r_cddata_masks)
136 {
138 
139  if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
140  r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */
141  }
142 }
143 #else /* WITH_OCEANSIM */
144 static void requiredDataMask(Object *UNUSED(ob),
145  ModifierData *UNUSED(md),
146  CustomData_MeshMasks *UNUSED(r_cddata_masks))
147 {
148 }
149 #endif /* WITH_OCEANSIM */
150 
152 {
154  return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE);
155 }
156 
157 #ifdef WITH_OCEANSIM
158 
159 typedef struct GenerateOceanGeometryData {
160  MVert *mverts;
161  MPoly *mpolys;
162  MLoop *mloops;
163  MLoopUV *mloopuvs;
164 
165  int res_x, res_y;
166  int rx, ry;
167  float ox, oy;
168  float sx, sy;
169  float ix, iy;
170 } GenerateOceanGeometryData;
171 
172 static void generate_ocean_geometry_vertices(void *__restrict userdata,
173  const int y,
174  const TaskParallelTLS *__restrict UNUSED(tls))
175 {
176  GenerateOceanGeometryData *gogd = userdata;
177  int x;
178 
179  for (x = 0; x <= gogd->res_x; x++) {
180  const int i = y * (gogd->res_x + 1) + x;
181  float *co = gogd->mverts[i].co;
182  co[0] = gogd->ox + (x * gogd->sx);
183  co[1] = gogd->oy + (y * gogd->sy);
184  co[2] = 0.0f;
185  }
186 }
187 
188 static void generate_ocean_geometry_polygons(void *__restrict userdata,
189  const int y,
190  const TaskParallelTLS *__restrict UNUSED(tls))
191 {
192  GenerateOceanGeometryData *gogd = userdata;
193  int x;
194 
195  for (x = 0; x < gogd->res_x; x++) {
196  const int fi = y * gogd->res_x + x;
197  const int vi = y * (gogd->res_x + 1) + x;
198  MPoly *mp = &gogd->mpolys[fi];
199  MLoop *ml = &gogd->mloops[fi * 4];
200 
201  ml->v = vi;
202  ml++;
203  ml->v = vi + 1;
204  ml++;
205  ml->v = vi + 1 + gogd->res_x + 1;
206  ml++;
207  ml->v = vi + gogd->res_x + 1;
208  ml++;
209 
210  mp->loopstart = fi * 4;
211  mp->totloop = 4;
212 
213  mp->flag |= ME_SMOOTH;
214  }
215 }
216 
217 static void generate_ocean_geometry_uvs(void *__restrict userdata,
218  const int y,
219  const TaskParallelTLS *__restrict UNUSED(tls))
220 {
221  GenerateOceanGeometryData *gogd = userdata;
222  int x;
223 
224  for (x = 0; x < gogd->res_x; x++) {
225  const int i = y * gogd->res_x + x;
226  MLoopUV *luv = &gogd->mloopuvs[i * 4];
227 
228  luv->uv[0] = x * gogd->ix;
229  luv->uv[1] = y * gogd->iy;
230  luv++;
231 
232  luv->uv[0] = (x + 1) * gogd->ix;
233  luv->uv[1] = y * gogd->iy;
234  luv++;
235 
236  luv->uv[0] = (x + 1) * gogd->ix;
237  luv->uv[1] = (y + 1) * gogd->iy;
238  luv++;
239 
240  luv->uv[0] = x * gogd->ix;
241  luv->uv[1] = (y + 1) * gogd->iy;
242  luv++;
243  }
244 }
245 
246 static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution)
247 {
248  Mesh *result;
249 
250  GenerateOceanGeometryData gogd;
251 
252  int verts_num;
253  int polys_num;
254 
255  const bool use_threading = resolution > 4;
256 
257  gogd.rx = resolution * resolution;
258  gogd.ry = resolution * resolution;
259  gogd.res_x = gogd.rx * omd->repeat_x;
260  gogd.res_y = gogd.ry * omd->repeat_y;
261 
262  verts_num = (gogd.res_x + 1) * (gogd.res_y + 1);
263  polys_num = gogd.res_x * gogd.res_y;
264 
265  gogd.sx = omd->size * omd->spatial_size;
266  gogd.sy = omd->size * omd->spatial_size;
267  gogd.ox = -gogd.sx / 2.0f;
268  gogd.oy = -gogd.sy / 2.0f;
269 
270  gogd.sx /= gogd.rx;
271  gogd.sy /= gogd.ry;
272 
273  result = BKE_mesh_new_nomain(verts_num, 0, 0, polys_num * 4, polys_num);
275 
276  gogd.mverts = result->mvert;
277  gogd.mpolys = result->mpoly;
278  gogd.mloops = result->mloop;
279 
280  TaskParallelSettings settings;
282  settings.use_threading = use_threading;
283 
284  /* create vertices */
285  BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings);
286 
287  /* create faces */
288  BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings);
289 
290  BKE_mesh_calc_edges(result, false, false);
291 
292  /* add uvs */
294  gogd.mloopuvs = CustomData_add_layer(
295  &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, polys_num * 4);
296 
297  if (gogd.mloopuvs) { /* unlikely to fail */
298  gogd.ix = 1.0 / gogd.rx;
299  gogd.iy = 1.0 / gogd.ry;
300 
301  BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings);
302  }
303  }
304 
305  return result;
306 }
307 
308 static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
309 {
311  if (omd->ocean && !BKE_ocean_is_valid(omd->ocean)) {
312  BKE_modifier_set_error(ctx->object, md, "Failed to allocate memory");
313  return mesh;
314  }
315  int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph);
316  Object *ob = ctx->object;
317  bool allocated_ocean = false;
318 
319  Mesh *result = NULL;
320  OceanResult ocr;
321 
322  const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution :
323  omd->viewport_resolution;
324 
325  MVert *mverts;
326 
327  int cfra_for_cache;
328  int i, j;
329 
330  /* use cached & inverted value for speed
331  * expanded this would read...
332  *
333  * (axis / (omd->size * omd->spatial_size)) + 0.5f) */
334 # define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)
335 
336  const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);
337 
338  /* can happen in when size is small, avoid bad array lookups later and quit now */
339  if (!isfinite(size_co_inv)) {
340  return mesh;
341  }
342 
343  /* do ocean simulation */
344  if (omd->cached == true) {
345  if (!omd->oceancache) {
346  init_cache_data(ob, omd, resolution);
347  }
348  BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
349  }
350  else {
351  /* omd->ocean is NULL on an original object (in contrast to an evaluated one).
352  * We can create a new one, but we have to free it as well once we're done.
353  * This function is only called on an original object when applying the modifier
354  * using the 'Apply Modifier' button, and thus it is not called frequently for
355  * simulation. */
356  allocated_ocean |= BKE_ocean_ensure(omd, resolution);
357  simulate_ocean_modifier(omd);
358  }
359 
361  result = generate_ocean_geometry(omd, mesh, resolution);
362  }
363  else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
365  }
366 
367  cfra_for_cache = cfra_scene;
368  CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend);
369  cfra_for_cache -= omd->bakestart; /* shift to 0 based */
370 
371  mverts = result->mvert;
372 
373  /* add vcols before displacement - allows lookup based on position */
374 
375  if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
376  const int polys_num = result->totpoly;
377  const int loops_num = result->totloop;
378  MLoop *mloops = result->mloop;
380  &result->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, NULL, loops_num, omd->foamlayername);
381 
382  MLoopCol *mloopcols_spray = NULL;
383  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
384  mloopcols_spray = CustomData_add_layer_named(
385  &result->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, NULL, loops_num, omd->spraylayername);
386  }
387 
388  if (mloopcols) { /* unlikely to fail */
389  MPoly *mpolys = result->mpoly;
390  MPoly *mp;
391 
392  for (i = 0, mp = mpolys; i < polys_num; i++, mp++) {
393  MLoop *ml = &mloops[mp->loopstart];
394  MLoopCol *mlcol = &mloopcols[mp->loopstart];
395 
396  MLoopCol *mlcolspray = NULL;
397  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
398  mlcolspray = &mloopcols_spray[mp->loopstart];
399  }
400 
401  for (j = mp->totloop; j--; ml++, mlcol++) {
402  const float *vco = mverts[ml->v].co;
403  const float u = OCEAN_CO(size_co_inv, vco[0]);
404  const float v = OCEAN_CO(size_co_inv, vco[1]);
405  float foam;
406 
407  if (omd->oceancache && omd->cached == true) {
408  BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
409  foam = ocr.foam;
410  CLAMP(foam, 0.0f, 1.0f);
411  }
412  else {
413  BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
415  }
416 
417  mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
418  /* This needs to be set (render engine uses) */
419  mlcol->a = 255;
420 
421  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
422  if (omd->flag & MOD_OCEAN_INVERT_SPRAY) {
423  mlcolspray->r = ocr.Eminus[0] * 255;
424  }
425  else {
426  mlcolspray->r = ocr.Eplus[0] * 255;
427  }
428  mlcolspray->g = 0;
429  if (omd->flag & MOD_OCEAN_INVERT_SPRAY) {
430  mlcolspray->b = ocr.Eminus[2] * 255;
431  }
432  else {
433  mlcolspray->b = ocr.Eplus[2] * 255;
434  }
435  mlcolspray->a = 255;
436  }
437  }
438  }
439  }
440  }
441 
442  /* displace the geometry */
443 
444  /* NOTE: tried to parallelized that one and previous foam loop,
445  * but gives 20% slower results... odd. */
446  {
447  const int verts_num = result->totvert;
448 
449  for (i = 0; i < verts_num; i++) {
450  float *vco = mverts[i].co;
451  const float u = OCEAN_CO(size_co_inv, vco[0]);
452  const float v = OCEAN_CO(size_co_inv, vco[1]);
453 
454  if (omd->oceancache && omd->cached == true) {
455  BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
456  }
457  else {
458  BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
459  }
460 
461  vco[2] += ocr.disp[1];
462 
463  if (omd->chop_amount > 0.0f) {
464  vco[0] += ocr.disp[0];
465  vco[1] += ocr.disp[2];
466  }
467  }
468  }
469 
471 
472  if (allocated_ocean) {
473  BKE_ocean_free(omd->ocean);
474  omd->ocean = NULL;
475  }
476 
477 # undef OCEAN_CO
478 
479  return result;
480 }
481 #else /* WITH_OCEANSIM */
483 {
484  return mesh;
485 }
486 #endif /* WITH_OCEANSIM */
487 
489 {
490  return doOcean(md, ctx, mesh);
491 }
492 // #define WITH_OCEANSIM
493 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
494 {
495  uiLayout *layout = panel->layout;
496 #ifdef WITH_OCEANSIM
497  uiLayout *col, *sub;
498 
499  PointerRNA ob_ptr;
501 
502  uiLayoutSetPropSep(layout, true);
503 
504  col = uiLayoutColumn(layout, false);
505  uiItemR(col, ptr, "geometry_mode", 0, NULL, ICON_NONE);
506  if (RNA_enum_get(ptr, "geometry_mode") == MOD_OCEAN_GEOM_GENERATE) {
507  sub = uiLayoutColumn(col, true);
508  uiItemR(sub, ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE);
509  uiItemR(sub, ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE);
510  }
511 
512  sub = uiLayoutColumn(col, true);
513  uiItemR(sub, ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE);
514  uiItemR(sub, ptr, "resolution", 0, IFACE_("Render"), ICON_NONE);
515 
516  uiItemR(col, ptr, "time", 0, NULL, ICON_NONE);
517 
518  uiItemR(col, ptr, "depth", 0, NULL, ICON_NONE);
519  uiItemR(col, ptr, "size", 0, NULL, ICON_NONE);
520  uiItemR(col, ptr, "spatial_size", 0, NULL, ICON_NONE);
521 
522  uiItemR(col, ptr, "random_seed", 0, NULL, ICON_NONE);
523 
524  uiItemR(col, ptr, "use_normals", 0, NULL, ICON_NONE);
525 
526  modifier_panel_end(layout, ptr);
527 
528 #else /* WITH_OCEANSIM */
529  uiItemL(layout, TIP_("Built without Ocean modifier"), ICON_NONE);
530 #endif /* WITH_OCEANSIM */
531 }
532 
533 #ifdef WITH_OCEANSIM
534 static void waves_panel_draw(const bContext *UNUSED(C), Panel *panel)
535 {
536  uiLayout *col, *sub;
537  uiLayout *layout = panel->layout;
538 
540 
541  uiLayoutSetPropSep(layout, true);
542 
543  col = uiLayoutColumn(layout, false);
544  uiItemR(col, ptr, "wave_scale", 0, IFACE_("Scale"), ICON_NONE);
545  uiItemR(col, ptr, "wave_scale_min", 0, NULL, ICON_NONE);
546  uiItemR(col, ptr, "choppiness", 0, NULL, ICON_NONE);
547  uiItemR(col, ptr, "wind_velocity", 0, NULL, ICON_NONE);
548 
549  uiItemS(layout);
550 
551  col = uiLayoutColumn(layout, false);
552  uiItemR(col, ptr, "wave_alignment", UI_ITEM_R_SLIDER, IFACE_("Alignment"), ICON_NONE);
553  sub = uiLayoutColumn(col, false);
554  uiLayoutSetActive(sub, RNA_float_get(ptr, "wave_alignment") > 0.0f);
555  uiItemR(sub, ptr, "wave_direction", 0, IFACE_("Direction"), ICON_NONE);
556  uiItemR(sub, ptr, "damping", 0, NULL, ICON_NONE);
557 }
558 
559 static void foam_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
560 {
561  uiLayout *layout = panel->layout;
562 
564 
565  uiItemR(layout, ptr, "use_foam", 0, IFACE_("Foam"), ICON_NONE);
566 }
567 
568 static void foam_panel_draw(const bContext *UNUSED(C), Panel *panel)
569 {
570  uiLayout *col;
571  uiLayout *layout = panel->layout;
572 
574 
575  bool use_foam = RNA_boolean_get(ptr, "use_foam");
576 
577  uiLayoutSetPropSep(layout, true);
578 
579  col = uiLayoutColumn(layout, false);
580  uiLayoutSetActive(col, use_foam);
581  uiItemR(col, ptr, "foam_layer_name", 0, IFACE_("Data Layer"), ICON_NONE);
582  uiItemR(col, ptr, "foam_coverage", 0, IFACE_("Coverage"), ICON_NONE);
583 }
584 
585 static void spray_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
586 {
587  uiLayout *row;
588  uiLayout *layout = panel->layout;
589 
591 
592  bool use_foam = RNA_boolean_get(ptr, "use_foam");
593 
594  row = uiLayoutRow(layout, false);
595  uiLayoutSetActive(row, use_foam);
596  uiItemR(row, ptr, "use_spray", 0, IFACE_("Spray"), ICON_NONE);
597 }
598 
599 static void spray_panel_draw(const bContext *UNUSED(C), Panel *panel)
600 {
601  uiLayout *col;
602  uiLayout *layout = panel->layout;
603 
605 
606  bool use_foam = RNA_boolean_get(ptr, "use_foam");
607  bool use_spray = RNA_boolean_get(ptr, "use_spray");
608 
609  uiLayoutSetPropSep(layout, true);
610 
611  col = uiLayoutColumn(layout, false);
612  uiLayoutSetActive(col, use_foam && use_spray);
613  uiItemR(col, ptr, "spray_layer_name", 0, IFACE_("Data Layer"), ICON_NONE);
614  uiItemR(col, ptr, "invert_spray", 0, IFACE_("Invert"), ICON_NONE);
615 }
616 
617 static void spectrum_panel_draw(const bContext *UNUSED(C), Panel *panel)
618 {
619  uiLayout *col;
620  uiLayout *layout = panel->layout;
621 
623 
624  int spectrum = RNA_enum_get(ptr, "spectrum");
625 
626  uiLayoutSetPropSep(layout, true);
627 
628  col = uiLayoutColumn(layout, false);
629  uiItemR(col, ptr, "spectrum", 0, NULL, ICON_NONE);
631  uiItemR(col, ptr, "sharpen_peak_jonswap", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
632  uiItemR(col, ptr, "fetch_jonswap", 0, NULL, ICON_NONE);
633  }
634 }
635 
636 static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel)
637 {
638  uiLayout *col;
639  uiLayout *layout = panel->layout;
640 
642 
643  uiLayoutSetPropSep(layout, true);
644 
645  bool is_cached = RNA_boolean_get(ptr, "is_cached");
646  bool use_foam = RNA_boolean_get(ptr, "use_foam");
647 
648  if (is_cached) {
649  PointerRNA op_ptr;
650  uiItemFullO(layout,
651  "OBJECT_OT_ocean_bake",
652  IFACE_("Delete Bake"),
653  ICON_NONE,
654  NULL,
656  0,
657  &op_ptr);
658  RNA_boolean_set(&op_ptr, "free", true);
659  }
660  else {
661  uiItemO(layout, NULL, ICON_NONE, "OBJECT_OT_ocean_bake");
662  }
663 
664  uiItemR(layout, ptr, "filepath", 0, NULL, ICON_NONE);
665 
666  col = uiLayoutColumn(layout, true);
667  uiLayoutSetEnabled(col, !is_cached);
668  uiItemR(col, ptr, "frame_start", 0, IFACE_("Frame Start"), ICON_NONE);
669  uiItemR(col, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
670 
671  col = uiLayoutColumn(layout, false);
672  uiLayoutSetActive(col, use_foam);
673  uiItemR(col, ptr, "bake_foam_fade", 0, NULL, ICON_NONE);
674 }
675 #endif /* WITH_OCEANSIM */
676 
677 static void panelRegister(ARegionType *region_type)
678 {
680 #ifdef WITH_OCEANSIM
681  modifier_subpanel_register(region_type, "waves", "Waves", NULL, waves_panel_draw, panel_type);
683  region_type, "foam", "", foam_panel_draw_header, foam_panel_draw, panel_type);
685  region_type, "spray", "", spray_panel_draw_header, spray_panel_draw, foam_panel);
687  region_type, "spectrum", "Spectrum", NULL, spectrum_panel_draw, panel_type);
688  modifier_subpanel_register(region_type, "bake", "Bake", NULL, bake_panel_draw, panel_type);
689 #else
690  UNUSED_VARS(panel_type);
691 #endif /* WITH_OCEANSIM */
692 }
693 
694 static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
695 {
697  omd->oceancache = NULL;
698  omd->ocean = NULL;
699 }
700 
702  /* name */ N_("Ocean"),
703  /* structName */ "OceanModifierData",
704  /* structSize */ sizeof(OceanModifierData),
705  /* srna */ &RNA_OceanModifier,
709  /* icon */ ICON_MOD_OCEAN,
710 
711  /* copyData */ copyData,
712  /* deformMatrices_DM */ NULL,
713 
714  /* deformMatrices */ NULL,
715  /* deformVertsEM */ NULL,
716  /* deformMatricesEM */ NULL,
717  /* modifyMesh */ modifyMesh,
718  /* modifyGeometrySet */ NULL,
719 
720  /* initData */ initData,
721  /* requiredDataMask */ requiredDataMask,
722  /* freeData */ freeData,
723  /* isDisabled */ NULL,
724  /* updateDepsgraph */ NULL,
725  /* dependsOnTime */ NULL,
726  /* dependsOnNormals */ dependsOnNormals,
727  /* foreachIDLink */ NULL,
728  /* foreachTexLink */ NULL,
729  /* freeRuntimeData */ NULL,
730  /* panelRegister */ panelRegister,
731  /* blendWrite */ NULL,
732  /* blendRead */ blendRead,
733 };
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_CALLOC
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.cc:2792
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void BKE_mesh_copy_parameters_for_eval(struct Mesh *me_dst, const struct Mesh *me_src)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
void BKE_mesh_tag_coords_changed(struct Mesh *mesh)
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, bool select_new_edges)
void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:78
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
const char * BKE_modifier_path_relbase_from_global(struct Object *ob)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:47
void BKE_modifier_set_error(const struct Object *ob, struct ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
@ MOD_APPLY_RENDER
Definition: BKE_modifier.h:115
void BKE_ocean_cache_eval_uv(struct OceanCache *och, struct OceanResult *ocr, int f, float u, float v)
struct OceanCache * BKE_ocean_init_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale, float chop_amount, float foam_coverage, float foam_fade, int resolution)
void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount)
float BKE_ocean_jminus_to_foam(float jminus, float coverage)
bool BKE_ocean_ensure(struct OceanModifierData *omd, int resolution)
void BKE_ocean_free_cache(struct OceanCache *och)
Definition: ocean.c:1655
void BKE_ocean_simulate_cache(struct OceanCache *och, int frame)
struct Ocean * BKE_ocean_add(void)
Definition: ocean.c:1608
void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
bool BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd, int resolution)
void BKE_ocean_free(struct Ocean *oc)
Definition: ocean.c:1645
bool BKE_ocean_is_valid(const struct Ocean *o)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
#define UNUSED_VARS(...)
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define TIP_(msgid)
#define IFACE_(msgid)
float DEG_get_ctime(const Depsgraph *graph)
#define CD_MASK_MCOL
@ CD_PROP_BYTE_COLOR
@ CD_MLOOPUV
#define MAX_MTFACE
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ ME_SMOOTH
@ MOD_OCEAN_GEOM_GENERATE
@ MOD_OCEAN_GEOM_DISPLACE
@ MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE
@ MOD_OCEAN_SPECTRUM_JONSWAP
@ MOD_OCEAN_GENERATE_FOAM
@ MOD_OCEAN_INVERT_SPRAY
@ MOD_OCEAN_GENERATE_SPRAY
@ eModifierType_Ocean
struct OceanModifierData OceanModifierData
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel)
static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
Definition: MOD_ocean.c:694
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_ocean.c:106
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition: MOD_ocean.c:488
static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *UNUSED(r_cddata_masks))
Definition: MOD_ocean.c:144
static bool dependsOnNormals(ModifierData *md)
Definition: MOD_ocean.c:151
ModifierTypeInfo modifierType_Ocean
Definition: MOD_ocean.c:701
static Mesh * doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
Definition: MOD_ocean.c:482
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_ocean.c:493
static void initData(ModifierData *md)
Definition: MOD_ocean.c:71
static void panelRegister(ARegionType *region_type)
Definition: MOD_ocean.c:677
static void freeData(ModifierData *md)
Definition: MOD_ocean.c:91
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define C
Definition: RandGen.cpp:25
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_ITEM_R_SLIDER
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, wmOperatorCallContext context, int flag, struct PointerRNA *r_opptr)
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:208
ATTR_WARN_UNUSED_RESULT const BMVert * v
SyclQueue void void size_t num_bytes void
define("MAT_AOV_SUPPORT") .image_array_out(6
uint col
ccl_gpu_kernel_postfix ccl_global float int int sy
ccl_gpu_kernel_postfix ccl_global float int sx
bool isfinite(uchar)
Definition: scene/image.cpp:31
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
unsigned char a
unsigned char b
unsigned char r
unsigned char g
unsigned int v
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:140
ModifierApplyFlag flag
Definition: BKE_modifier.h:142
struct Object * object
Definition: BKE_modifier.h:141
struct OceanCache * oceancache
float Eplus[3]
Definition: BKE_ocean.h:26
float Eminus[3]
Definition: BKE_ocean.h:25
float disp[3]
Definition: BKE_ocean.h:18
float Jminus
Definition: BKE_ocean.h:23
float foam
Definition: BKE_ocean.h:20
struct uiLayout * layout
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480