Ocean Modifier: Add viewport resolution
Following work done in 2.83, the resolution control is now a real level-of-detail parameter. It is now useful to be able to set the resolution for display independently from render. This is true for both mesh generation and mesh deformation modes. For compatibility with old scenes, resolution is retained and is the render resolution. Old modifiers loaded have the value of resolution also applied to viewport resolution. This allows newer modifiers to be used in older versions without trouble Differential Revision: https://developer.blender.org/D8336
This commit is contained in:
@@ -70,8 +70,10 @@ typedef struct OceanCache {
|
||||
struct Ocean *BKE_ocean_add(void);
|
||||
void BKE_ocean_free_data(struct Ocean *oc);
|
||||
void BKE_ocean_free(struct Ocean *oc);
|
||||
bool BKE_ocean_ensure(struct OceanModifierData *omd);
|
||||
void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd);
|
||||
bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution);
|
||||
void BKE_ocean_init_from_modifier(struct Ocean *ocean,
|
||||
struct OceanModifierData const *omd,
|
||||
const int resolution);
|
||||
|
||||
void BKE_ocean_init(struct Ocean *o,
|
||||
int M,
|
||||
|
||||
@@ -753,18 +753,20 @@ struct Ocean *BKE_ocean_add(void)
|
||||
return oc;
|
||||
}
|
||||
|
||||
bool BKE_ocean_ensure(struct OceanModifierData *omd)
|
||||
bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
|
||||
{
|
||||
if (omd->ocean) {
|
||||
return false;
|
||||
}
|
||||
|
||||
omd->ocean = BKE_ocean_add();
|
||||
BKE_ocean_init_from_modifier(omd->ocean, omd);
|
||||
BKE_ocean_init_from_modifier(omd->ocean, omd, resolution);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd)
|
||||
void BKE_ocean_init_from_modifier(struct Ocean *ocean,
|
||||
struct OceanModifierData const *omd,
|
||||
const int resolution)
|
||||
{
|
||||
short do_heightfield, do_chop, do_normals, do_jacobian;
|
||||
|
||||
@@ -774,9 +776,10 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData
|
||||
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
|
||||
|
||||
BKE_ocean_free_data(ocean);
|
||||
|
||||
BKE_ocean_init(ocean,
|
||||
omd->resolution * omd->resolution,
|
||||
omd->resolution * omd->resolution,
|
||||
resolution * resolution,
|
||||
resolution * resolution,
|
||||
omd->spatial_size,
|
||||
omd->spatial_size,
|
||||
omd->wind_velocity,
|
||||
@@ -1607,7 +1610,8 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o),
|
||||
}
|
||||
|
||||
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
|
||||
struct OceanModifierData const *UNUSED(omd))
|
||||
struct OceanModifierData const *UNUSED(omd),
|
||||
int UNUSED(resolution))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -452,5 +452,16 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "int", "viewport_resolution")) {
|
||||
for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
|
||||
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
if (md->type == eModifierType_Ocean) {
|
||||
OceanModifierData *omd = (OceanModifierData *)md;
|
||||
omd->viewport_resolution = omd->resolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2813,7 +2813,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* make a copy of ocean to use for baking - threadsafety */
|
||||
ocean = BKE_ocean_add();
|
||||
BKE_ocean_init_from_modifier(ocean, omd);
|
||||
BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
|
||||
|
||||
#if 0
|
||||
BKE_ocean_bake(ocean, och);
|
||||
|
||||
@@ -1277,7 +1277,11 @@ typedef struct OceanModifierData {
|
||||
struct Ocean *ocean;
|
||||
struct OceanCache *oceancache;
|
||||
|
||||
/** Render resolution. */
|
||||
int resolution;
|
||||
/** Viewport resolution for the non-render case. */
|
||||
int viewport_resolution;
|
||||
|
||||
int spatial_size;
|
||||
|
||||
float wind_velocity;
|
||||
@@ -1294,8 +1298,6 @@ typedef struct OceanModifierData {
|
||||
float foam_coverage;
|
||||
float time;
|
||||
|
||||
char _pad1[4];
|
||||
|
||||
/* Spectrum being used. */
|
||||
int spectrum;
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
|
||||
{0, "", 0, N_("Generate"), ""},
|
||||
{eModifierType_Array,
|
||||
"ARRAY",
|
||||
ICON_MOD_ARRAY,
|
||||
ICON_MOD_ARRAY,
|
||||
"Array",
|
||||
"Create copies of the shape with offsets"},
|
||||
{eModifierType_Bevel,
|
||||
@@ -5712,7 +5712,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, 1024);
|
||||
RNA_def_property_ui_range(prop, 1, 32, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Render Resolution", "Resolution of the generated surface for rendering and baking");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop = RNA_def_property(srna, "viewport_resolution", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "viewport_resolution");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, 1024);
|
||||
RNA_def_property_ui_range(prop, 1, 32, 1, -1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Viewport Resolution", "Viewport resolution of the generated surface");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE);
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#include "MOD_ui_common.h"
|
||||
|
||||
#ifdef WITH_OCEANSIM
|
||||
static void init_cache_data(Object *ob, struct OceanModifierData *omd)
|
||||
static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution)
|
||||
{
|
||||
const char *relbase = BKE_modifier_path_relbase_from_global(ob);
|
||||
|
||||
@@ -71,7 +71,7 @@ static void init_cache_data(Object *ob, struct OceanModifierData *omd)
|
||||
omd->chop_amount,
|
||||
omd->foam_coverage,
|
||||
omd->foam_fade,
|
||||
omd->resolution);
|
||||
resolution);
|
||||
}
|
||||
|
||||
static void simulate_ocean_modifier(struct OceanModifierData *omd)
|
||||
@@ -87,7 +87,11 @@ static void initData(ModifierData *md)
|
||||
#ifdef WITH_OCEANSIM
|
||||
OceanModifierData *omd = (OceanModifierData *)md;
|
||||
|
||||
/* Render resolution */
|
||||
omd->resolution = 7;
|
||||
/* Display resolution for the non-render case */
|
||||
omd->viewport_resolution = 7;
|
||||
|
||||
omd->spatial_size = 50;
|
||||
|
||||
omd->wave_alignment = 0.0;
|
||||
@@ -126,7 +130,7 @@ static void initData(ModifierData *md)
|
||||
omd->spraylayername[0] = '\0'; /* layer name empty by default */
|
||||
|
||||
omd->ocean = BKE_ocean_add();
|
||||
BKE_ocean_init_from_modifier(omd->ocean, omd);
|
||||
BKE_ocean_init_from_modifier(omd->ocean, omd, omd->viewport_resolution);
|
||||
simulate_ocean_modifier(omd);
|
||||
#else /* WITH_OCEANSIM */
|
||||
/* unused */
|
||||
@@ -164,7 +168,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
|
||||
tomd->oceancache = NULL;
|
||||
|
||||
tomd->ocean = BKE_ocean_add();
|
||||
BKE_ocean_init_from_modifier(tomd->ocean, tomd);
|
||||
BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution);
|
||||
simulate_ocean_modifier(tomd);
|
||||
#else /* WITH_OCEANSIM */
|
||||
/* unused */
|
||||
@@ -288,7 +292,7 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
|
||||
static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution)
|
||||
{
|
||||
Mesh *result;
|
||||
|
||||
@@ -297,10 +301,10 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
|
||||
int num_verts;
|
||||
int num_polys;
|
||||
|
||||
const bool use_threading = omd->resolution > 4;
|
||||
const bool use_threading = resolution > 4;
|
||||
|
||||
gogd.rx = omd->resolution * omd->resolution;
|
||||
gogd.ry = omd->resolution * omd->resolution;
|
||||
gogd.rx = resolution * resolution;
|
||||
gogd.ry = resolution * resolution;
|
||||
gogd.res_x = gogd.rx * omd->repeat_x;
|
||||
gogd.res_y = gogd.ry * omd->repeat_y;
|
||||
|
||||
@@ -362,6 +366,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
|
||||
Mesh *result = NULL;
|
||||
OceanResult ocr;
|
||||
|
||||
const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution :
|
||||
omd->viewport_resolution;
|
||||
|
||||
MVert *mverts;
|
||||
|
||||
int cfra_for_cache;
|
||||
@@ -383,7 +390,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
|
||||
/* do ocean simulation */
|
||||
if (omd->cached == true) {
|
||||
if (!omd->oceancache) {
|
||||
init_cache_data(ob, omd);
|
||||
init_cache_data(ob, omd, resolution);
|
||||
}
|
||||
BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
|
||||
}
|
||||
@@ -393,12 +400,12 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
|
||||
* 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);
|
||||
allocated_ocean |= BKE_ocean_ensure(omd, resolution);
|
||||
simulate_ocean_modifier(omd);
|
||||
}
|
||||
|
||||
if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
|
||||
result = generate_ocean_geometry(omd, mesh);
|
||||
result = generate_ocean_geometry(omd, mesh, resolution);
|
||||
BKE_mesh_ensure_normals(result);
|
||||
}
|
||||
else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
|
||||
@@ -558,7 +565,10 @@ static void panel_draw(const bContext *C, Panel *panel)
|
||||
uiItemR(sub, &ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE);
|
||||
uiItemR(sub, &ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE);
|
||||
}
|
||||
uiItemR(col, &ptr, "resolution", 0, NULL, ICON_NONE);
|
||||
|
||||
sub = uiLayoutColumn(col, true);
|
||||
uiItemR(sub, &ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE);
|
||||
uiItemR(sub, &ptr, "resolution", 0, IFACE_("Render"), ICON_NONE);
|
||||
|
||||
uiItemR(col, &ptr, "time", 0, NULL, ICON_NONE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user