void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot);
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
+ void OBJECT_OT_ocean_bake(struct wmOperatorType *ot);
+void OBJECT_OT_test_multires(struct wmOperatorType *ot);
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
#include "BKE_multires.h"
#include "BKE_report.h"
#include "BKE_object.h"
+ #include "BKE_ocean.h"
#include "BKE_particle.h"
#include "BKE_softbody.h"
+#include "BKE_tessmesh.h"
#include "RNA_access.h"
#include "RNA_define.h"
if(dt>OB_WIRE) {
if(CHECK_OB_DRAWTEXTURE(v3d, dt)) {
if(draw_glsl_material(scene, ob, v3d, dt)) {
- glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
+ /* if em has no faces the drawMappedFaces callback will fail */
- if(em->faces.first) {
++ if(em->bm->totface) {
+ glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- finalDM->drawMappedFacesGLSL(finalDM, GPU_enable_material,
- draw_em_fancy__setGLSLFaceOpts, em);
- GPU_disable_material();
+ finalDM->drawMappedFacesGLSL(finalDM, GPU_enable_material,
- draw_em_fancy__setGLSLFaceOpts, NULL);
++ draw_em_fancy__setGLSLFaceOpts, em);
+ GPU_disable_material();
- glFrontFace(GL_CCW);
+ glFrontFace(GL_CCW);
+ }
}
else {
draw_mesh_textured(scene, v3d, rv3d, ob, finalDM, 0);
}
}
else {
- /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
+ /* if em has no faces the drawMappedFaces callback will fail */
- if(em->faces.first) {
++ if(em->bm->totface) {
+ /* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
- glEnable(GL_LIGHTING);
- glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, me->edit_btmesh, 0, GPU_enable_material, NULL);
+ glEnable(GL_LIGHTING);
+ glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
-
- finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material, NULL);
++ finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, me->edit_btmesh, 0, GPU_enable_material, NULL);
- glFrontFace(GL_CCW);
- glDisable(GL_LIGHTING);
+ glFrontFace(GL_CCW);
+ glDisable(GL_LIGHTING);
+ }
}
// Setup for drawing wire over, disable zbuffer
eModifierType_WeightVGEdit,
eModifierType_WeightVGMix,
eModifierType_WeightVGProximity,
- eModifierType_EmptySlot, /* keep so DynamicPaint keep loading, can re-use later */
- eModifierType_DynamicPaint, /* reserve slot */
+ eModifierType_Ocean,
+ eModifierType_DynamicPaint,
+
+ /* BMESH ONLY - keeps getting bumped by new modifiers in trunk */
+ eModifierType_NgonInterp,
NUM_MODIFIER_TYPES
} ModifierType;
#define MOD_SCREW_OBJECT_OFFSET (1<<2)
// #define MOD_SCREW_OBJECT_ANGLE (1<<4)
-typedef struct WarpModifierData {
+ typedef struct OceanModifierData {
+ ModifierData modifier;
+
+ struct Ocean *ocean;
+ struct OceanCache *oceancache;
+
+ int resolution;
+ int spatial_size;
+
+ float wind_velocity;
+
+ float damp;
+ float smallest_wave;
+ float depth;
+
+ float wave_alignment;
+ float wave_direction;
+ float wave_scale;
+
+ float chop_amount;
+ float foam_coverage;
+ float time;
+
+ int seed;
+ int flag;
+ int output;
+
+ int refresh;
+
+ int bakestart;
+ int bakeend;
+
+ char cachepath[240]; // FILE_MAX
+ int cached;
+
+ int geometry_mode;
+ float size;
+ int repeat_x;
+ int repeat_y;
+
+ float foam_fade;
+
+ } OceanModifierData;
+
+ #define MOD_OCEAN_GEOM_GENERATE 0
+ #define MOD_OCEAN_GEOM_DISPLACE 1
+ #define MOD_OCEAN_GEOM_SIM_ONLY 2
+
+ #define MOD_OCEAN_REFRESH_RESET 1
+ #define MOD_OCEAN_REFRESH_SIM 2
+ #define MOD_OCEAN_REFRESH_ADD 4
+ #define MOD_OCEAN_REFRESH_CLEAR_CACHE 8
+ #define MOD_OCEAN_REFRESH_TOPOLOGY 16
+
+ #define MOD_OCEAN_GENERATE_FOAM 1
+ #define MOD_OCEAN_GENERATE_NORMALS 2
+
+
++/* BMESH_ONLY */
+typedef struct NgonInterpModifierData {
ModifierData modifier;
+ int resolution, pad0;
+} NgonInterpModifierData;
+typedef struct WarpModifierData {
+ ModifierData modifier;
/* keep in sync with MappingInfoModifierData */
struct Tex *texture;
struct Object *map_object;
{eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""},
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
{eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""},
- {eModifierType_DynamicPaint, "DYNAMIC_PAINT", ICON_MOD_DYNAMICPAINT, "Dynamic Paint", ""},
+ {eModifierType_NgonInterp, "NGONINTERP", ICON_MOD_LATTICE, "Precision UV Interpolation", ""},
{0, NULL, 0, NULL, NULL}};
#ifdef RNA_RUNTIME
rna_def_modifier_weightvg_mask(brna, srna);
}
+
+ static void rna_def_modifier_ocean(BlenderRNA *brna)
+ {
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem geometry_items[]= {
+ {MOD_OCEAN_GEOM_GENERATE, "GENERATE", 0, "Generate", "Generates ocean surface geometry at the specified resolution"},
+ {MOD_OCEAN_GEOM_DISPLACE, "DISPLACE", 0, "Displace", "Displaces existing geometry according to simulation"},
+ //{MOD_OCEAN_GEOM_SIM_ONLY, "SIM_ONLY", 0, "Sim Only", "Leaves geometry unchanged, but still runs simulation (to be used from texture)"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "OceanModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Ocean Modifier", "Simulate an ocean surface");
+ RNA_def_struct_sdna(srna, "OceanModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_FLUIDSIM);
+
+ /* General check if blender was built with OceanSim modifier support */
+ prop= RNA_def_property(srna, "is_build_enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_OceanModifier_is_build_enabled_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Build Enabled", "True if the OceanSim modifier is enabled in this build");
+
+ prop= RNA_def_property(srna, "geometry_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "geometry_mode");
+ RNA_def_property_enum_items(prop, geometry_items);
+ RNA_def_property_ui_text(prop, "Geometry", "Method of modifying geometry");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "size");
+ RNA_def_property_ui_text(prop, "Size", "");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
+
+ prop= RNA_def_property(srna, "repeat_x", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "repeat_x");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+ RNA_def_property_ui_text(prop, "Repeat X", "Repetitions of the generated surface in X");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
+
+ prop= RNA_def_property(srna, "repeat_y", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "repeat_y");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+ RNA_def_property_ui_text(prop, "Repeat Y", "Repetitions of the generated surface in Y");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
+
+ prop= RNA_def_property(srna, "use_normals", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_OCEAN_GENERATE_NORMALS);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Generate Normals", "Outputs normals for bump mapping - disabling can speed up performance if its not needed");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "use_foam", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_OCEAN_GENERATE_FOAM);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Generate Foam", "Generates foam mask as a vertex color channel");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "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, 0);
+ RNA_def_property_ui_text(prop, "Resolution", "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_DISTANCE);
+ RNA_def_property_int_sdna(prop, NULL, "spatial_size");
+ RNA_def_property_ui_range(prop, 1, 512, 2, 0);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Spatial Size", "Physical size of the simulation domain (m)");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "wind_velocity", PROP_FLOAT, PROP_VELOCITY);
+ RNA_def_property_float_sdna(prop, NULL, "wind_velocity");
+ RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed (m/s)");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "damping", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "damp");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Damping", "Damp reflected waves going in opposite direction to the wind");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "wave_scale_min", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_float_sdna(prop, NULL, "smallest_wave");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 0.0, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength (m)");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "wave_alignment", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "wave_alignment");
+ RNA_def_property_range(prop, 0.0, 10.0);
+ RNA_def_property_ui_text(prop, "Wave Alignment", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "wave_direction", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "wave_direction");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Wave Direction", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "wave_scale", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "wave_scale");
+ RNA_def_property_ui_text(prop, "Wave Scale", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
+
+ prop= RNA_def_property(srna, "depth", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "depth");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Depth", "");
+ RNA_def_property_ui_range(prop, 0, 250, 1, 0);
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "foam_coverage", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "foam_coverage");
+ RNA_def_property_ui_text(prop, "Foam Coverage", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "bake_foam_fade", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "foam_fade");
+ RNA_def_property_ui_text(prop, "Foam Fade", "");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
+ RNA_def_property_update(prop, 0, NULL);
+
+ prop= RNA_def_property(srna, "choppiness", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "chop_amount");
+ RNA_def_property_ui_text(prop, "Choppiness", "");
+ RNA_def_property_ui_range(prop, 0.0, 4.0, 3, 0);
+ RNA_def_property_float_funcs(prop, NULL, "rna_OceanModifier_ocean_chop_set", NULL);
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
+
+ prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "time");
+ RNA_def_property_ui_text(prop, "Time", "");
+ RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
+
+ prop= RNA_def_property(srna, "random_seed", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "seed");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "frame_start", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "bakestart");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Bake Start", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "frame_end", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "bakeend");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Bake End", "");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop= RNA_def_property(srna, "is_cached", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "cached", 1);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Ocean is Cached", "Whether the ocean is useing cached data or simulating");
+
+ prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_string_sdna(prop, NULL, "cachepath");
+ RNA_def_property_ui_text(prop, "Cache Path", "Path to a folder to store external baked images");
+ //RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ // XXX how to update?
+ }
+
+
+
+static void rna_def_modifier_ngoninterp(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "NgonInterpModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Precision UV Modifier", "Precision UV interpolation");
+ RNA_def_struct_sdna(srna, "NgonInterpModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_SCREW);
+
+ prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
+ RNA_def_property_ui_text(prop, "Resolution", "Size of interpolation grids");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+}
++
++
++
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
rna_def_modifier_weightvgmix(brna);
rna_def_modifier_weightvgproximity(brna);
rna_def_modifier_dynamic_paint(brna);
+ rna_def_modifier_ocean(brna);
++
++
++ /* BMESH_ONLY */
+ rna_def_modifier_ngoninterp(brna);
}
#endif
intern/MOD_meshdeform.c
intern/MOD_mirror.c
intern/MOD_multires.c
+ intern/MOD_ngoninterp.c
intern/MOD_none.c
+ intern/MOD_ocean.c
intern/MOD_particleinstance.c
intern/MOD_particlesystem.c
intern/MOD_screw.c
--- /dev/null
- struct EditMesh *UNUSED(editData),
+ /**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matt Ebb
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+ #include "MEM_guardedalloc.h"
+
+ #include "DNA_customdata_types.h"
+ #include "DNA_object_types.h"
+ #include "DNA_meshdata_types.h"
+ #include "DNA_modifier_types.h"
+ #include "DNA_scene_types.h"
+
+ #include "BKE_cdderivedmesh.h"
+ #include "BKE_modifier.h"
+ #include "BKE_ocean.h"
+ #include "BKE_utildefines.h"
+
+ #include "BLI_math.h"
+ #include "BLI_math_inline.h"
+ #include "BLI_utildefines.h"
+ #include "BLI_string.h"
+
+ #include "MOD_util.h"
+
+ #ifdef WITH_OCEANSIM
+ static void init_cache_data(struct OceanModifierData *omd)
+ {
+ omd->oceancache = BKE_init_ocean_cache(omd->cachepath, omd->bakestart, omd->bakeend, omd->wave_scale,
+ omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
+ }
+
+ static void clear_cache_data(struct OceanModifierData *omd)
+ {
+ BKE_free_ocean_cache(omd->oceancache);
+ omd->oceancache = NULL;
+ omd->cached = FALSE;
+ }
+
+ /* keep in sync with init_ocean_modifier_bake(), object_modifier.c */
+ static void init_ocean_modifier(struct OceanModifierData *omd)
+ {
+ int do_heightfield, do_chop, do_normals, do_jacobian;
+
+ if (!omd || !omd->ocean) return;
+
+ do_heightfield = TRUE;
+ do_chop = (omd->chop_amount > 0);
+ do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
+ do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
+
+ BKE_free_ocean_data(omd->ocean);
+ BKE_init_ocean(omd->ocean, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size,
+ omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
+ omd->depth, omd->time,
+ do_heightfield, do_chop, do_normals, do_jacobian,
+ omd->seed);
+ }
+
+ static void simulate_ocean_modifier(struct OceanModifierData *omd)
+ {
+ if (!omd || !omd->ocean) return;
+
+ BKE_simulate_ocean(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;
+
+ omd->resolution = 7;
+ omd->spatial_size = 50;
+
+ 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->wave_scale = 1.0;
+
+ omd->chop_amount = 1.0;
+
+ omd->foam_coverage = 0.0;
+
+ omd->seed = 0;
+ omd->time = 1.0;
+
+ omd->refresh = 0;
+
+ omd->size = 1.0;
+ omd->repeat_x = 1;
+ omd->repeat_y = 1;
+
+ BLI_strncpy(omd->cachepath, "//ocean_cache", sizeof(omd->cachepath));
+
+ omd->cached = 0;
+ omd->bakestart = 1;
+ omd->bakeend = 250;
+ omd->oceancache = NULL;
+ omd->foam_fade = 0.98;
+
+ omd->ocean = BKE_add_ocean();
+ init_ocean_modifier(omd);
+ simulate_ocean_modifier(omd);
+ #else // WITH_OCEANSIM
+ /* unused */
+ (void)md;
+ #endif // WITH_OCEANSIM
+ }
+
+ static void freeData(ModifierData *md)
+ {
+ #ifdef WITH_OCEANSIM
+ OceanModifierData *omd = (OceanModifierData*) md;
+
+ BKE_free_ocean(omd->ocean);
+ if (omd->oceancache)
+ BKE_free_ocean_cache(omd->oceancache);
+ #else // WITH_OCEANSIM
+ /* unused */
+ (void)md;
+ #endif // WITH_OCEANSIM
+ }
+
+ static void copyData(ModifierData *md, ModifierData *target)
+ {
+ #ifdef WITH_OCEANSIM
+ OceanModifierData *omd = (OceanModifierData*) md;
+ OceanModifierData *tomd = (OceanModifierData*) target;
+
+ tomd->resolution = omd->resolution;
+ tomd->spatial_size = omd->spatial_size;
+
+ tomd->wind_velocity = omd->wind_velocity;
+
+ tomd->damp = omd->damp;
+ tomd->smallest_wave = omd->smallest_wave;
+ tomd->depth = omd->depth;
+
+ tomd->wave_alignment = omd->wave_alignment;
+ tomd->wave_direction = omd->wave_direction;
+ tomd->wave_scale = omd->wave_scale;
+
+ tomd->chop_amount = omd->chop_amount;
+ tomd->foam_coverage = omd->foam_coverage;
+ tomd->time = omd->time;
+
+ tomd->seed = omd->seed;
+ tomd->flag = omd->flag;
+ tomd->output = omd->output;
+
+ tomd->refresh = 0;
+
+
+ tomd->size = omd->size;
+ tomd->repeat_x = omd->repeat_x;
+ tomd->repeat_y = omd->repeat_y;
+
+ /* XXX todo: copy cache runtime too */
+ tomd->cached = 0;
+ tomd->bakestart = omd->bakestart;
+ tomd->bakeend = omd->bakeend;
+ tomd->oceancache = NULL;
+
+ tomd->ocean = BKE_add_ocean();
+ init_ocean_modifier(tomd);
+ simulate_ocean_modifier(tomd);
+ #else // WITH_OCEANSIM
+ /* unused */
+ (void)md;
+ (void)target;
+ #endif // WITH_OCEANSIM
+ }
+
+ #ifdef WITH_OCEANSIM
+ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+ {
+ OceanModifierData *omd = (OceanModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ if (omd->flag & MOD_OCEAN_GENERATE_FOAM)
+ dataMask |= CD_MASK_MCOL;
+
+ return dataMask;
+ }
+ #else // WITH_OCEANSIM
+ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+ {
+ /* unused */
+ (void)md;
+ return 0;
+ }
+ #endif // WITH_OCEANSIM
+
+ #if 0
+ static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, float *oy)
+ {
+ /* get bounding box of underlying dm */
+ int v, totvert=dm->getNumVerts(dm);
+ float min[3], max[3], delta[3];
+
+ MVert *mvert = dm->getVertDataArray(dm,0);
+
+ copy_v3_v3(min, mvert->co);
+ copy_v3_v3(max, mvert->co);
+
+ for(v=1; v<totvert; v++, mvert++) {
+ min[0]=MIN2(min[0],mvert->co[0]);
+ min[1]=MIN2(min[1],mvert->co[1]);
+ min[2]=MIN2(min[2],mvert->co[2]);
+
+ max[0]=MAX2(max[0],mvert->co[0]);
+ max[1]=MAX2(max[1],mvert->co[1]);
+ max[2]=MAX2(max[2],mvert->co[2]);
+ }
+
+ sub_v3_v3v3(delta, max, min);
+
+ *sx = delta[0];
+ *sy = delta[1];
+
+ *ox = min[0];
+ *oy = min[1];
+ }
+ #endif
+
+ #ifdef WITH_OCEANSIM
+ MINLINE float ocean_co(OceanModifierData *omd, float v)
+ {
+ //float scale = 1.0 / (omd->size * omd->spatial_size);
+ //*v = (*v * scale) + 0.5;
+
+ return (v / (omd->size * omd->spatial_size)) + 0.5f;
+ }
+
+ #define OMP_MIN_RES 18
+ static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
+ {
+ DerivedMesh *result;
+
+ MVert *mv;
+ MFace *mf;
+ MTFace *tf;
+
+ int cdlayer;
+
+ const int rx = omd->resolution*omd->resolution;
+ const int ry = omd->resolution*omd->resolution;
+ const int res_x = rx * omd->repeat_x;
+ const int res_y = ry * omd->repeat_y;
+
+ const int num_verts = (res_x + 1) * (res_y + 1);
+ const int num_edges = (res_x * res_y * 2) + res_x + res_y;
+ const int num_faces = res_x * res_y;
+
+ float sx = omd->size * omd->spatial_size;
+ float sy = omd->size * omd->spatial_size;
+ const float ox = -sx / 2.0f;
+ const float oy = -sy / 2.0f;
+
+ float ix, iy;
+
+ int x, y;
+
+ sx /= rx;
+ sy /= ry;
+
+ result = CDDM_new(num_verts, num_edges, num_faces);
+
+ mv = CDDM_get_verts(result);
+ mf = CDDM_get_faces(result);
+
+ /* create vertices */
+ #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
+ for (y=0; y < res_y+1; y++) {
+ for (x=0; x < res_x+1; x++) {
+ const int i = y*(res_x+1) + x;
+ mv[i].co[0] = ox + (x * sx);
+ mv[i].co[1] = oy + (y * sy);
+ mv[i].co[2] = 0;
+ }
+ }
+
+ /* create faces */
+ #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
+ for (y=0; y < res_y; y++) {
+ for (x=0; x < res_x; x++) {
+ const int fi = y*res_x + x;
+ const int vi = y*(res_x+1) + x;
+ mf[fi].v1 = vi;
+ mf[fi].v2 = vi + 1;
+ mf[fi].v3 = vi + 1 + res_x+1;
+ mf[fi].v4 = vi + res_x+1;
+
+ mf[fi].flag |= ME_SMOOTH;
+ }
+ }
+
+ CDDM_calc_edges(result);
+
+ /* add uvs */
+ cdlayer= CustomData_number_of_layers(&result->faceData, CD_MTFACE);
+ if(cdlayer >= MAX_MTFACE)
+ return result;
+ CustomData_add_layer(&result->faceData, CD_MTFACE, CD_CALLOC, NULL, num_faces);
+ tf = CustomData_get_layer(&result->faceData, CD_MTFACE);
+
+ ix = 1.0 / rx;
+ iy = 1.0 / ry;
+ #pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
+ for (y=0; y < res_y; y++) {
+ for (x=0; x < res_x; x++) {
+ const int i = y*res_x + x;
+ tf[i].uv[0][0] = x * ix;
+ tf[i].uv[0][1] = y * iy;
+
+ tf[i].uv[1][0] = (x+1) * ix;
+ tf[i].uv[1][1] = y * iy;
+
+ tf[i].uv[2][0] = (x+1) * ix;
+ tf[i].uv[2][1] = (y+1) * iy;
+
+ tf[i].uv[3][0] = x * ix;
+ tf[i].uv[3][1] = (y+1) * iy;
+ }
+ }
+
+ return result;
+ }
+
+ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
+ DerivedMesh *derivedData,
+ int UNUSED(useRenderParams))
+ {
+ OceanModifierData *omd = (OceanModifierData*) md;
+
+ DerivedMesh *dm=NULL;
+ OceanResult ocr;
+
+ MVert *mv;
+ MFace *mf;
+
+ int cdlayer;
+
+ int i, j;
+
+ int num_verts;
+ int num_faces;
+
+ int cfra;
+
+ /* update modifier */
+ if (omd->refresh & MOD_OCEAN_REFRESH_ADD)
+ omd->ocean = BKE_add_ocean();
+ if (omd->refresh & MOD_OCEAN_REFRESH_RESET)
+ init_ocean_modifier(omd);
+ if (omd->refresh & MOD_OCEAN_REFRESH_CLEAR_CACHE)
+ clear_cache_data(omd);
+
+ omd->refresh = 0;
+
+ /* do ocean simulation */
+ if (omd->cached == TRUE) {
+ if (!omd->oceancache) init_cache_data(omd);
+ BKE_simulate_ocean_cache(omd->oceancache, md->scene->r.cfra);
+ } else {
+ simulate_ocean_modifier(omd);
+ }
+
+ if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE)
+ dm = generate_ocean_geometry(omd);
+ else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
+ dm = CDDM_copy(derivedData);
+ }
+
+ cfra = md->scene->r.cfra;
+ CLAMP(cfra, omd->bakestart, omd->bakeend);
+ cfra -= omd->bakestart; // shift to 0 based
+
+ num_verts = dm->getNumVerts(dm);
+ num_faces = dm->getNumFaces(dm);
+
+ /* add vcols before displacement - allows lookup based on position */
+
+ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
+ MCol *mc;
+ float foam;
+ char cf;
+
+ float u=0.0, v=0.0;
+
+ cdlayer= CustomData_number_of_layers(&dm->faceData, CD_MCOL);
+ if(cdlayer >= MAX_MCOL)
+ return dm;
+
+ CustomData_add_layer(&dm->faceData, CD_MCOL, CD_CALLOC, NULL, num_faces);
+
+ mc = dm->getFaceDataArray(dm, CD_MCOL);
+ mv = dm->getVertArray(dm);
+ mf = dm->getFaceArray(dm);
+
+ for (i = 0; i < num_faces; i++, mf++) {
+ for (j=0; j<4; j++) {
+
+ if (j == 3 && !mf->v4) continue;
+
+ switch(j) {
+ case 0:
+ u = ocean_co(omd, mv[mf->v1].co[0]);
+ v = ocean_co(omd, mv[mf->v1].co[1]);
+ break;
+ case 1:
+ u = ocean_co(omd, mv[mf->v2].co[0]);
+ v = ocean_co(omd, mv[mf->v2].co[1]);
+ break;
+ case 2:
+ u = ocean_co(omd, mv[mf->v3].co[0]);
+ v = ocean_co(omd, mv[mf->v3].co[1]);
+ break;
+ case 3:
+ u = ocean_co(omd, mv[mf->v4].co[0]);
+ v = ocean_co(omd, mv[mf->v4].co[1]);
+
+ break;
+ }
+
+ if (omd->oceancache && omd->cached==TRUE) {
+ BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, 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);
+ }
+
+ cf = (char)(foam*255);
+ mc[i*4 + j].r = mc[i*4 + j].g = mc[i*4 + j].b = cf;
+ mc[i*4 + j].a = 255;
+ }
+ }
+ }
+
+
+ /* displace the geometry */
+
+ mv = dm->getVertArray(dm);
+
+ //#pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES)
+ for (i=0; i< num_verts; i++) {
+ const float u = ocean_co(omd, mv[i].co[0]);
+ const float v = ocean_co(omd, mv[i].co[1]);
+
+ if (omd->oceancache && omd->cached==TRUE)
+ BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
+ else
+ BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
+
+ mv[i].co[2] += ocr.disp[1];
+
+ if (omd->chop_amount > 0.0f) {
+ mv[i].co[0] += ocr.disp[0];
+ mv[i].co[1] += ocr.disp[2];
+ }
+ }
+
+
+ return dm;
+ }
+ #else // WITH_OCEANSIM
+ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
+ DerivedMesh *derivedData,
+ int UNUSED(useRenderParams))
+ {
+ /* unused */
+ (void)md;
+ return derivedData;
+ }
+ #endif // WITH_OCEANSIM
+
+ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *derivedData,
+ int UNUSED(useRenderParams),
+ int UNUSED(isFinalCalc))
+ {
+ DerivedMesh *result;
+
+ result = doOcean(md, ob, derivedData, 0);
+
+ if(result != derivedData)
+ CDDM_calc_normals(result);
+
+ return result;
+ }
+
+ static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
++ struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData)
+ {
+ return applyModifier(md, ob, derivedData, 0, 1);
+ }
+
+
+
+ ModifierTypeInfo modifierType_Ocean = {
+ /* name */ "Ocean",
+ /* structName */ "OceanModifierData",
+ /* structSize */ sizeof(OceanModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_SupportsEditmode
+ | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ copyData,
+ /* deformMatrices */ NULL,
+ /* deformVerts */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ applyModifierEM,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ freeData,
+ /* isDisabled */ NULL,
+ /* updateDepgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ NULL,
+ /* foreachIDLink */ NULL,
+ };