diff options
Diffstat (limited to 'source/blender/blenkernel/intern/fluid.c')
-rw-r--r-- | source/blender/blenkernel/intern/fluid.c | 167 |
1 files changed, 77 insertions, 90 deletions
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index c06cefbb493..b75592836e0 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -81,6 +81,8 @@ # include "RE_shader_ext.h" +# include "CLG_log.h" + # include "manta_fluid_API.h" #endif /* WITH_FLUID */ @@ -96,6 +98,8 @@ static void BKE_fluid_modifier_reset_ex(struct FluidModifierData *mmd, bool need #ifdef WITH_FLUID // #define DEBUG_PRINT +static CLG_LogRef LOG = {"bke.fluid"}; + /* -------------------------------------------------------------------- */ /** \name Fluid API * \{ */ @@ -346,7 +350,7 @@ void BKE_fluid_cache_free(FluidDomainSettings *mds, Object *ob, int cache_map) { char temp_dir[FILE_MAX]; int flags = mds->cache_flag; - const char *relbase = modifier_path_relbase_from_global(ob); + const char *relbase = BKE_modifier_path_relbase_from_global(ob); if (cache_map & FLUID_DOMAIN_OUTDATED_DATA) { flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA); @@ -487,32 +491,6 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *mds, mds->cell_size[2] /= (float)mds->base_res[2]; } -static void manta_set_domain_gravity(Scene *scene, FluidDomainSettings *mds) -{ - const float normalization_factor = 1.0f / 9.81f; - - /* Use global gravity if enabled. */ - if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { - float gravity[3]; - copy_v3_v3(gravity, scene->physics_settings.gravity); - /* Map default value to 1.0. */ - mul_v3_fl(gravity, normalization_factor); - - /* Convert gravity to domain space. */ - float gravity_mag = len_v3(gravity); - mul_mat3_m4_v3(mds->imat, gravity); - normalize_v3(gravity); - mul_v3_fl(gravity, gravity_mag); - - copy_v3_v3(mds->gravity, gravity); - } - else { - mul_v3_fl(mds->gravity, normalization_factor); - } - - mul_v3_fl(mds->gravity, mds->effector_weights->global_gravity); -} - static bool BKE_fluid_modifier_init( FluidModifierData *mmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me) { @@ -523,8 +501,11 @@ static bool BKE_fluid_modifier_init( int res[3]; /* Set domain dimensions from mesh. */ manta_set_domain_from_mesh(mds, ob, me, true); - /* Set domain gravity. */ - manta_set_domain_gravity(scene, mds); + /* Set domain gravity, use global gravity if enabled. */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(mds->gravity, scene->physics_settings.gravity); + } + mul_v3_fl(mds->gravity, mds->effector_weights->global_gravity); /* Reset domain values. */ zero_v3_int(mds->shift); zero_v3(mds->shift_f); @@ -552,7 +533,6 @@ static bool BKE_fluid_modifier_init( /* Initially dt is equal to frame length (dt can change with adaptive-time stepping though). */ mds->dt = mds->frame_length; mds->time_per_frame = 0; - mds->time_total = abs(scene_framenr - mds->cache_frame_start) * mds->frame_length; mmd->time = scene_framenr; @@ -948,11 +928,7 @@ static void sample_effector(FluidEffectorSettings *mes, velocity_map[index * 3 + 2] += hit_vel[2]; # ifdef DEBUG_PRINT /* Debugging: Print object velocities. */ - printf("adding effector object vel: [%f, %f, %f], dx is: %f\n", - hit_vel[0], - hit_vel[1], - hit_vel[2], - mds->dx); + printf("adding effector object vel: [%f, %f, %f]\n", hit_vel[0], hit_vel[1], hit_vel[2]); # endif } } @@ -1165,8 +1141,8 @@ static void update_obstacleflags(FluidDomainSettings *mds, /* Monitor active fields based on flow settings */ for (coll_index = 0; coll_index < coll_ob_array_len; coll_index++) { Object *coll_ob = coll_ob_array[coll_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(coll_ob, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(coll_ob, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -1238,8 +1214,8 @@ static void compute_obstaclesemission(Scene *scene, /* Prepare effector maps. */ for (int effec_index = 0; effec_index < numeffecobjs; effec_index++) { Object *effecobj = effecobjs[effec_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(effecobj, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(effecobj, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -1411,8 +1387,8 @@ static void update_obstacles(Depsgraph *depsgraph, /* Prepare grids from effector objects. */ for (int effec_index = 0; effec_index < numeffecobjs; effec_index++) { Object *effecobj = effecobjs[effec_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(effecobj, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(effecobj, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -1996,9 +1972,9 @@ static void sample_mesh(FluidFlowSettings *mfs, normalize_v3(hit_normal); /* Apply normal directional velocity. */ - velocity_map[index * 3] += hit_normal[0] * mfs->vel_normal * 0.25f; - velocity_map[index * 3 + 1] += hit_normal[1] * mfs->vel_normal * 0.25f; - velocity_map[index * 3 + 2] += hit_normal[2] * mfs->vel_normal * 0.25f; + velocity_map[index * 3] += hit_normal[0] * mfs->vel_normal; + velocity_map[index * 3 + 1] += hit_normal[1] * mfs->vel_normal; + velocity_map[index * 3 + 2] += hit_normal[2] * mfs->vel_normal; } /* Apply object velocity. */ if (has_velocity && mfs->vel_multi) { @@ -2651,8 +2627,8 @@ static void update_flowsflags(FluidDomainSettings *mds, Object **flowobjs, int n /* Monitor active fields based on flow settings */ for (flow_index = 0; flow_index < numflowobj; flow_index++) { Object *flow_ob = flowobjs[flow_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flow_ob, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flow_ob, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -2782,8 +2758,8 @@ static void compute_flowsemission(Scene *scene, /* Prepare flow emission maps. */ for (int flow_index = 0; flow_index < numflowobjs; flow_index++) { Object *flowobj = flowobjs[flow_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flowobj, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flowobj, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -3002,8 +2978,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, /* Apply emission data for every flow object. */ for (int flow_index = 0; flow_index < numflowobjs; flow_index++) { Object *flowobj = flowobjs[flow_index]; - FluidModifierData *mmd2 = (FluidModifierData *)modifiers_findByType(flowobj, - eModifierType_Fluid); + FluidModifierData *mmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flowobj, + eModifierType_Fluid); /* Sanity check. */ if (!mmd2) { @@ -3220,7 +3196,7 @@ static void update_effectors( { ListBase *effectors; /* make sure smoke flow influence is 0.0f */ - mds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; + mds->effector_weights->weight[PFIELD_FLUIDFLOW] = 0.0f; effectors = BKE_effectors_create(depsgraph, ob, NULL, mds->effector_weights); if (effectors) { @@ -3580,7 +3556,7 @@ static int manta_step( Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me, FluidModifierData *mmd, int frame) { FluidDomainSettings *mds = mmd->domain; - float dt, frame_length, time_total; + float dt, frame_length, time_total, time_total_old; float time_per_frame; bool init_resolution = true; @@ -3604,6 +3580,8 @@ static int manta_step( dt = mds->dt; time_per_frame = 0; time_total = mds->time_total; + /* Keep track of original total time to correct small errors at end of step. */ + time_total_old = mds->time_total; BLI_mutex_lock(&object_update_lock); @@ -3649,6 +3627,8 @@ static int manta_step( mds->time_per_frame = time_per_frame; mds->time_total = time_total; } + /* Total time must not exceed framecount times framelength. Correct tiny errors here. */ + CLAMP(mds->time_total, mds->time_total, time_total_old + mds->frame_length); if (mds->type == FLUID_DOMAIN_TYPE_GAS && result) { manta_smoke_calc_transparency(mds, DEG_get_evaluated_view_layer(depsgraph)); @@ -3755,7 +3735,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, } /* Ensure cache directory is not relative. */ - const char *relbase = modifier_path_relbase_from_global(ob); + const char *relbase = BKE_modifier_path_relbase_from_global(ob); BLI_path_abs(mds->cache_directory, relbase); /* Ensure that all flags are up to date before doing any baking and/or cache reading. */ @@ -3785,6 +3765,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, /* Fluid domain init must not fail in order to continue modifier evaluation. */ if (!mds->fluid && !BKE_fluid_modifier_init(mmd, depsgraph, ob, scene, me)) { + CLOG_ERROR(&LOG, "Fluid initialization failed. Should not happen!"); return; } BLI_assert(mds->fluid); @@ -3792,7 +3773,7 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, /* Guiding parent res pointer needs initialization. */ guide_parent = mds->guide_parent; if (guide_parent) { - mmd_parent = (FluidModifierData *)modifiers_findByType(guide_parent, eModifierType_Fluid); + mmd_parent = (FluidModifierData *)BKE_modifiers_findby_type(guide_parent, eModifierType_Fluid); if (mmd_parent && mmd_parent->domain) { copy_v3_v3_int(mds->guide_res, mmd_parent->domain->res); } @@ -3803,8 +3784,12 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, mds->frame_length = DT_DEFAULT * (25.0f / fps) * mds->time_scale; mds->dt = mds->frame_length; mds->time_per_frame = 0; - /* Get distance between cache start and current frame for total time. */ - mds->time_total = abs(scene_framenr - mds->cache_frame_start) * mds->frame_length; + + /* Ensure that gravity is copied over every frame (could be keyframed). */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(mds->gravity, scene->physics_settings.gravity); + mul_v3_fl(mds->gravity, mds->effector_weights->global_gravity); + } int next_frame = scene_framenr + 1; int prev_frame = scene_framenr - 1; @@ -3831,12 +3816,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, with_guide = mds->flags & FLUID_DOMAIN_USE_GUIDE; with_particles = drops || bubble || floater; - bool has_data, has_noise, has_mesh, has_particles, has_guide; + bool has_data, has_noise, has_mesh, has_particles, has_guide, has_config; has_data = manta_has_data(mds->fluid, mmd, scene_framenr); has_noise = manta_has_noise(mds->fluid, mmd, scene_framenr); has_mesh = manta_has_mesh(mds->fluid, mmd, scene_framenr); has_particles = manta_has_particles(mds->fluid, mmd, scene_framenr); has_guide = manta_has_guiding(mds->fluid, mmd, scene_framenr, guide_parent); + has_config = false; bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide; baking_data = mds->cache_flag & FLUID_DOMAIN_BAKING_DATA; @@ -3947,12 +3933,16 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, /* Read mesh cache. */ if (with_liquid && with_mesh) { + has_config = manta_read_config(mds->fluid, mmd, mesh_frame); + /* Update mesh data from file is faster than via Python (manta_read_mesh()). */ has_mesh = manta_update_mesh_structures(mds->fluid, mmd, mesh_frame); } /* Read particles cache. */ if (with_liquid && with_particles) { + has_config = manta_read_config(mds->fluid, mmd, particles_frame); + if (!baking_data && !baking_particles && next_particles) { /* Update particle data from file is faster than via Python (manta_read_particles()). */ has_particles = manta_update_particle_structures(mds->fluid, mmd, particles_frame); @@ -3970,10 +3960,10 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, /* Read noise and data cache */ if (with_smoke && with_noise) { + has_config = manta_read_config(mds->fluid, mmd, noise_frame); /* Only reallocate when just reading cache or when resuming during bake. */ - if ((!baking_noise || (baking_noise && resume_noise)) && - manta_read_config(mds->fluid, mmd, noise_frame) && + if ((!baking_noise || (baking_noise && resume_noise)) && has_config && manta_needs_realloc(mds->fluid, mmd)) { BKE_fluid_reallocate_fluid(mds, mds->res, 1); } @@ -3991,16 +3981,13 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, copy_v3_v3_int(o_min, mds->res_min); copy_v3_v3_int(o_max, mds->res_max); copy_v3_v3_int(o_shift, mds->shift); - if (manta_read_config(mds->fluid, mmd, data_frame) && - manta_needs_realloc(mds->fluid, mmd)) { + if (has_config && manta_needs_realloc(mds->fluid, mmd)) { BKE_fluid_reallocate_copy_fluid( mds, o_res, mds->res, o_min, mds->res_min, o_max, o_shift, mds->shift); } } if (!baking_data && !baking_noise && next_data && next_noise) { - /* TODO (sebbas): Confirm if this read call is really needed or not. - * Currently only important to load the shadow grid. */ - has_data = manta_update_smoke_structures(mds->fluid, mmd, data_frame); + /* Nothing to do here since we already loaded noise grids. */ } else { has_data = manta_read_data(mds->fluid, mmd, data_frame); @@ -4008,10 +3995,11 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *mmd, } /* Read data cache only */ else { + has_config = manta_read_config(mds->fluid, mmd, data_frame); + if (with_smoke) { /* Read config and realloc fluid object if needed. */ - if (manta_read_config(mds->fluid, mmd, data_frame) && - manta_needs_realloc(mds->fluid, mmd)) { + if (has_config && manta_needs_realloc(mds->fluid, mmd)) { BKE_fluid_reallocate_fluid(mds, mds->res, 1); } /* Read data cache */ @@ -4400,26 +4388,25 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *mds, ViewLayer *v } } -/* get smoke velocity and density at given coordinates - * returns fluid density or -1.0f if outside domain. */ +/* Get fluid velocity and density at given coordinates + * Returns fluid density or -1.0f if outside domain. */ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) { - FluidModifierData *mmd = (FluidModifierData *)modifiers_findByType(ob, eModifierType_Fluid); + FluidModifierData *mmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid); zero_v3(velocity); if (mmd && (mmd->type & MOD_FLUID_TYPE_DOMAIN) && mmd->domain && mmd->domain->fluid) { FluidDomainSettings *mds = mmd->domain; float time_mult = 25.f * DT_DEFAULT; + float size_mult = MAX3(mds->global_size[0], mds->global_size[1], mds->global_size[2]) / + mds->maxres; float vel_mag; - float *velX = manta_get_velocity_x(mds->fluid); - float *velY = manta_get_velocity_y(mds->fluid); - float *velZ = manta_get_velocity_z(mds->fluid); float density = 0.0f, fuel = 0.0f; float pos[3]; copy_v3_v3(pos, position); manta_pos_to_cell(mds, pos); - /* check if point is outside domain max bounds */ + /* Check if position is outside domain max bounds. */ if (pos[0] < mds->res_min[0] || pos[1] < mds->res_min[1] || pos[2] < mds->res_min[2]) { return -1.0f; } @@ -4432,9 +4419,8 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo pos[1] = (pos[1] - mds->res_min[1]) / ((float)mds->res[1]); pos[2] = (pos[2] - mds->res_min[2]) / ((float)mds->res[2]); - /* check if point is outside active area */ - if (mmd->domain->type == FLUID_DOMAIN_TYPE_GAS && - mmd->domain->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { + /* Check if position is outside active area. */ + if (mds->type == FLUID_DOMAIN_TYPE_GAS && mds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) { return 0.0f; } @@ -4443,21 +4429,22 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo } } - /* get interpolated velocity */ - velocity[0] = BLI_voxel_sample_trilinear(velX, mds->res, pos) * mds->global_size[0] * - time_mult; - velocity[1] = BLI_voxel_sample_trilinear(velY, mds->res, pos) * mds->global_size[1] * - time_mult; - velocity[2] = BLI_voxel_sample_trilinear(velZ, mds->res, pos) * mds->global_size[2] * - time_mult; + /* Get interpolated velocity at given position. */ + velocity[0] = BLI_voxel_sample_trilinear(manta_get_velocity_x(mds->fluid), mds->res, pos); + velocity[1] = BLI_voxel_sample_trilinear(manta_get_velocity_y(mds->fluid), mds->res, pos); + velocity[2] = BLI_voxel_sample_trilinear(manta_get_velocity_z(mds->fluid), mds->res, pos); + + /* Convert simulation units to Blender units. */ + mul_v3_fl(velocity, size_mult); + mul_v3_fl(velocity, time_mult); - /* convert velocity direction to global space */ + /* Convert velocity direction to global space. */ vel_mag = len_v3(velocity); mul_mat3_m4_v3(mds->obmat, velocity); normalize_v3(velocity); mul_v3_fl(velocity, vel_mag); - /* use max value of fuel or smoke density */ + /* Use max value of fuel or smoke density. */ density = BLI_voxel_sample_trilinear(manta_smoke_get_density(mds->fluid), mds->res, pos); if (manta_smoke_has_fuel(mds->fluid)) { fuel = BLI_voxel_sample_trilinear(manta_smoke_get_fuel(mds->fluid), mds->res, pos); @@ -4511,11 +4498,11 @@ void BKE_fluid_particle_system_create(struct Main *bmain, BLI_addtail(&ob->particlesystem, psys); /* add modifier */ - pmmd = (ParticleSystemModifierData *)modifier_new(eModifierType_ParticleSystem); + pmmd = (ParticleSystemModifierData *)BKE_modifier_new(eModifierType_ParticleSystem); BLI_strncpy(pmmd->modifier.name, psys_name, sizeof(pmmd->modifier.name)); pmmd->psys = psys; BLI_addtail(&ob->modifiers, pmmd); - modifier_unique_name(&ob->modifiers, (ModifierData *)pmmd); + BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)pmmd); } void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_type) @@ -4529,7 +4516,7 @@ void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_typ /* clear modifier */ pmmd = psys_get_modifier(ob, psys); BLI_remlink(&ob->modifiers, pmmd); - modifier_free((ModifierData *)pmmd); + BKE_modifier_free((ModifierData *)pmmd); /* clear particle system */ BLI_remlink(&ob->particlesystem, psys); @@ -4942,7 +4929,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *mmd) /* cache options */ mmd->domain->cache_frame_start = 1; - mmd->domain->cache_frame_end = 50; + mmd->domain->cache_frame_end = 250; mmd->domain->cache_frame_pause_data = 0; mmd->domain->cache_frame_pause_noise = 0; mmd->domain->cache_frame_pause_mesh = 0; @@ -4962,7 +4949,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *mmd) #endif char cache_name[64]; BKE_fluid_cache_new_name_for_current_session(sizeof(cache_name), cache_name); - modifier_path_init( + BKE_modifier_path_init( mmd->domain->cache_directory, sizeof(mmd->domain->cache_directory), cache_name); /* time options */ |