[Bf-blender-cvs] [4a813ce] hair_system: Integrate hair solver stepping with the global scene stepping used for Bullet physics.

Lukas Tönne noreply at git.blender.org
Thu Jul 31 19:08:11 CEST 2014


Commit: 4a813ce215b3208dad19906273a3335b05794902
Author: Lukas Tönne
Date:   Thu Jul 31 19:04:50 2014 +0200
Branches: hair_system
https://developer.blender.org/rB4a813ce215b3208dad19906273a3335b05794902

Integrate hair solver stepping with the global scene stepping used for
Bullet physics.

This is a preparation to using Bullet for hair-mesh collisions. This
is much more accurate and requires less secondary interpolation when
the hair solver is in sync with the Bullet stepping.

Bullet uses essentially the same time step concepts as the hair solver
did, i.e. the main "step" (1 frame) is divided into fixed-size "ticks".
This is paramount for stability of the solver. The hair solver could
eventually use a multiple or integer fraction of the Bullet tick size
if more accuracy or performance is necessary.

===================================================================

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/hair/intern/HAIR_scene.cpp
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_hair.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index c0da816..56ad034 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -171,6 +171,10 @@ void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx,
                                  const bool do_proxy_update);
 void BKE_object_sculpt_modifiers_changed(struct Object *ob);
 
+void BKE_object_sim_pre_step(struct Scene *scene, struct Object *ob, float ctime);
+void BKE_object_sim_tick(struct Scene *scene, struct Object *ob, float ctime, float timestep);
+void BKE_object_sim_post_step(struct Scene *scene, struct Object *ob, float ctime);
+
 int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
 
 int BKE_object_insert_ptcache(struct Object *ob);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 60d177c..e39c239 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -36,6 +36,7 @@ set(INC
 	../bmesh
 	../modifiers
 	../nodes
+	../hair
 	../render/extern/include
 	../../../intern/guardedalloc
 	../../../intern/iksolver/extern
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 5281b0b..b844795 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -41,6 +41,7 @@
 #include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_group_types.h"
+#include "DNA_hair_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_material_types.h"
@@ -86,6 +87,7 @@
 #include "BKE_effect.h"
 #include "BKE_fcurve.h"
 #include "BKE_group.h"
+#include "BKE_hair.h"
 #include "BKE_key.h"
 #include "BKE_lamp.h"
 #include "BKE_lattice.h"
@@ -110,6 +112,8 @@
 #include "BKE_camera.h"
 #include "BKE_image.h"
 
+#include "HAIR_capi.h"
+
 #ifdef WITH_MOD_FLUID
 #include "LBM_fluidsim.h"
 #endif
@@ -3082,6 +3086,57 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
 	}
 }
 
+void BKE_object_sim_pre_step(Scene *scene, Object *ob, float ctime)
+{
+	ModifierData *md;
+	
+	for (md = ob->modifiers.first; md; md = md->next) {
+		if (md->type == eModifierType_Hair) {
+			HairModifierData *hmd = (HairModifierData*) md;
+			HairSystem *hsys = hmd->hairsys;
+			DerivedMesh *dm = ob->derivedFinal;
+			
+			if (!hmd->solver) {
+				hmd->solver = HAIR_solver_new();
+				hmd->flag &= ~MOD_HAIR_SOLVER_DATA_VALID;
+			}
+			
+			HAIR_solver_set_params(hmd->solver, &hsys->params);
+			
+			if (!hmd->flag & MOD_HAIR_SOLVER_DATA_VALID) {
+				HAIR_solver_build_data(hmd->solver, scene, ob, dm, hsys, ctime);
+				hmd->flag |= MOD_HAIR_SOLVER_DATA_VALID;
+			}
+			
+			HAIR_solver_update_externals(hmd->solver, scene, ob, dm, hsys, ctime);
+		}
+	}
+}
+
+void BKE_object_sim_tick(Scene *UNUSED(scene), Object *ob, float ctime, float timestep)
+{
+	ModifierData *md;
+	
+	for (md = ob->modifiers.first; md; md = md->next) {
+		if (md->type == eModifierType_Hair) {
+			HairModifierData *hmd = (HairModifierData*) md;
+			HAIR_solver_step(hmd->solver, ctime, timestep);
+		}
+	}
+}
+
+void BKE_object_sim_post_step(Scene *scene, Object *ob, float UNUSED(ctime))
+{
+	ModifierData *md;
+	
+	for (md = ob->modifiers.first; md; md = md->next) {
+		if (md->type == eModifierType_Hair) {
+			HairModifierData *hmd = (HairModifierData*) md;
+			HAIR_solver_apply(hmd->solver, scene, ob, hmd->hairsys);
+		}
+	}
+}
+
 int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot)
 {
 	
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index b24ab63..c1643b8 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1249,8 +1249,44 @@ static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
 		BKE_rigidbody_rebuild_world(scene, ctime);
 }
 
-static void scene_tick(void *vscene, float timestep)
+static void scene_simulation_objects_pre_step(Scene *scene, float ctime)
 {
+	Base *base;
+	for (base = scene->base.first; base; base = base->next) {
+		Object *ob = base->object;
+		BKE_object_sim_pre_step(scene, ob, ctime);
+	}
+}
+
+static void scene_simulation_objects_tick(Scene *scene, float ctime, float timestep)
+{
+	Base *base;
+	for (base = scene->base.first; base; base = base->next) {
+		Object *ob = base->object;
+		BKE_object_sim_tick(scene, ob, ctime, timestep);
+	}
+}
+
+static void scene_simulation_objects_post_step(Scene *scene, float ctime)
+{
+	Base *base;
+	for (base = scene->base.first; base; base = base->next) {
+		Object *ob = base->object;
+		BKE_object_sim_post_step(scene, ob, ctime);
+	}
+}
+
+typedef struct SceneSimStepData {
+	Scene *scene;
+	float t0, t1, t;
+} SceneSimStepData;
+
+static void scene_simulation_tick(void *vdata, float timestep)
+{
+	SceneSimStepData *data = vdata;
+	
+	scene_simulation_objects_tick(data->scene, data->t, timestep);
+	data->t += timestep;
 }
 
 /* fallback implementation for global simulation solvers,
@@ -1258,21 +1294,59 @@ static void scene_tick(void *vscene, float timestep)
  */
 static void scene_do_simulation_step(Scene *scene, float ctime)
 {
-	// XXX TODO !!
+#if 0
+	const int maxSubSteps = INT_MAX;
+	const float fixedTimeStep = 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f);
+	int numSimulationSubSteps = 0;
+	float local_time;
+	
+	//fixed timestep with interpolation
+	local_time += timeStep;
+	if (local_time >= fixedTimeStep)
+	{
+		numSimulationSubSteps = int( local_time / fixedTimeStep);
+		local_time -= numSimulationSubSteps * fixedTimeStep;
+	}
+	
+	if (numSimulationSubSteps) {
+		//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
+		int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps) ? maxSubSteps : numSimulationSubSteps;
+		
+		for (int i=0;i<clampedSimulationSteps;i++)
+		{
+			scene_tick(scene, fixedTimeStep);
+		}
+	}
+	
+	return numSimulationSubSteps;
+#endif
 }
 
-static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
+static void scene_do_rb_simulation_recursive(Scene *scene, float cfra)
 {
 	if (scene->set)
-		scene_do_rb_simulation_recursive(scene->set, ctime);
+		scene_do_rb_simulation_recursive(scene->set, cfra);
 
 	{
 		bool stepped = false;
+		SceneSimStepData data;
+		float frametime = FRA2TIME(1);
+		
+		data.scene = scene;
+		data.t0 = cfra * frametime;
+		// XXX assuming 1 frame step ...
+		data.t1 = data.t0 + frametime;
+		data.t = data.t0;
+		
+		scene_simulation_objects_pre_step(scene, data.t0);
+		
 		if (BKE_scene_check_rigidbody_active(scene))
-			stepped |= BKE_rigidbody_do_simulation(scene, ctime, scene_tick, scene);
+			stepped |= BKE_rigidbody_do_simulation(scene, cfra, scene_simulation_tick, &data);
 	
 		if (!stepped)
-			scene_do_simulation_step(scene, ctime);
+			scene_do_simulation_step(scene, cfra);
+		
+		scene_simulation_objects_post_step(scene, data.t1);
 	}
 }
 
diff --git a/source/blender/hair/intern/HAIR_scene.cpp b/source/blender/hair/intern/HAIR_scene.cpp
index eda1569..56a7b46 100644
--- a/source/blender/hair/intern/HAIR_scene.cpp
+++ b/source/blender/hair/intern/HAIR_scene.cpp
@@ -59,6 +59,9 @@ SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, DerivedM
 	HairCurve *hair;
 	int i;
 	
+	if (!dm)
+		return new SolverData(0, 0);
+	
 	Transform mat = Transform(ob->obmat);
 	
 	/* count points */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 6771b22..e907f89 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1372,11 +1372,9 @@ typedef struct HairModifierData {
 	struct HairSystem *hairsys;
 	
 	struct HAIR_Solver *solver;     /* runtime instance */
-	float prev_cfra;
 	int steps_per_second;
 	
 	int flag;
-	int pad;
 } HairModifierData;
 
 enum {
diff --git a/source/blender/modifiers/intern/MOD_hair.c b/source/blender/modifiers/intern/MOD_hair.c
index 70af492..51d562e 100644
--- a/source/blender/modifiers/intern/MOD_hair.c
+++ b/source/blender/modifiers/intern/MOD_hair.c
@@ -52,7 +52,6 @@ static void initData(ModifierData *md)
 	HairModifierData *hmd = (HairModifierData *) md;
 	
 	hmd->hairsys = BKE_hairsys_new();
-	hmd->prev_cfra = 1.0f; /* XXX where to get this properly ... md-> is not initialized at this point */
 	
 	hmd->steps_per_second = 30;
 }
@@ -77,57 +76,12 @@ static void copyData(ModifierData *md, ModifierData *target)
 	thmd->hairsys = BKE_hairsys_copy(hmd->hairsys);
 	
 	thmd->solver = NULL;
-	thmd->prev_cfra = hmd->prev_cfra;
 }
 
-static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
+static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob),
                                   DerivedMesh *dm,
                                   ModifierApplyFlag UNUSED(flag))
 {
-	HairModifierData *hmd = (HairModifierData *) md;
-	HairSystem *hsys = hmd->hairsys;
-	Scene *scene = md->scene;
-	float cfra = BKE_scene_frame_get(scene), dfra;
-	
-	dfra = cfra - hmd->prev_cfra;
-	if (dfra > 0.0f && FPS > 0.0f) {
-		float prev_steps = hmd->prev_cfra / FPS * (float)hmd->steps_per_second;
-		float steps = cfra / FPS * (float)hmd->steps_per_second;
-		int num_steps = (int)steps - (int)prev_steps;
-		int s;
-		
-		float dt = 1.0f / (float)hmd->steps_per_second;
-		float prev_time = floorf(prev_steps) * dt;
-		float time = floorf(steps) * dt;
-		
-		if (!hmd->solver) {
-			hmd->solver = HAIR_solver_new();
-			hmd->flag &= ~MOD_HAIR_SOLVER_DATA_VALID;
-		}
-		
-		HAIR_solver_set_params(hmd->solver, &hsys->params);
-		
-		if (!hmd->flag & MOD_HAIR_SOLVER_DATA_VALID) {
-			HAIR_solver_build_data(hmd->solver, scene, ob, dm, hsys, time);
-			hmd->flag |= MOD_HAIR_SOLVER_DATA_VALID;
-		}
-		
-		HAIR_solver_update_externals(hmd->solver, scene, ob, dm, hsys, time);
-		
-		if (num_steps < 10000) {
-			struct HAIR_Solver *solver = hmd->solver;
-			float curtime = prev_time;
-			for (s = 0; s < num_steps; ++s) {
-				HAIR_solver_step(solver, curtime, dt);
-				curti

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list