[Bf-blender-cvs] [501f58c] hair_system: Base support for hair root animation.

Lukas Tönne noreply at git.blender.org
Wed Jul 30 16:27:12 CEST 2014


Commit: 501f58c41f017118304aaf6e3fcae64f0f87cdab
Author: Lukas Tönne
Date:   Wed Jul 30 16:22:33 2014 +0200
Branches: hair_system
https://developer.blender.org/rB501f58c41f017118304aaf6e3fcae64f0f87cdab

Base support for hair root animation.

Note: This does not work currently, because of the way the solver is
reconstructed in every time step currently, and so does not provide
actual changes in the transform.

Note2: The mesh sampling system does not support changes in DerivedMesh
topology so far. It can be necessary to move the hair system to the
bottom of the modifier stack, because the hair roots are created for
the final mesh version and for animation support it can only use the
mesh being passed to the modifier. Any later subsurf etc. (constructive
modifier) will alter the topology and cause a difference in the DM used
for hair roots vs. DM used for calculating deformation.

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

M	source/blender/editors/space_view3d/drawhair.c
M	source/blender/hair/HAIR_capi.cpp
M	source/blender/hair/HAIR_capi.h
M	source/blender/hair/intern/HAIR_curve.h
M	source/blender/hair/intern/HAIR_scene.cpp
M	source/blender/hair/intern/HAIR_scene.h
M	source/blender/hair/intern/HAIR_solver.cpp
M	source/blender/hair/intern/HAIR_solver.h
M	source/blender/modifiers/intern/MOD_hair.c

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

diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index f0e9aa8..2a6c5cb 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -57,7 +57,7 @@
 
 /* TODO vertex/index buffers, etc. etc., avoid direct mode ... */
 
-static void draw_hair_curve(HairSystem *hsys, HairCurve *hair)
+static void draw_hair_curve(HairSystem *UNUSED(hsys), HairCurve *hair)
 {
 	HairPoint *point;
 	int k;
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 440bccf..eb8a283 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -57,21 +57,28 @@ void HAIR_solver_free(struct HAIR_Solver *csolver)
 	delete solver;
 }
 
-void HAIR_solver_init(struct HAIR_Solver *csolver, Scene *scene, Object *ob, HairSystem *hsys)
+void HAIR_solver_init(struct HAIR_Solver *csolver, Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time)
 {
 	Solver *solver = (Solver *)csolver;
 	
 	solver->forces().gravity = float3(scene->physics_settings.gravity);
 	
-	SolverData *data = SceneConverter::build_solver_data(scene, ob, hsys);
+	SolverData *data = SceneConverter::build_solver_data(scene, ob, dm, hsys, time);
 	solver->set_data(data);
 }
 
-void HAIR_solver_step(struct HAIR_Solver *csolver, float timestep)
+void HAIR_solver_update_externals(struct HAIR_Solver *csolver, Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time)
 {
 	Solver *solver = (Solver *)csolver;
 	
-	solver->step(timestep);
+	SceneConverter::update_solver_data_externals(solver->data(), scene, ob, dm, hsys, time);
+}
+
+void HAIR_solver_step(struct HAIR_Solver *csolver, float time, float timestep)
+{
+	Solver *solver = (Solver *)csolver;
+	
+	solver->step(time, timestep);
 }
 
 void HAIR_solver_apply(struct HAIR_Solver *csolver, Scene *scene, Object *ob, HairSystem *hsys)
diff --git a/source/blender/hair/HAIR_capi.h b/source/blender/hair/HAIR_capi.h
index dc70add..f9a915e 100644
--- a/source/blender/hair/HAIR_capi.h
+++ b/source/blender/hair/HAIR_capi.h
@@ -30,6 +30,7 @@ extern "C" {
 
 struct Scene;
 struct Object;
+struct DerivedMesh;
 struct HairCurve;
 struct HairSystem;
 
@@ -39,8 +40,9 @@ struct HAIR_FrameIterator;
 
 struct HAIR_Solver *HAIR_solver_new(const struct HairParams *params);
 void HAIR_solver_free(struct HAIR_Solver *solver);
-void HAIR_solver_init(struct HAIR_Solver *solver, struct Scene *scene, struct Object *ob, struct HairSystem *hsys);
-void HAIR_solver_step(struct HAIR_Solver *solver, float timestep);
+void HAIR_solver_init(struct HAIR_Solver *solver, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, struct HairSystem *hsys, float time);
+void HAIR_solver_update_externals(struct HAIR_Solver *solver, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, struct HairSystem *hsys, float time);
+void HAIR_solver_step(struct HAIR_Solver *solver, float time, float timestep);
 void HAIR_solver_apply(struct HAIR_Solver *solver, struct Scene *scene, struct Object *ob, struct HairSystem *hsys);
 
 struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(struct HairCurve *curve, float rest_length, float amount, float cval[3]);
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index c267759..dbd649f 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -51,13 +51,20 @@ struct Point {
 	HAIR_CXX_CLASS_ALLOC(Point)
 };
 
+struct CurveRoot {
+	float3 co;
+	float3 nor;
+};
+
 struct Curve {
 	Curve();
 	Curve(int totpoints, Point *points);
 	
 	Point *points;
 	int totpoints;
-
+	
+	CurveRoot root0, root1;
+	
 	HAIR_CXX_CLASS_ALLOC(Curve)
 };
 
diff --git a/source/blender/hair/intern/HAIR_scene.cpp b/source/blender/hair/intern/HAIR_scene.cpp
index 63f156b..eda1569 100644
--- a/source/blender/hair/intern/HAIR_scene.cpp
+++ b/source/blender/hair/intern/HAIR_scene.cpp
@@ -28,7 +28,11 @@ extern "C" {
 #include "BLI_math.h"
 
 #include "DNA_hair_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_mesh_sample.h"
 }
 
 #include "HAIR_curve.h"
@@ -39,7 +43,18 @@ extern "C" {
 
 HAIR_NAMESPACE_BEGIN
 
-SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, HairSystem *hsys)
+static bool mesh_sample_eval(DerivedMesh *dm, const Transform &tfm, MSurfaceSample *sample, float3 &loc, float3 &nor)
+{
+	float vloc[3], vnor[3];
+	
+	bool ok = BKE_mesh_sample_eval(dm, sample, vloc, vnor);
+	loc = transform_point(tfm, vloc);
+	nor = transform_direction(tfm, vnor);
+	
+	return ok;
+}
+
+SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time)
 {
 	HairCurve *hair;
 	int i;
@@ -57,10 +72,16 @@ SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, HairSyst
 	Curve *solver_curves = data->curves;
 	Point *solver_points = data->points;
 	
+	data->t0 = data->t1 = time;
+	
 	/* copy scene data to solver data */
 	Point *point = solver_points;
 	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
-		solver_curves[i] = Curve(hair->totpoints, point);
+		Curve *curve = solver_curves + i;
+		*curve = Curve(hair->totpoints, point);
+		
+		mesh_sample_eval(dm, mat, &hair->root, curve->root1.co, curve->root1.nor);
+		curve->root0 = curve->root1;
 		
 		for (int k = 0; k < hair->totpoints; ++k, ++point) {
 			HairPoint *hair_pt = hair->points + k;
@@ -77,6 +98,27 @@ SolverData *SceneConverter::build_solver_data(Scene *scene, Object *ob, HairSyst
 	return data;
 }
 
+void SceneConverter::update_solver_data_externals(SolverData *data, Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time)
+{
+	int i;
+	
+	Transform mat = Transform(ob->obmat);
+	
+	Curve *solver_curves = data->curves;
+	int totcurves = data->totcurves;
+	
+	data->t0 = data->t1;
+	data->t1 = time;
+	
+	for (i = 0; i < totcurves; ++i) {
+		HairCurve *hcurve = hsys->curves + i;
+		Curve *curve = solver_curves + i;
+		
+		curve->root0 = curve->root1;
+		mesh_sample_eval(dm, mat, &hcurve->root, curve->root1.co, curve->root1.nor);
+	}
+}
+
 void SceneConverter::apply_solver_data(SolverData *data, Scene *scene, Object *ob, HairSystem *hsys)
 {
 	int i;
diff --git a/source/blender/hair/intern/HAIR_scene.h b/source/blender/hair/intern/HAIR_scene.h
index 4b3548e..777e59c 100644
--- a/source/blender/hair/intern/HAIR_scene.h
+++ b/source/blender/hair/intern/HAIR_scene.h
@@ -29,6 +29,7 @@
 
 struct Scene;
 struct Object;
+struct DerivedMesh;
 struct HairSystem;
 
 HAIR_NAMESPACE_BEGIN
@@ -36,7 +37,9 @@ HAIR_NAMESPACE_BEGIN
 struct SolverData;
 
 struct SceneConverter {
-	static SolverData *build_solver_data(Scene *scene, Object *ob, HairSystem *hsys);
+	static SolverData *build_solver_data(Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time);
+	static void update_solver_data_externals(SolverData *data, Scene *scene, Object *ob, DerivedMesh *dm, HairSystem *hsys, float time);
+	
 	static void apply_solver_data(SolverData *data, Scene *scene, Object *ob, HairSystem *hsys);
 };
 
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 54685b4..f56bfa7 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -136,6 +136,24 @@ void Solver::free_data()
 	}
 }
 
+void Solver::calc_root_animation(float t0, float t1, float t, Curve *curve, float3 &co, float3 &vel) const
+{
+	const CurveRoot &root0 = curve->root0;
+	const CurveRoot &root1 = curve->root1;
+	
+	if (t1 > t0) {
+		float x = (t - t0) / (t1 - t0);
+		float mx = 1.0f - x;
+		
+		co = root0.co * mx + root1.co * x;
+		vel = (root1.co - root0.co) / (t1 - t0);
+	}
+	else {
+		co = root0.co;
+		vel = float3(0.0f, 0.0f, 0.0f);
+	}
+}
+
 float3 Solver::calc_velocity(Curve *curve, Point *point, float time, Point::State &state) const
 {
 	return state.vel;
@@ -186,7 +204,7 @@ float3 Solver::calc_acceleration(Curve *curve, Point *point, float time, Point::
 	return acc;
 }
 
-void Solver::step(float timestep)
+void Solver::step(float time, float timestep)
 {
 	Curve *curve;
 	Point *point;
@@ -194,8 +212,6 @@ void Solver::step(float timestep)
 	/*int totpoint = m_data->totpoints;*/
 	int i, k;
 	
-	float time = 0.0f;
-	
 	for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
 		int numpoints = curve->totpoints;
 		float3 stretch, prev_stretch, bend, prev_bend;
@@ -204,9 +220,7 @@ void Solver::step(float timestep)
 		k = 0;
 		point = curve->points;
 		
-		// TODO actually evaluate animation here
-		point->next.co = point->cur.co;
-		point->next.vel = float3(0.0f, 0.0f, 0.0f);
+		calc_root_animation(m_data->t0, m_data->t1, time, curve, point->next.co, point->next.vel);
 		
 		if (k < numpoints-1) {
 			stretch = calc_stretch_force(curve, point, point+1, time);
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 01b40d3..f4d444a 100644
--- a/source/blender/hair/intern/HAIR_solver.h
+++ b/source/blender/hair/intern/HAIR_solver.h
@@ -47,6 +47,8 @@ struct SolverData {
 	int totcurves;
 	int totpoints;
 	
+	float t0, t1;
+	
 	void precompute_rest_bend();
 	
 	HAIR_CXX_CLASS_ALLOC(SolverData)
@@ -72,9 +74,10 @@ public:
 	void free_data();
 	SolverData *data() const { return m_data; }
 	
-	void step(float timestep);
+	void step(float time, float timestep);
 	
 protected:
+	void calc_root_animation(float t0, float t1, float t, Curve *curve, float3 &co, float3 &vel) const;
 	float3 calc_velocity(Curve *curve, Point *point, float time, Point::State &state) const;
 	float3 calc_acceleration(Curve *curve, Point *point, float time, Point::State &state) const;
 	float3 calc_stretch_force(Curve *curve, Point *point0, Point *point1, float time) const;
diff --git a/source/blender/modifiers/intern/MOD_hair.c b/source/blender/modifiers/intern/MOD_hair.c
index 7fbc0fe..8cd2fb0 100644
--- a/source/blender/modifiers/intern/MOD_hair.c
+++ b/source/blender/modifiers/intern/MOD_hair.c
@@ -28,6 +28,7 @@
  *  \ingroup modifiers
  */
 
+#include "BLI_math.h"
 #include "BLI_utild

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list