[Bf-blender-cvs] [2daac22] hair_system: Cleanup of integrator functions, to clarify which values are calculated at which stage in the process.
Lukas Tönne
noreply at git.blender.org
Sun Aug 17 20:32:44 CEST 2014
Commit: 2daac2295708ad952eded5c8407f513a8688e4ef
Author: Lukas Tönne
Date: Sun Aug 17 14:32:24 2014 +0200
Branches: hair_system
https://developer.blender.org/rB2daac2295708ad952eded5c8407f513a8688e4ef
Cleanup of integrator functions, to clarify which values are calculated
at which stage in the process.
This is a preparation for damping calculation fixes.
===================================================================
M source/blender/hair/intern/HAIR_solver.cpp
===================================================================
diff --git a/source/blender/hair/intern/HAIR_solver.cpp b/source/blender/hair/intern/HAIR_solver.cpp
index 46d90e7..defaf17 100644
--- a/source/blender/hair/intern/HAIR_solver.cpp
+++ b/source/blender/hair/intern/HAIR_solver.cpp
@@ -170,7 +170,7 @@ void Solver::free_data()
}
}
-static void calc_root_animation(float t0, float t1, float t, Curve *curve, float3 &co, float3 &vel, float3 &normal, float3 &tangent)
+static float3 get_root_location(float t0, float t1, float t, Curve *curve)
{
const CurveRoot &root0 = curve->root0;
const CurveRoot &root1 = curve->root1;
@@ -179,14 +179,38 @@ static void calc_root_animation(float t0, float t1, float t, Curve *curve, float
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);
+ return root0.co * mx + root1.co * x;
+ }
+ else {
+ return root0.co;
+ }
+}
+
+static float3 get_root_velocity(float t0, float t1, float t, Curve *curve)
+{
+ const CurveRoot &root0 = curve->root0;
+ const CurveRoot &root1 = curve->root1;
+
+ if (t1 > t0) {
+ return (root1.co - root0.co) / (t1 - t0);
+ }
+ else {
+ return float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+static void get_root_frame(float t0, float t1, float t, Curve *curve, float3 &normal, float3 &tangent)
+{
+ const CurveRoot &root0 = curve->root0;
+ const CurveRoot &root1 = curve->root1;
+
+ if (t1 > t0) {
+ float x = (t - t0) / (t1 - t0);
+
interp_v3v3_slerp(normal, root0.nor, root1.nor, x);
interp_v3v3_slerp(tangent, root0.tan, root1.tan, x);
}
else {
- co = root0.co;
- vel = float3(0.0f, 0.0f, 0.0f);
normal = root0.nor;
tangent = root0.tan;
}
@@ -283,7 +307,7 @@ static void do_external_forces(const HairParams ¶ms, const SolverForces &for
static void do_damping(const HairParams ¶ms, const SolverForces &forces, float time, float timestep, const Point *point0, const Point *point1, const Frame &frame,
float3 &force0, float3 &force1)
{
- const int totsteps = 1; /* XXX TODO can have multiple damping steps per integration step for accuracy */
+ const int totsteps = params.substeps_damping;
float dt = timestep / (float)totsteps;
float3 stretch, bend;
@@ -294,6 +318,7 @@ static void do_damping(const HairParams ¶ms, const SolverForces &forces, flo
for (int step = 0; step < totsteps; ++step) {
stretch = calc_stretch_damping(params, point0, point1, time);
bend = calc_bend_damping(params, point0, point1, frame, time);
+
force0 = force0 + stretch + bend;
force1 = force1 - stretch - bend;
@@ -343,14 +368,126 @@ static void do_collision(const HairParams ¶ms, const SolverForces &forces, f
}
}
+static void calc_forces(const HairParams ¶ms, const SolverForces &forces, float time, float timestep, float restitution_scale, float t0, float t1,
+ const SolverTaskData &data, const PointContactCache &contacts)
+{
+ /* clear forces */
+ for (int k = 0; k < data.totpoints; ++k) {
+ data.points[k].force_accum = float3(0.0f, 0.0f, 0.0f);
+ }
+
+ Curve *curve = data.curves;
+ for (int i = 0; i < data.totcurves; ++i, ++curve) {
+ int numpoints = curve->totpoints;
+
+ /* note: roots are evaluated at the end of the timestep: time + timestep
+ * so the hair points align perfectly with them
+ */
+ float3 root_nor, root_tan;
+ get_root_frame(t0, t1, time + timestep, curve, root_nor, root_tan);
+
+ Frame rest_frame(root_nor, root_tan, cross_v3_v3(root_nor, root_tan));
+ FrameIterator<SolverDataLocWalker> frame_iter(SolverDataLocWalker(curve), curve->avg_rest_length, params.bend_smoothing, rest_frame);
+
+ float3 intern_force, intern_force_next, extern_force, damping, damping_next;
+ float3 acc_prev; /* reactio from previous point */
+
+ /* Root point animation */
+ Point *point = curve->points;
+ int k = 0;
+ if (numpoints > 0) {
+ Point *point_next = k < numpoints-1 ? point+1 : NULL;
+ do_internal_forces(params, forces, time, timestep, point, point_next, frame_iter.frame(), intern_force, intern_force_next);
+ do_external_forces(params, forces, time, timestep, point, point_next, frame_iter.frame(), extern_force);
+ do_damping(params, forces, time, timestep, point, point_next, frame_iter.frame(), damping, damping_next);
+
+ frame_iter.next();
+ acc_prev = intern_force_next + damping_next;
+ ++k;
+ ++point;
+ }
+
+ /* Integrate free points */
+ for (; k < numpoints; ++k, ++point) {
+ Point *point_next = k < numpoints-1 ? point+1 : NULL;
+ do_internal_forces(params, forces, time, timestep, point, point_next, frame_iter.frame(), intern_force, intern_force_next);
+ do_external_forces(params, forces, time, timestep, point, point_next, frame_iter.frame(), extern_force);
+ do_damping(params, forces, time, timestep, point, point_next, frame_iter.frame(), damping, damping_next);
+
+ point->force_accum = point->force_accum + intern_force + extern_force + damping + acc_prev;
+
+ frame_iter.next();
+ acc_prev = intern_force_next + damping_next;
+ }
+
+ }
+
+ do_collision(params, forces, time, timestep, restitution_scale, data, contacts);
+}
+
+static void calc_velocity_step(const SolverTaskData &data, float time, float timestep, float t0, float t1)
+{
+ Curve *curve = data.curves;
+ for (int i = 0; i < data.totcurves; ++i, ++curve) {
+ int numpoints = curve->totpoints;
+
+ /* note: roots are evaluated at the end of the timestep: time + timestep
+ * so the hair points align perfectly with them
+ */
+ float3 root_vel = get_root_velocity(t0, t1, time + timestep, curve);
+
+ /* Root point animation */
+ Point *point = curve->points;
+ int k = 0;
+ if (numpoints > 0) {
+ point->next.vel = root_vel;
+
+ ++k;
+ ++point;
+ }
+
+ /* Integrate free points */
+ for (; k < numpoints; ++k, ++point) {
+ /* semi-implicit Euler step */
+ point->next.vel = point->cur.vel + point->force_accum * timestep;
+ }
+ }
+}
+
+static void calc_position_step(const SolverTaskData &data, float time, float timestep, float t0, float t1)
+{
+ Curve *curve = data.curves;
+ for (int i = 0; i < data.totcurves; ++i, ++curve) {
+ int numpoints = curve->totpoints;
+
+ /* note: roots are evaluated at the end of the timestep: time + timestep
+ * so the hair points align perfectly with them
+ */
+ float3 root_co = get_root_location(t0, t1, time + timestep, curve);
+
+ /* Root point animation */
+ Point *point = curve->points;
+ int k = 0;
+ if (numpoints > 0) {
+ point->next.co = root_co;
+
+ ++k;
+ ++point;
+ }
+
+ /* Integrate free points */
+ for (; k < numpoints; ++k, ++point) {
+ /* semi-implicit Euler step */
+ point->next.co = point->cur.co + point->next.vel * timestep;
+ }
+ }
+}
+
void Solver::do_integration(float time, float timestep, const SolverTaskData &data, const PointContactCache &contacts) const
{
const int totsteps = m_params.substeps_forces; /* can have multiple integration steps per tick for accuracy */
float dt = timestep / (float)totsteps;
- int totcurve = data.totcurves;
- /*int totpoint = data.totpoints;*/
-
/* Note: the restitution scale is determined by the overall timestep,
* since collisions are only generated once during this interval.
* Otherwise restitution forces would be num_force_steps times too large
@@ -359,92 +496,14 @@ void Solver::do_integration(float time, float timestep, const SolverTaskData &da
for (int step = 0; step < totsteps; ++step) {
- /* clear forces */
- for (int k = 0; k < data.totpoints; ++k) {
- data.points[k].force_accum = float3(0.0f, 0.0f, 0.0f);
- }
-
- Curve *curve = data.curves;
- for (int i = 0; i < totcurve; ++i, ++curve) {
- int numpoints = curve->totpoints;
-
- /* note: roots are evaluated at the end of the timestep: time + timestep
- * so the hair points align perfectly with them
- */
- float3 root_co, root_vel, normal, tangent;
- calc_root_animation(m_data->t0, m_data->t1, time + timestep, curve, root_co, root_vel, normal, tangent);
-
- Frame rest_frame(normal, tangent, cross_v3_v3(normal, tangent));
- FrameIterator<SolverDataLocWalker> frame_iter(SolverDataLocWalker(curve), curve->avg_rest_length, m_params.bend_smoothing, rest_frame);
-
- float3 intern_force, intern_force_next, extern_force, damping, damping_next;
- float3 acc_prev; /* reactio from previous point */
-
- /* Root point animation */
- Point *point = curve->points;
- int k = 0;
- if (numpoints > 0) {
- Point *point_next = k < numpoints-1 ? point+1 : NULL;
- do_internal_forces(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), intern_force, intern_force_next);
- do_external_forces(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), extern_force);
- do_damping(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), damping, damping_next);
-
- frame_iter.next();
- acc_prev = intern_force_next + damping_next;
- ++k;
- ++point;
- }
-
- /* Integrate free points */
- for (; k < numpoints; ++k, ++point) {
- Point *point_next = k < numpoints-1 ? point+1 : NULL;
- do_internal_forces(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), intern_force, intern_force_next);
- do_external_forces(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), extern_force);
- do_damping(m_params, m_forces, time, dt, point, point_next, frame_iter.frame(), damping, damping_next);
-
- point->force_accum = point->force_accum + intern_force + extern_force + damping + acc_prev;
-
- frame_iter.next();
- acc_prev = intern_force_next + damping_next;
- }
-
- }
-
- do_collision(m_params, m_forces, time, dt, restitution_scale, data, contacts);
+ /* calculate Point.force_accum vectors */
+ calc_forces(m_params, m_forces, time, dt, restitution_scale, m_data->t0, m_data->t1, data, contacts);
/* integrate */
- {
- Curve *curve = data.curves;
- for (int i = 0; i < totcurve; ++i, ++curve) {
- int numpoints = curve->totpoints;
-
- /* note: roots are evaluated at the end of the timestep: time + timestep
- * so the hair points align perfectly with them
-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list