public void smooth_append(CurvePreview preview, Vector3f newPos, float fDistThresh) { // empty curve, always append if (preview.VertexCount == 0) { preview.AppendVertex(newPos); last_append = newPos; appended_last_update = true; have_temp_append = false; return; } double d = (newPos - last_append).Length; if (d < fDistThresh) { // have not gone far enough for a real new vertex! Vector3f usePos = new Vector3f(newPos); bool bValid = false; // do we have enough vertices to do a good job? if (preview.VertexCount > 3) { int nLast = (have_temp_append) ? preview.VertexCount - 2 : preview.VertexCount - 1; Vector3d tan = preview.Tangent(nLast); double fDot = tan.Dot((usePos - preview[nLast]).Normalized); if (fDot > 0.9f) // cos(25) ~= 0.9f // new vtx is aligned with tangent of last "real" vertex { bValid = true; } else { // not aligned, try projection onto tangent Line3d l = new Line3d(preview[nLast], tan); double t = l.Project(newPos); if (t > 0) { // projection of new vtx is 'ahead' so we can use it usePos = (Vector3f)l.PointAt(t); bValid = true; } } } if (bValid) { if (appended_last_update) { preview.AppendVertex(usePos); have_temp_append = true; } else if (have_temp_append) { preview[preview.VertexCount - 1] = usePos; } } appended_last_update = false; } else { // ok we drew far enough, add this position if (have_temp_append) { // re-use temp vertex preview[preview.VertexCount - 1] = newPos; have_temp_append = false; } else { preview.AppendVertex(newPos); } last_append = newPos; appended_last_update = true; // do smoothing pass smoother.End = preview.VertexCount - 1; smoother.Start = MathUtil.Clamp(smoother.End - 5, 0, smoother.End); smoother.UpdateDeformation(2); } }