33#include "RNA_prototypes.hh"
78 simulate_ocean_modifier(omd);
116 simulate_ocean_modifier(tomd);
141struct GenerateOceanGeometryData {
142 blender::MutableSpan<blender::float3> vert_positions;
143 blender::MutableSpan<int> face_offsets;
144 blender::MutableSpan<int> corner_verts;
154static void generate_ocean_geometry_verts(
void *__restrict userdata,
158 GenerateOceanGeometryData *gogd =
static_cast<GenerateOceanGeometryData *
>(userdata);
161 for (
x = 0;
x <= gogd->res_x;
x++) {
162 const int i =
y * (gogd->res_x + 1) +
x;
163 float *co = gogd->vert_positions[
i];
164 co[0] = gogd->ox + (
x * gogd->sx);
165 co[1] = gogd->oy + (
y * gogd->sy);
170static void generate_ocean_geometry_faces(
void *__restrict userdata,
174 GenerateOceanGeometryData *gogd =
static_cast<GenerateOceanGeometryData *
>(userdata);
177 for (
x = 0;
x < gogd->res_x;
x++) {
178 const int fi =
y * gogd->res_x +
x;
179 const int vi =
y * (gogd->res_x + 1) +
x;
181 gogd->corner_verts[fi * 4 + 0] = vi;
182 gogd->corner_verts[fi * 4 + 1] = vi + 1;
183 gogd->corner_verts[fi * 4 + 2] = vi + 1 + gogd->res_x + 1;
184 gogd->corner_verts[fi * 4 + 3] = vi + gogd->res_x + 1;
186 gogd->face_offsets[fi] = fi * 4;
190static void generate_ocean_geometry_uvs(
void *__restrict userdata,
194 GenerateOceanGeometryData *gogd =
static_cast<GenerateOceanGeometryData *
>(userdata);
197 for (
x = 0;
x < gogd->res_x;
x++) {
198 const int i =
y * gogd->res_x +
x;
199 float (*luv)[2] = &gogd->uv_map[
i * 4];
201 (*luv)[0] =
x * gogd->ix;
202 (*luv)[1] =
y * gogd->iy;
205 (*luv)[0] = (
x + 1) * gogd->ix;
206 (*luv)[1] =
y * gogd->iy;
209 (*luv)[0] = (
x + 1) * gogd->ix;
210 (*luv)[1] = (
y + 1) * gogd->iy;
213 (*luv)[0] =
x * gogd->ix;
214 (*luv)[1] = (
y + 1) * gogd->iy;
223 GenerateOceanGeometryData gogd;
228 const bool use_threading = resolution > 4;
230 gogd.rx = resolution * resolution;
231 gogd.ry = resolution * resolution;
232 gogd.res_x = gogd.rx * omd->
repeat_x;
233 gogd.res_y = gogd.ry * omd->
repeat_y;
235 verts_num = (gogd.res_x + 1) * (gogd.res_y + 1);
236 faces_num = gogd.res_x * gogd.res_y;
240 gogd.ox = -gogd.sx / 2.0f;
241 gogd.oy = -gogd.sy / 2.0f;
249 gogd.vert_positions =
result->vert_positions_for_write();
250 gogd.face_offsets =
result->face_offsets_for_write();
251 gogd.corner_verts =
result->corner_verts_for_write();
271 gogd.ix = 1.0 / gogd.rx;
272 gogd.iy = 1.0 / gogd.ry;
274 BLI_task_parallel_range(0, gogd.res_y, &gogd, generate_ocean_geometry_uvs, &settings);
290 bool allocated_ocean =
false;
296 omd->viewport_resolution;
305# define OCEAN_CO(_size_co_inv, _v) ((_v * _size_co_inv) + 0.5f)
310 if (!isfinite(size_co_inv)) {
317 init_cache_data(ob, omd, resolution);
328 simulate_ocean_modifier(omd);
332 result = generate_ocean_geometry(omd, mesh, resolution);
338 cfra_for_cache = cfra_scene;
355 MLoopCol *mloopcols_spray =
nullptr;
366 for (
const int i :
faces.index_range()) {
368 const int *corner_vert = &corner_verts[face.
start()];
373 mlcolspray = &mloopcols_spray[face.
start()];
376 for (j = face.
size(); j--; corner_vert++, mlcol++) {
377 const float *vco = positions[*corner_vert];
378 const float u = OCEAN_CO(size_co_inv, vco[0]);
379 const float v = OCEAN_CO(size_co_inv, vco[1]);
385 CLAMP(foam, 0.0f, 1.0f);
392 mlcol->
r = mlcol->
g = mlcol->
b = char(foam * 255);
398 mlcolspray->
r = ocr.
Eminus[0] * 255;
401 mlcolspray->
r = ocr.
Eplus[0] * 255;
405 mlcolspray->
b = ocr.
Eminus[2] * 255;
408 mlcolspray->
b = ocr.
Eplus[2] * 255;
422 const int verts_num =
result->verts_num;
424 for (
i = 0;
i < verts_num;
i++) {
425 float *vco = positions[
i];
426 const float u = OCEAN_CO(size_co_inv, vco[0]);
427 const float v = OCEAN_CO(size_co_inv, vco[1]);
436 vco[2] += ocr.
disp[1];
439 vco[0] += ocr.
disp[0];
440 vco[1] += ocr.
disp[2];
445 result->tag_positions_changed();
447 if (allocated_ocean) {
449 omd->
ocean =
nullptr;
482 sub = &
col->column(
true);
487 sub = &
col->column(
true);
504 layout->
label(
RPT_(
"Built without Ocean modifier"), ICON_NONE);
528 sub = &
col->column(
false);
534static void foam_panel_draw_header(
const bContext * ,
Panel *panel)
555 col->active_set(use_foam);
560static void spray_panel_draw_header(
const bContext * ,
Panel *panel)
569 row = &layout->
row(
false);
588 col->active_set(use_foam && use_spray);
593static void spectrum_panel_draw(
const bContext * ,
Panel *panel)
644 col->enabled_set(!is_cached);
649 col->active_set(use_foam);
660 region_type,
"foam",
"", foam_panel_draw_header, foam_panel_draw, panel_type);
662 region_type,
"spray",
"", spray_panel_draw_header, spray_panel_draw, foam_panel);
664 region_type,
"spectrum",
"Spectrum",
nullptr, spectrum_panel_draw, panel_type);
675 omd->
ocean =
nullptr;
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_modifier_path_init(char *path, int path_maxncpy, const char *name)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
const char * BKE_modifier_path_relbase_from_global(Object *ob)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
struct Ocean * BKE_ocean_add(void)
void BKE_ocean_cache_eval_uv(struct OceanCache *och, struct OceanResult *ocr, int f, float u, float v)
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)
void BKE_ocean_simulate_cache(struct OceanCache *och, int frame)
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)
bool BKE_ocean_is_valid(const struct Ocean *o)
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 BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_ID_MESH
float DEG_get_ctime(const Depsgraph *graph)
#define DNA_struct_default_get(struct_name)
@ MOD_OCEAN_GENERATE_FOAM
@ MOD_OCEAN_GENERATE_SPRAY
@ MOD_OCEAN_GEOM_GENERATE
@ MOD_OCEAN_GEOM_DISPLACE
@ MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE
@ MOD_OCEAN_SPECTRUM_JONSWAP
Object is a sort of wrapper for general info.
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void free_data(ModifierData *md)
static void init_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static void blend_read(BlendDataReader *, ModifierData *md)
static Mesh * modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static void free_data(ModifierData *md)
ModifierTypeInfo modifierType_Ocean
static void required_data_mask(ModifierData *, CustomData_MeshMasks *)
static Mesh * doOcean(ModifierData *, const ModifierEvalContext *, Mesh *mesh)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
PanelType * modifier_subpanel_register(ARegionType *region_type, const char *name, const char *label, PanelDrawFn draw_header, PanelDrawFn draw, PanelType *parent)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_error_message_draw(uiLayout *layout, PointerRNA *ptr)
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
struct OceanCache * oceancache
void label(blender::StringRef name, int icon)
uiLayout & column(bool align)
void active_set(bool active)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)