From 1c3ded12f439c90beee155ebd9261b8b2e947674 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 2 Apr 2020 10:34:05 +0200 Subject: Fluids: improve subframe handling Reviewers: sebbas Differential Revision: https://developer.blender.org/D7256 --- source/blender/blenkernel/intern/fluid.c | 73 +++++++------------------------- 1 file changed, 15 insertions(+), 58 deletions(-) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 75e1dce9958..e8da4385fb9 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1232,52 +1232,31 @@ static void update_obstacles(Depsgraph *depsgraph, continue; } - /* Length of one adaptive frame. If using adaptive stepping, length is smaller than actual - * frame length */ - float adaptframe_length = time_per_frame / frame_length; - /* Adaptive frame length as percentage */ - CLAMP(adaptframe_length, 0.0f, 1.0f); - - /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ - float sample_size = 1.0f / (float)(subframes + 1); - /* First frame cannot have any subframes because there is (obviously) no previous frame from * where subframes could come from. */ if (is_first_frame) { subframes = 0; } - int subframe; + /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ + float sample_size = 1.0f / (float)(subframes + 1); float subframe_dt = dt * sample_size; /* Emission loop. When not using subframes this will loop only once. */ - for (subframe = subframes; subframe >= 0; subframe--) { + for (int subframe = 0; subframe <= subframes; subframe++) { /* Temporary emission map used when subframes are enabled, i.e. at least one subframe. */ FluidObjectBB bb_temp = {NULL}; /* Set scene time */ /* Handle emission subframe */ - if (subframe > 0 && !is_first_frame) { - scene->r.subframe = adaptframe_length - - sample_size * (float)(subframe) * (dt / frame_length); + if (subframe < subframes || time_per_frame + dt + FLT_EPSILON < frame_length) { + scene->r.subframe = (time_per_frame + (subframe + 1.0f) * subframe_dt) / frame_length; scene->r.cfra = frame - 1; } - /* Last frame in this loop (subframe == suframes). Can be real end frame or in between - * frames (adaptive frame). */ else { - /* Handle adaptive subframe (ie has subframe fraction). Need to set according scene - * subframe parameter. */ - if (time_per_frame < frame_length) { - scene->r.subframe = adaptframe_length; - scene->r.cfra = frame - 1; - } - /* Handle absolute endframe (ie no subframe fraction). Need to set the scene subframe - * parameter to 0 and advance current scene frame. */ - else { - scene->r.subframe = 0.0f; - scene->r.cfra = frame; - } + scene->r.subframe = 0.0f; + scene->r.cfra = frame; } /* Sanity check: subframe portion must be between 0 and 1. */ CLAMP(scene->r.subframe, 0.0f, 1.0f); @@ -2768,53 +2747,31 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, continue; } - /* Length of one adaptive frame. If using adaptive stepping, length is smaller than actual - * frame length */ - float adaptframe_length = time_per_frame / frame_length; - /* Adaptive frame length as percentage */ - CLAMP(adaptframe_length, 0.0f, 1.0f); - - /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ - float sample_size = 1.0f / (float)(subframes + 1); - /* First frame cannot have any subframes because there is (obviously) no previous frame from * where subframes could come from. */ if (is_first_frame) { subframes = 0; } - int subframe; + /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ + float sample_size = 1.0f / (float)(subframes + 1); float subframe_dt = dt * sample_size; /* Emission loop. When not using subframes this will loop only once. */ - for (subframe = subframes; subframe >= 0; subframe--) { - + for (int subframe = 0; subframe <= subframes; subframe++) { /* Temporary emission map used when subframes are enabled, i.e. at least one subframe. */ FluidObjectBB bb_temp = {NULL}; /* Set scene time */ - /* Handle emission subframe */ - if (subframe > 0 && !is_first_frame) { - scene->r.subframe = adaptframe_length - - sample_size * (float)(subframe) * (dt / frame_length); + if (subframe < subframes || time_per_frame + dt + FLT_EPSILON < frame_length) { + scene->r.subframe = (time_per_frame + (subframe + 1.0f) * subframe_dt) / frame_length; scene->r.cfra = frame - 1; } - /* Last frame in this loop (subframe == suframes). Can be real end frame or in between - * frames (adaptive frame). */ else { - /* Handle adaptive subframe (ie has subframe fraction). Need to set according scene - * subframe parameter. */ - if (time_per_frame < frame_length) { - scene->r.subframe = adaptframe_length; - scene->r.cfra = frame - 1; - } - /* Handle absolute endframe (ie no subframe fraction). Need to set the scene subframe - * parameter to 0 and advance current scene frame. */ - else { - scene->r.subframe = 0.0f; - scene->r.cfra = frame; - } + scene->r.subframe = 0.0f; + scene->r.cfra = frame; } + /* Sanity check: subframe portion must be between 0 and 1. */ CLAMP(scene->r.subframe, 0.0f, 1.0f); # ifdef DEBUG_PRINT -- cgit v1.2.3