[Bf-blender-cvs] [d572d60] hair_system: Very basic Semi-implicit Euler integrator for hair particles.
Lukas Tönne
noreply at git.blender.org
Sun Jul 27 17:05:38 CEST 2014
Commit: d572d60d03844361032087c4d7dbd7c8d9515e38
Author: Lukas Tönne
Date: Sun Jul 27 17:02:47 2014 +0200
Branches: hair_system
https://developer.blender.org/rBd572d60d03844361032087c4d7dbd7c8d9515e38
Very basic Semi-implicit Euler integrator for hair particles.
The semi-implicit (aka symplectic) Euler integrator is almost as simple
as the basic Euler integration, but conserves Energy much better.
http://en.wikipedia.org/wiki/Semi-implicit_Euler_method
It is the integrator suggested originally in this paper:
http://graphics.pixar.com/library/CurlyHairA/paper.pdf
===================================================================
M source/blender/editors/physics/hair_ops.c
M source/blender/hair/HAIR_capi.cpp
M source/blender/hair/HAIR_capi.h
M source/blender/hair/intern/HAIR_curve.cpp
M source/blender/hair/intern/HAIR_curve.h
M source/blender/hair/intern/HAIR_solver.cpp
M source/blender/hair/intern/HAIR_solver.h
M source/blender/hair/intern/HAIR_types.h
M source/blender/makesdna/DNA_hair_types.h
===================================================================
diff --git a/source/blender/editors/physics/hair_ops.c b/source/blender/editors/physics/hair_ops.c
index d9a578c..a41991d 100644
--- a/source/blender/editors/physics/hair_ops.c
+++ b/source/blender/editors/physics/hair_ops.c
@@ -92,7 +92,7 @@ static int hair_simulate_exec(bContext *C, wmOperator *UNUSED(op))
solver = HAIR_solver_new();
HAIR_solver_init(solver, hsys);
-
+ HAIR_solver_step(solver, 0.1f);
HAIR_solver_apply(solver, hsys);
@@ -146,6 +146,7 @@ static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, Object *
HairPoint *point = points + k;
mul_v3_m4v3(point->co, mat, pa_key->co);
+ zero_v3(point->vel);
}
}
}
diff --git a/source/blender/hair/HAIR_capi.cpp b/source/blender/hair/HAIR_capi.cpp
index 0345e1c..ebf6877 100644
--- a/source/blender/hair/HAIR_capi.cpp
+++ b/source/blender/hair/HAIR_capi.cpp
@@ -76,11 +76,18 @@ void HAIR_solver_init(struct HAIR_Solver *csolver, HairSystem *hsys)
for (int k = 0; k < hair->totpoints; ++k, ++point) {
HairPoint *hair_pt = hair->points + k;
- *point = Point(float3(hair_pt->co[0], hair_pt->co[1], hair_pt->co[2]));
+ *point = Point(hair_pt->co, hair_pt->vel);
}
}
}
+void HAIR_solver_step(struct HAIR_Solver *csolver, float timestep)
+{
+ Solver *solver = (Solver *)csolver;
+
+ solver->step(timestep);
+}
+
void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
{
Solver *solver = (Solver *)csolver;
@@ -98,9 +105,8 @@ void HAIR_solver_apply(struct HAIR_Solver *csolver, HairSystem *hsys)
Point *point = curve->points + k;
HairPoint *hpoint = hcurve->points + k;
- hpoint->co[0] = point->co.x;
- hpoint->co[1] = point->co.y;
- hpoint->co[2] = point->co.z;
+ copy_v3_v3(hpoint->co, point->cur.co.data());
+ copy_v3_v3(hpoint->vel, point->cur.vel.data());
}
}
}
@@ -114,10 +120,8 @@ struct HAIR_SmoothingIteratorFloat3 *HAIR_smoothing_iter_new(HairCurve *curve, f
float *co0 = curve->points[0].co;
float *co1 = curve->points[1].co;
- float3 val = iter->begin(float3(co0[0], co0[1], co0[2]), float3(co1[0], co1[1], co1[2]));
- cval[0] = val.x;
- cval[1] = val.y;
- cval[2] = val.z;
+ float3 val = iter->begin(co0, co1);
+ copy_v3_v3(cval, val.data());
}
/* XXX setting iter->num is not nice, find a better way to invalidate the iterator */
else if (curve->totpoints >= 1) {
@@ -149,10 +153,8 @@ void HAIR_smoothing_iter_next(HairCurve *curve, struct HAIR_SmoothingIteratorFlo
SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
float *co = curve->points[iter->num].co;
- float3 val = iter->next(float3(co[0], co[1], co[2]));
- cval[0] = val.x;
- cval[1] = val.y;
- cval[2] = val.z;
+ float3 val = iter->next(co);
+ copy_v3_v3(cval, val.data());
}
void HAIR_smoothing_iter_end(HairCurve *curve, struct HAIR_SmoothingIteratorFloat3 *citer, float cval[3])
@@ -160,8 +162,6 @@ void HAIR_smoothing_iter_end(HairCurve *curve, struct HAIR_SmoothingIteratorFloa
SmoothingIterator<float3> *iter = (SmoothingIterator<float3> *)citer;
float *co = curve->points[iter->num-1].co;
- float3 val = iter->next(float3(co[0], co[1], co[2]));
- cval[0] = val.x;
- cval[1] = val.y;
- cval[2] = val.z;
+ float3 val = iter->next(co);
+ copy_v3_v3(cval, val.data());
}
diff --git a/source/blender/hair/HAIR_capi.h b/source/blender/hair/HAIR_capi.h
index d6a9581..64d3764 100644
--- a/source/blender/hair/HAIR_capi.h
+++ b/source/blender/hair/HAIR_capi.h
@@ -37,6 +37,7 @@ struct HAIR_SmoothingIteratorFloat3;
struct HAIR_Solver *HAIR_solver_new(void);
void HAIR_solver_free(struct HAIR_Solver *solver);
void HAIR_solver_init(struct HAIR_Solver *solver, struct HairSystem *hsys);
+void HAIR_solver_step(struct HAIR_Solver *solver, float timestep);
void HAIR_solver_apply(struct HAIR_Solver *solver, 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.cpp b/source/blender/hair/intern/HAIR_curve.cpp
index 8a9cfb1..1d9af11 100644
--- a/source/blender/hair/intern/HAIR_curve.cpp
+++ b/source/blender/hair/intern/HAIR_curve.cpp
@@ -32,9 +32,10 @@ Point::Point()
{
}
-Point::Point(const float3 &co) :
- co(co)
+Point::Point(const float3 &co, const float3 &vel)
{
+ cur.co = co;
+ cur.vel = vel;
}
Curve::Curve(int totpoints, Point *points) :
diff --git a/source/blender/hair/intern/HAIR_curve.h b/source/blender/hair/intern/HAIR_curve.h
index 70b4f13..404dbac 100644
--- a/source/blender/hair/intern/HAIR_curve.h
+++ b/source/blender/hair/intern/HAIR_curve.h
@@ -34,10 +34,16 @@
HAIR_NAMESPACE_BEGIN
struct Point {
+ struct State {
+ float3 co;
+ float3 vel;
+ };
+
Point();
- Point(const float3 &co);
+ Point(const float3 &co, const float3 &vel);
- float3 co;
+ State cur;
+ State next;
HAIR_CXX_CLASS_ALLOC(Point)
};
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 834133c..84b6e39 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -86,4 +86,42 @@ void Solver::free_data()
}
}
+float3 Solver::calc_velocity(Curve *curve, Point *point, float time, Point::State &state) const
+{
+ return state.vel;
+}
+
+float3 Solver::calc_acceleration(Curve *curve, Point *point, float time, Point::State &state) const
+{
+ return float3(0.0f, 0.0f, -1.0f);
+}
+
+void Solver::step(float timestep)
+{
+ Curve *curve;
+ Point *point;
+ int totcurve = m_data->totcurves;
+ /*int totpoint = m_data->totpoints;*/
+ int i, k;
+
+ for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
+ int numpoints = curve->totpoints;
+ for (k = 0, point = curve->points; k < numpoints; ++k, ++point) {
+ float3 acc = calc_acceleration(curve, point, 0.0f, point->cur);
+ point->next.vel = point->cur.vel + acc * timestep;
+
+ float3 vel = calc_velocity(curve, point, 0.0f, point->next);
+ point->next.co = point->cur.co + vel * timestep;
+ }
+ }
+
+ /* advance state */
+ for (i = 0, curve = m_data->curves; i < totcurve; ++i, ++curve) {
+ int numpoints = curve->totpoints;
+ for (k = 0, point = curve->points; k < numpoints; ++k, ++point) {
+ point->cur = point->next;
+ }
+ }
+}
+
HAIR_NAMESPACE_END
diff --git a/source/blender/hair/intern/HAIR_solver.h b/source/blender/hair/intern/HAIR_solver.h
index 387570a..fb222ad 100644
--- a/source/blender/hair/intern/HAIR_solver.h
+++ b/source/blender/hair/intern/HAIR_solver.h
@@ -58,6 +58,10 @@ public:
void step(float timestep);
+protected:
+ 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;
+
private:
SolverData *m_data;
diff --git a/source/blender/hair/intern/HAIR_types.h b/source/blender/hair/intern/HAIR_types.h
index 5af8e33..26e8355 100644
--- a/source/blender/hair/intern/HAIR_types.h
+++ b/source/blender/hair/intern/HAIR_types.h
@@ -58,10 +58,14 @@ struct float3 {
__forceinline float3() {}
__forceinline float3(float x, float y, float z) : x(x), y(y), z(z) {}
+ __forceinline float3(float *data) : x(data[0]), y(data[1]), z(data[2]) {}
#endif
__forceinline float operator[](int i) const { return *(&x + i); }
__forceinline float& operator[](int i) { return *(&x + i); }
+
+ __forceinline float *data() { return &x; }
+ __forceinline const float *data() const { return &x; }
};
struct float4 {
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 7312eda..1e83a75 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -36,6 +36,8 @@
typedef struct HairPoint {
float co[3]; /* location in object space */
int pad;
+ float vel[3]; /* velocity */
+ int pad2;
} HairPoint;
typedef struct HairCurve {
More information about the Bf-blender-cvs
mailing list