diff options
author | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2013-01-15 23:44:41 +0400 |
---|---|---|
committer | Stuart Broadfoot <gbroadfoot@hotmail.com> | 2013-01-15 23:44:41 +0400 |
commit | 3373b8154b16d345b0e1fcbdb55d03d8ec088006 (patch) | |
tree | eec2b36ebf0f70ca882a26e6525839c9f7f2013a /intern/cycles/render/curves.cpp | |
parent | 0967b39be1cf9644454e1d4e9c6d0250d9a36e85 (diff) |
Cycles Hair: Introduction of Cardinal Spline Curve Segments and minor fixes.
The curve segment primitive has been added. This includes an intersection function and changes to the BVH.
A few small errors in the line segment intersection routine are also fixed.
Diffstat (limited to 'intern/cycles/render/curves.cpp')
-rw-r--r-- | intern/cycles/render/curves.cpp | 107 |
1 files changed, 80 insertions, 27 deletions
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp index 3299503b4ab..3ee441ef095 100644 --- a/intern/cycles/render/curves.cpp +++ b/intern/cycles/render/curves.cpp @@ -29,6 +29,52 @@ CCL_NAMESPACE_BEGIN +/* Curve functions */ + +void curvebounds(float *lower, float *upper, float3 *p, int dim) +{ + float *p0 = &p[0].x; + float *p1 = &p[1].x; + float *p2 = &p[2].x; + float *p3 = &p[3].x; + float fc = 0.71f; + float curve_coef[4]; + curve_coef[0] = p1[dim]; + curve_coef[1] = -fc*p0[dim] + fc*p2[dim]; + curve_coef[2] = 2.0f * fc * p0[dim] + (fc - 3.0f) * p1[dim] + (3.0f - 2.0f * fc) * p2[dim] - fc * p3[dim]; + curve_coef[3] = -fc * p0[dim] + (2.0f - fc) * p1[dim] + (fc - 2.0f) * p2[dim] + fc * p3[dim]; + float discroot = curve_coef[2] * curve_coef[2] - 3 * curve_coef[3] * curve_coef[1]; + float ta = -1.0f; + float tb = -1.0f; + if(discroot >= 0) { + discroot = sqrt(discroot); + ta = (-curve_coef[2] - discroot) / (3 * curve_coef[3]); + tb = (-curve_coef[2] + discroot) / (3 * curve_coef[3]); + ta = (ta > 1.0f || ta < 0.0f) ? -1.0f : ta; + tb = (tb > 1.0f || tb < 0.0f) ? -1.0f : tb; + } + + *upper = max(p1[dim],p2[dim]); + *lower = min(p1[dim],p2[dim]); + float exa = p1[dim]; + float exb = p2[dim]; + float t2; + float t3; + if(ta >= 0.0f) { + t2 = ta * ta; + t3 = t2 * ta; + exa = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * ta + curve_coef[0]; + } + if(tb >= 0.0f) { + t2 = tb * tb; + t3 = t2 * tb; + exb = curve_coef[3] * t3 + curve_coef[2] * t2 + curve_coef[1] * tb + curve_coef[0]; + } + *upper = max(*upper, max(exa,exb)); + *lower = min(*lower, min(exa,exb)); + +} + /* Hair System Manager */ CurveSystemManager::CurveSystemManager() @@ -36,9 +82,10 @@ CurveSystemManager::CurveSystemManager() primitive = CURVE_LINE_SEGMENTS; line_method = CURVE_CORRECTED; interpolation = CURVE_CARDINAL; - triangle_method = CURVE_CAMERA; + triangle_method = CURVE_CAMERA_TRIANGLES; resolution = 3; segments = 1; + subdivisions = 3; normalmix = 1.0f; encasing_ratio = 1.01f; @@ -75,31 +122,36 @@ void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scen kcurve->curveflags = 0; - if(primitive == CURVE_SEGMENTS) - kcurve->curveflags |= CURVE_KN_INTERPOLATE; - - if(line_method == CURVE_ACCURATE) - kcurve->curveflags |= CURVE_KN_ACCURATE; - if(line_method == CURVE_CORRECTED) - kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION; - if(line_method == CURVE_POSTCORRECTED) - kcurve->curveflags |= CURVE_KN_POSTINTERSECTCORRECTION; - - if(use_tangent_normal) - kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL; - if(use_tangent_normal_correction) - kcurve->curveflags |= CURVE_KN_NORMALCORRECTION; - if(use_tangent_normal_geometry) - kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL; - if(use_joined) - kcurve->curveflags |= CURVE_KN_CURVEDATA; - if(use_backfacing) - kcurve->curveflags |= CURVE_KN_BACKFACING; - if(use_encasing) - kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER; - - kcurve->normalmix = normalmix; - kcurve->encasing_ratio = encasing_ratio; + if(use_curves) { + if(primitive == CURVE_SEGMENTS || primitive == CURVE_RIBBONS) + kcurve->curveflags |= CURVE_KN_INTERPOLATE; + if(primitive == CURVE_RIBBONS) + kcurve->curveflags |= CURVE_KN_RIBBONS; + + if(line_method == CURVE_ACCURATE) + kcurve->curveflags |= CURVE_KN_ACCURATE; + if(line_method == CURVE_CORRECTED) + kcurve->curveflags |= CURVE_KN_INTERSECTCORRECTION; + if(line_method == CURVE_POSTCORRECTED) + kcurve->curveflags |= CURVE_KN_POSTINTERSECTCORRECTION; + + if(use_tangent_normal) + kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL; + if(use_tangent_normal_correction) + kcurve->curveflags |= CURVE_KN_NORMALCORRECTION; + if(use_tangent_normal_geometry) + kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL; + if(use_joined) + kcurve->curveflags |= CURVE_KN_CURVEDATA; + if(use_backfacing) + kcurve->curveflags |= CURVE_KN_BACKFACING; + if(use_encasing) + kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER; + + kcurve->normalmix = normalmix; + kcurve->encasing_ratio = encasing_ratio; + kcurve->subdivisions = subdivisions; + } if(progress.get_cancel()) return; @@ -130,7 +182,8 @@ bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager) use_curves == CurveSystemManager.use_curves && use_joined == CurveSystemManager.use_joined && segments == CurveSystemManager.segments && - use_parents == CurveSystemManager.use_parents); + use_parents == CurveSystemManager.use_parents && + subdivisions == CurveSystemManager.subdivisions); } bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemManager) |