Blender  V2.93
MOD_ocean.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) Blender Foundation
17  * All rights reserved.
18  */
19 
24 #include "BLI_utildefines.h"
25 
26 #include "BLI_math.h"
27 #include "BLI_math_inline.h"
28 #include "BLI_task.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "DNA_customdata_types.h"
33 #include "DNA_defaults.h"
34 #include "DNA_mesh_types.h"
35 #include "DNA_meshdata_types.h"
36 #include "DNA_modifier_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_screen_types.h"
40 
41 #include "BKE_context.h"
42 #include "BKE_lib_id.h"
43 #include "BKE_mesh.h"
44 #include "BKE_modifier.h"
45 #include "BKE_ocean.h"
46 #include "BKE_screen.h"
47 
48 #include "UI_interface.h"
49 #include "UI_resources.h"
50 
51 #include "RNA_access.h"
52 
53 #include "BLO_read_write.h"
54 
55 #include "WM_types.h" /* For UI free bake operator. */
56 
57 #include "DEG_depsgraph_query.h"
58 
59 #include "MOD_modifiertypes.h"
60 #include "MOD_ui_common.h"
61 
62 #ifdef WITH_OCEANSIM
63 static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution)
64 {
65  const char *relbase = BKE_modifier_path_relbase_from_global(ob);
66 
68  relbase,
69  omd->bakestart,
70  omd->bakeend,
71  omd->wave_scale,
72  omd->chop_amount,
73  omd->foam_coverage,
74  omd->foam_fade,
75  resolution);
76 }
77 
78 static void simulate_ocean_modifier(struct OceanModifierData *omd)
79 {
80  BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
81 }
82 #endif /* WITH_OCEANSIM */
83 
84 /* Modifier Code */
85 
86 static void initData(ModifierData *md)
87 {
88 #ifdef WITH_OCEANSIM
90 
92 
94 
95  BKE_modifier_path_init(omd->cachepath, sizeof(omd->cachepath), "cache_ocean");
96 
97  omd->ocean = BKE_ocean_add();
99  simulate_ocean_modifier(omd);
100 #else /* WITH_OCEANSIM */
101  UNUSED_VARS(md);
102 #endif /* WITH_OCEANSIM */
103 }
104 
105 static void freeData(ModifierData *md)
106 {
107 #ifdef WITH_OCEANSIM
109 
110  BKE_ocean_free(omd->ocean);
111  if (omd->oceancache) {
113  }
114 #else /* WITH_OCEANSIM */
115  /* unused */
116  (void)md;
117 #endif /* WITH_OCEANSIM */
118 }
119 
120 static void copyData(const ModifierData *md, ModifierData *target, const int flag)
121 {
122 #ifdef WITH_OCEANSIM
123 # if 0
124  const OceanModifierData *omd = (const OceanModifierData *)md;
125 # endif
126  OceanModifierData *tomd = (OceanModifierData *)target;
127 
128  BKE_modifier_copydata_generic(md, target, flag);
129 
130  /* The oceancache object will be recreated for this copy
131  * automatically when cached=true */
132  tomd->oceancache = NULL;
133 
134  tomd->ocean = BKE_ocean_add();
136  simulate_ocean_modifier(tomd);
137 #else /* WITH_OCEANSIM */
138  /* unused */
139  (void)md;
140  (void)target;
141  (void)flag;
142 #endif /* WITH_OCEANSIM */
143 }
144 
145 #ifdef WITH_OCEANSIM
146 static void requiredDataMask(Object *UNUSED(ob),
147  ModifierData *md,
148  CustomData_MeshMasks *r_cddata_masks)
149 {
151 
152  if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
153  r_cddata_masks->fmask |= CD_MASK_MCOL; /* XXX Should be loop cddata I guess? */
154  }
155 }
156 #else /* WITH_OCEANSIM */
157 static void requiredDataMask(Object *UNUSED(ob),
158  ModifierData *UNUSED(md),
159  CustomData_MeshMasks *UNUSED(r_cddata_masks))
160 {
161 }
162 #endif /* WITH_OCEANSIM */
163 
165 {
167  return (omd->geometry_mode != MOD_OCEAN_GEOM_GENERATE);
168 }
169 
170 #ifdef WITH_OCEANSIM
171 
172 typedef struct GenerateOceanGeometryData {
173  MVert *mverts;
174  MPoly *mpolys;
175  MLoop *mloops;
176  MLoopUV *mloopuvs;
177 
178  int res_x, res_y;
179  int rx, ry;
180  float ox, oy;
181  float sx, sy;
182  float ix, iy;
183 } GenerateOceanGeometryData;
184 
185 static void generate_ocean_geometry_vertices(void *__restrict userdata,
186  const int y,
187  const TaskParallelTLS *__restrict UNUSED(tls))
188 {
189  GenerateOceanGeometryData *gogd = userdata;
190  int x;
191 
192  for (x = 0; x <= gogd->res_x; x++) {
193  const int i = y * (gogd->res_x + 1) + x;
194  float *co = gogd->mverts[i].co;
195  co[0] = gogd->ox + (x * gogd->sx);
196  co[1] = gogd->oy + (y * gogd->sy);
197  co[2] = 0.0f;
198  }
199 }
200 
201 static void generate_ocean_geometry_polygons(void *__restrict userdata,
202  const int y,
203  const TaskParallelTLS *__restrict UNUSED(tls))
204 {
205  GenerateOceanGeometryData *gogd = userdata;
206  int x;
207 
208  for (x = 0; x < gogd->res_x; x++) {
209  const int fi = y * gogd->res_x + x;
210  const int vi = y * (gogd->res_x + 1) + x;
211  MPoly *mp = &gogd->mpolys[fi];
212  MLoop *ml = &gogd->mloops[fi * 4];
213 
214  ml->v = vi;
215  ml++;
216  ml->v = vi + 1;
217  ml++;
218  ml->v = vi + 1 + gogd->res_x + 1;
219  ml++;
220  ml->v = vi + gogd->res_x + 1;
221  ml++;
222 
223  mp->loopstart = fi * 4;
224  mp->totloop = 4;
225 
226  mp->flag |= ME_SMOOTH;
227  }
228 }
229 
230 static void generate_ocean_geometry_uvs(void *__restrict userdata,
231  const int y,
232  const TaskParallelTLS *__restrict UNUSED(tls))
233 {
234  GenerateOceanGeometryData *gogd = userdata;
235  int x;
236 
237  for (x = 0; x < gogd->res_x; x++) {
238  const int i = y * gogd->res_x + x;
239  MLoopUV *luv = &gogd->mloopuvs[i * 4];
240 
241  luv->uv[0] = x * gogd->ix;
242  luv->uv[1] = y * gogd->iy;
243  luv++;
244 
245  luv->uv[0] = (x + 1) * gogd->ix;
246  luv->uv[1] = y * gogd->iy;
247  luv++;
248 
249  luv->uv[0] = (x + 1) * gogd->ix;
250  luv->uv[1] = (y + 1) * gogd->iy;
251  luv++;
252 
253  luv->uv[0] = x * gogd->ix;
254  luv->uv[1] = (y + 1) * gogd->iy;
255  luv++;
256  }
257 }
258 
259 static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution)
260 {
261  Mesh *result;
262 
263  GenerateOceanGeometryData gogd;
264 
265  int num_verts;
266  int num_polys;
267 
268  const bool use_threading = resolution > 4;
269 
270  gogd.rx = resolution * resolution;
271  gogd.ry = resolution * resolution;
272  gogd.res_x = gogd.rx * omd->repeat_x;
273  gogd.res_y = gogd.ry * omd->repeat_y;
274 
275  num_verts = (gogd.res_x + 1) * (gogd.res_y + 1);
276  num_polys = gogd.res_x * gogd.res_y;
277 
278  gogd.sx = omd->size * omd->spatial_size;
279  gogd.sy = omd->size * omd->spatial_size;
280  gogd.ox = -gogd.sx / 2.0f;
281  gogd.oy = -gogd.sy / 2.0f;
282 
283  gogd.sx /= gogd.rx;
284  gogd.sy /= gogd.ry;
285 
286  result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys);
287  BKE_mesh_copy_settings(result, mesh_orig);
288 
289  gogd.mverts = result->mvert;
290  gogd.mpolys = result->mpoly;
291  gogd.mloops = result->mloop;
292 
293  TaskParallelSettings settings;
295  settings.use_threading = use_threading;
296 
297  /* create vertices */
298  BLI_task_parallel_range(0, gogd.res_y + 1, &gogd, generate_ocean_geometry_vertices, &settings);
299 
300  /* create faces */
301  BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_polygons, &settings);
302 
303  BKE_mesh_calc_edges(result, false, false);
304 
305  /* add uvs */
307  gogd.mloopuvs = CustomData_add_layer(
308  &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4);
309 
310  if (gogd.mloopuvs) { /* unlikely to fail */
311  gogd.ix = 1.0 / gogd.rx;
312  gogd.iy = 1.0 / gogd.ry;
313 
314  BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings);
315  }
316  }
317 
318  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
319 
320  return result;
321 }
322 
323 static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
324 {
326  int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph);
327  Object *ob = ctx->object;
328  bool allocated_ocean = false;
329 
330  Mesh *result = NULL;
331  OceanResult ocr;
332 
333  const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution :
334  omd->viewport_resolution;
335 
336  MVert *mverts;
337 
338  int cfra_for_cache;
339  int i, j;
340 
341  /* use cached & inverted value for speed
342  * expanded this would read...
343  *
344  * (axis / (omd->size * omd->spatial_size)) + 0.5f) */
345 # define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)
346 
347  const float size_co_inv = 1.0f / (omd->size * omd->spatial_size);
348 
349  /* can happen in when size is small, avoid bad array lookups later and quit now */
350  if (!isfinite(size_co_inv)) {
351  return mesh;
352  }
353 
354  /* do ocean simulation */
355  if (omd->cached == true) {
356  if (!omd->oceancache) {
357  init_cache_data(ob, omd, resolution);
358  }
359  BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
360  }
361  else {
362  /* omd->ocean is NULL on an original object (in contrast to an evaluated one).
363  * We can create a new one, but we have to free it as well once we're done.
364  * This function is only called on an original object when applying the modifier
365  * using the 'Apply Modifier' button, and thus it is not called frequently for
366  * simulation. */
367  allocated_ocean |= BKE_ocean_ensure(omd, resolution);
368  simulate_ocean_modifier(omd);
369  }
370 
372  result = generate_ocean_geometry(omd, mesh, resolution);
374  }
375  else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
377  }
378 
379  cfra_for_cache = cfra_scene;
380  CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend);
381  cfra_for_cache -= omd->bakestart; /* shift to 0 based */
382 
383  mverts = result->mvert;
384 
385  /* add vcols before displacement - allows lookup based on position */
386 
387  if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
389  const int num_polys = result->totpoly;
390  const int num_loops = result->totloop;
391  MLoop *mloops = result->mloop;
393  &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername);
394 
395  MLoopCol *mloopcols_spray = NULL;
396  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
397  mloopcols_spray = CustomData_add_layer_named(
398  &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->spraylayername);
399  }
400 
401  if (mloopcols) { /* unlikely to fail */
402  MPoly *mpolys = result->mpoly;
403  MPoly *mp;
404 
405  for (i = 0, mp = mpolys; i < num_polys; i++, mp++) {
406  MLoop *ml = &mloops[mp->loopstart];
407  MLoopCol *mlcol = &mloopcols[mp->loopstart];
408 
409  MLoopCol *mlcolspray = NULL;
410  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
411  mlcolspray = &mloopcols_spray[mp->loopstart];
412  }
413 
414  for (j = mp->totloop; j--; ml++, mlcol++) {
415  const float *vco = mverts[ml->v].co;
416  const float u = OCEAN_CO(size_co_inv, vco[0]);
417  const float v = OCEAN_CO(size_co_inv, vco[1]);
418  float foam;
419 
420  if (omd->oceancache && omd->cached == true) {
421  BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
422  foam = ocr.foam;
423  CLAMP(foam, 0.0f, 1.0f);
424  }
425  else {
426  BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
428  }
429 
430  mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255);
431  /* This needs to be set (render engine uses) */
432  mlcol->a = 255;
433 
434  if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
435  if (omd->flag & MOD_OCEAN_INVERT_SPRAY) {
436  mlcolspray->r = ocr.Eminus[0] * 255;
437  }
438  else {
439  mlcolspray->r = ocr.Eplus[0] * 255;
440  }
441  mlcolspray->g = 0;
442  if (omd->flag & MOD_OCEAN_INVERT_SPRAY) {
443  mlcolspray->b = ocr.Eminus[2] * 255;
444  }
445  else {
446  mlcolspray->b = ocr.Eplus[2] * 255;
447  }
448  mlcolspray->a = 255;
449  }
450  }
451  }
452  }
453  }
454  }
455 
456  /* displace the geometry */
457 
458  /* Note: tried to parallelized that one and previous foam loop,
459  * but gives 20% slower results... odd. */
460  {
461  const int num_verts = result->totvert;
462 
463  for (i = 0; i < num_verts; i++) {
464  float *vco = mverts[i].co;
465  const float u = OCEAN_CO(size_co_inv, vco[0]);
466  const float v = OCEAN_CO(size_co_inv, vco[1]);
467 
468  if (omd->oceancache && omd->cached == true) {
469  BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v);
470  }
471  else {
472  BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
473  }
474 
475  vco[2] += ocr.disp[1];
476 
477  if (omd->chop_amount > 0.0f) {
478  vco[0] += ocr.disp[0];
479  vco[1] += ocr.disp[2];
480  }
481  }
482  }
483 
484  if (allocated_ocean) {
485  BKE_ocean_free(omd->ocean);
486  omd->ocean = NULL;
487  }
488 
489 # undef OCEAN_CO
490 
491  return result;
492 }
493 #else /* WITH_OCEANSIM */
495 {
496  return mesh;
497 }
498 #endif /* WITH_OCEANSIM */
499 
501 {
502  Mesh *result;
503 
504  result = doOcean(md, ctx, mesh);
505 
506  if (result != mesh) {
507  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
508  }
509 
510  return result;
511 }
512 // #define WITH_OCEANSIM
513 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
514 {
515  uiLayout *layout = panel->layout;
516 #ifdef WITH_OCEANSIM
517  uiLayout *col, *sub;
518 
519  PointerRNA ob_ptr;
521 
522  uiLayoutSetPropSep(layout, true);
523 
524  col = uiLayoutColumn(layout, false);
525  uiItemR(col, ptr, "geometry_mode", 0, NULL, ICON_NONE);
526  if (RNA_enum_get(ptr, "geometry_mode") == MOD_OCEAN_GEOM_GENERATE) {
527  sub = uiLayoutColumn(col, true);
528  uiItemR(sub, ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE);
529  uiItemR(sub, ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE);
530  }
531 
532  sub = uiLayoutColumn(col, true);
533  uiItemR(sub, ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE);
534  uiItemR(sub, ptr, "resolution", 0, IFACE_("Render"), ICON_NONE);
535 
536  uiItemR(col, ptr, "time", 0, NULL, ICON_NONE);
537 
538  uiItemR(col, ptr, "depth", 0, NULL, ICON_NONE);
539  uiItemR(col, ptr, "size", 0, NULL, ICON_NONE);
540  uiItemR(col, ptr, "spatial_size", 0, NULL, ICON_NONE);
541 
542  uiItemR(col, ptr, "random_seed", 0, NULL, ICON_NONE);
543 
544  uiItemR(col, ptr, "use_normals", 0, NULL, ICON_NONE);
545 
546  modifier_panel_end(layout, ptr);
547 
548 #else /* WITH_OCEANSIM */
549  uiItemL(layout, IFACE_("Built without Ocean modifier"), ICON_NONE);
550 #endif /* WITH_OCEANSIM */
551 }
552 
553 #ifdef WITH_OCEANSIM
554 static void waves_panel_draw(const bContext *UNUSED(C), Panel *panel)
555 {
556  uiLayout *col, *sub;
557  uiLayout *layout = panel->layout;
558 
560 
561  uiLayoutSetPropSep(layout, true);
562 
563  col = uiLayoutColumn(layout, false);
564  uiItemR(col, ptr, "wave_scale", 0, IFACE_("Scale"), ICON_NONE);
565  uiItemR(col, ptr, "wave_scale_min", 0, NULL, ICON_NONE);
566  uiItemR(col, ptr, "choppiness", 0, NULL, ICON_NONE);
567  uiItemR(col, ptr, "wind_velocity", 0, NULL, ICON_NONE);
568 
569  uiItemS(layout);
570 
571  col = uiLayoutColumn(layout, false);
572  uiItemR(col, ptr, "wave_alignment", UI_ITEM_R_SLIDER, IFACE_("Alignment"), ICON_NONE);
573  sub = uiLayoutColumn(col, false);
574  uiLayoutSetActive(sub, RNA_float_get(ptr, "wave_alignment") > 0.0f);
575  uiItemR(sub, ptr, "wave_direction", 0, IFACE_("Direction"), ICON_NONE);
576  uiItemR(sub, ptr, "damping", 0, NULL, ICON_NONE);
577 }
578 
579 static void foam_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
580 {
581  uiLayout *layout = panel->layout;
582 
584 
585  uiItemR(layout, ptr, "use_foam", 0, IFACE_("Foam"), ICON_NONE);
586 }
587 
588 static void foam_panel_draw(const bContext *UNUSED(C), Panel *panel)
589 {
590  uiLayout *col;
591  uiLayout *layout = panel->layout;
592 
594 
595  bool use_foam = RNA_boolean_get(ptr, "use_foam");
596 
597  uiLayoutSetPropSep(layout, true);
598 
599  col = uiLayoutColumn(layout, false);
600  uiLayoutSetActive(col, use_foam);
601  uiItemR(col, ptr, "foam_layer_name", 0, IFACE_("Data Layer"), ICON_NONE);
602  uiItemR(col, ptr, "foam_coverage", 0, IFACE_("Coverage"), ICON_NONE);
603 }
604 
605 static void spray_panel_draw_header(const bContext *UNUSED(C), Panel *panel)
606 {
607  uiLayout *row;
608  uiLayout *layout = panel->layout;
609 
611 
612  bool use_foam = RNA_boolean_get(ptr, "use_foam");
613 
614  row = uiLayoutRow(layout, false);
615  uiLayoutSetActive(row, use_foam);
616  uiItemR(row, ptr, "use_spray", 0, IFACE_("Spray"), ICON_NONE);
617 }
618 
619 static void spray_panel_draw(const bContext *UNUSED(C), Panel *panel)
620 {
621  uiLayout *col;
622  uiLayout *layout = panel->layout;
623 
625 
626  bool use_foam = RNA_boolean_get(ptr, "use_foam");
627  bool use_spray = RNA_boolean_get(ptr, "use_spray");
628 
629  uiLayoutSetPropSep(layout, true);
630 
631  col = uiLayoutColumn(layout, false);
632  uiLayoutSetActive(col, use_foam && use_spray);
633  uiItemR(col, ptr, "spray_layer_name", 0, IFACE_("Data Layer"), ICON_NONE);
634  uiItemR(col, ptr, "invert_spray", 0, IFACE_("Invert"), ICON_NONE);
635 }
636 
637 static void spectrum_panel_draw(const bContext *UNUSED(C), Panel *panel)
638 {
639  uiLayout *col;
640  uiLayout *layout = panel->layout;
641 
643 
644  int spectrum = RNA_enum_get(ptr, "spectrum");
645 
646  uiLayoutSetPropSep(layout, true);
647 
648  col = uiLayoutColumn(layout, false);
649  uiItemR(col, ptr, "spectrum", 0, NULL, ICON_NONE);
651  uiItemR(col, ptr, "sharpen_peak_jonswap", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
652  uiItemR(col, ptr, "fetch_jonswap", 0, NULL, ICON_NONE);
653  }
654 }
655 
656 static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel)
657 {
658  uiLayout *col;
659  uiLayout *layout = panel->layout;
660 
662 
663  uiLayoutSetPropSep(layout, true);
664 
665  bool is_cached = RNA_boolean_get(ptr, "is_cached");
666  bool use_foam = RNA_boolean_get(ptr, "use_foam");
667 
668  if (is_cached) {
669  PointerRNA op_ptr;
670  uiItemFullO(layout,
671  "OBJECT_OT_ocean_bake",
672  IFACE_("Delete Bake"),
673  ICON_NONE,
674  NULL,
676  0,
677  &op_ptr);
678  RNA_boolean_set(&op_ptr, "free", true);
679  }
680  else {
681  uiItemO(layout, NULL, ICON_NONE, "OBJECT_OT_ocean_bake");
682  }
683 
684  uiItemR(layout, ptr, "filepath", 0, NULL, ICON_NONE);
685 
686  col = uiLayoutColumn(layout, true);
687  uiLayoutSetEnabled(col, !is_cached);
688  uiItemR(col, ptr, "frame_start", 0, IFACE_("Frame Start"), ICON_NONE);
689  uiItemR(col, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
690 
691  col = uiLayoutColumn(layout, false);
692  uiLayoutSetActive(col, use_foam);
693  uiItemR(col, ptr, "bake_foam_fade", 0, NULL, ICON_NONE);
694 }
695 #endif /* WITH_OCEANSIM */
696 
697 static void panelRegister(ARegionType *region_type)
698 {
700 #ifdef WITH_OCEANSIM
701  modifier_subpanel_register(region_type, "waves", "Waves", NULL, waves_panel_draw, panel_type);
703  region_type, "foam", "", foam_panel_draw_header, foam_panel_draw, panel_type);
705  region_type, "spray", "", spray_panel_draw_header, spray_panel_draw, foam_panel);
707  region_type, "spectrum", "Spectrum", NULL, spectrum_panel_draw, panel_type);
708  modifier_subpanel_register(region_type, "bake", "Bake", NULL, bake_panel_draw, panel_type);
709 #else
710  UNUSED_VARS(panel_type);
711 #endif /* WITH_OCEANSIM */
712 }
713 
714 static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
715 {
717  omd->oceancache = NULL;
718  omd->ocean = NULL;
719 }
720 
722  /* name */ "Ocean",
723  /* structName */ "OceanModifierData",
724  /* structSize */ sizeof(OceanModifierData),
725  /* srna */ &RNA_OceanModifier,
729  /* icon */ ICON_MOD_OCEAN,
730 
731  /* copyData */ copyData,
732  /* deformMatrices_DM */ NULL,
733 
734  /* deformMatrices */ NULL,
735  /* deformVertsEM */ NULL,
736  /* deformMatricesEM */ NULL,
737  /* modifyMesh */ modifyMesh,
738  /* modifyHair */ NULL,
739  /* modifyGeometrySet */ NULL,
740  /* modifyVolume */ NULL,
741 
742  /* initData */ initData,
743  /* requiredDataMask */ requiredDataMask,
744  /* freeData */ freeData,
745  /* isDisabled */ NULL,
746  /* updateDepsgraph */ NULL,
747  /* dependsOnTime */ NULL,
748  /* dependsOnNormals */ dependsOnNormals,
749  /* foreachIDLink */ NULL,
750  /* foreachTexLink */ NULL,
751  /* freeRuntimeData */ NULL,
752  /* panelRegister */ panelRegister,
753  /* blendWrite */ NULL,
754  /* blendRead */ blendRead,
755 };
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.c:2637
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:145
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_mesh_ensure_normals(struct Mesh *me)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.c:877
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, const bool select_new_edges)
void BKE_mesh_copy_settings(struct Mesh *me_dst, const struct Mesh *me_src)
void BKE_modifier_path_init(char *path, int path_maxlen, const char *name)
@ eModifierTypeFlag_EnableInEditmode
Definition: BKE_modifier.h:92
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:83
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:80
const char * BKE_modifier_path_relbase_from_global(struct Object *ob)
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:61
@ MOD_APPLY_RENDER
Definition: BKE_modifier.h:128
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)
void BKE_ocean_free_cache(struct OceanCache *och)
Definition: ocean.c:1650
void BKE_ocean_simulate_cache(struct OceanCache *och, int frame)
struct Ocean * BKE_ocean_add(void)
Definition: ocean.c:1604
void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
void BKE_ocean_free(struct Ocean *oc)
Definition: ocean.c:1640
void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd, const int resolution)
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#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 IFACE_(msgid)
float DEG_get_ctime(const Depsgraph *graph)
#define CD_MASK_NORMAL
#define CD_MASK_MCOL
#define MAX_MCOL
@ CD_MLOOPCOL
@ CD_MLOOPUV
#define MAX_MTFACE
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:44
@ ME_SMOOTH
@ MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE
@ MOD_OCEAN_SPECTRUM_JONSWAP
@ MOD_OCEAN_GEOM_GENERATE
@ MOD_OCEAN_GEOM_DISPLACE
@ eModifierType_Ocean
struct OceanModifierData OceanModifierData
@ MOD_OCEAN_GENERATE_FOAM
@ MOD_OCEAN_INVERT_SPRAY
@ MOD_OCEAN_GENERATE_SPRAY
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 blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
Definition: MOD_ocean.c:714
static void copyData(const ModifierData *md, ModifierData *target, const int flag)
Definition: MOD_ocean.c:120
static Mesh * modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
Definition: MOD_ocean.c:500
static void requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md), CustomData_MeshMasks *UNUSED(r_cddata_masks))
Definition: MOD_ocean.c:157
static bool dependsOnNormals(ModifierData *md)
Definition: MOD_ocean.c:164
ModifierTypeInfo modifierType_Ocean
Definition: MOD_ocean.c:721
static Mesh * doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
Definition: MOD_ocean.c:494
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
Definition: MOD_ocean.c:513
static void initData(ModifierData *md)
Definition: MOD_ocean.c:86
static void panelRegister(ARegionType *region_type)
Definition: MOD_ocean.c:697
static void freeData(ModifierData *md)
Definition: MOD_ocean.c:105
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
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 RGB to Bright Vector Camera CLAMP
StructRNA RNA_OceanModifier
#define C
Definition: RandGen.cpp:39
void uiLayoutSetActive(uiLayout *layout, bool active)
@ UI_ITEM_R_SLIDER
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
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)
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)
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
ATTR_WARN_UNUSED_RESULT const BMVert * v
uint col
bool isfinite(uchar)
Definition: image.cpp:44
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
unsigned char a
unsigned char b
unsigned char r
unsigned char g
unsigned int v
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
ModifierApplyFlag flag
Definition: BKE_modifier.h:155
struct Object * object
Definition: BKE_modifier.h:154
struct OceanCache * oceancache
float Eplus[3]
Definition: BKE_ocean.h:40
float Eminus[3]
Definition: BKE_ocean.h:39
float disp[3]
Definition: BKE_ocean.h:32
float Jminus
Definition: BKE_ocean.h:37
float foam
Definition: BKE_ocean.h:34
struct uiLayout * layout
PointerRNA * ptr
Definition: wm_files.c:3157