private static int CurvyControlPointsHash(ICurvySpline spline) { if (spline.ControlPoints.Count == 0) { return(0); } var hash_codes = spline.ControlPoints .Where(p => p != null) .Select((Func <ICurvySplineSegment, int>)CurvySplineSegmentHash) .ToArray(); int xor_hash = hash_codes.Aggregate((a, b) => a ^ b); return(xor_hash); }
private static void ApplyConstraint( Transform transform, ICurvySpline spline, float path_angle, ref float?distance, Vector3 position_offset, ERotationConstraintMode rotation_constraint_mode, bool allow_roll, Quaternion rotation_offset) { var relative_position = spline.transform.InverseTransformPoint(transform.position); var nearest_tf = spline.GetNearestPointTF(relative_position); var nearest_point = spline.Interpolate(nearest_tf); var position_to_point = relative_position - nearest_point; if (distance.HasValue) { position_to_point = distance.Value * position_to_point.normalized; } else { distance = Vector3.Distance(nearest_point, relative_position); } var tangent = spline.GetTangent(nearest_tf); var orientation = Quaternion.AngleAxis(path_angle, tangent) * spline.GetOrientationFast(nearest_tf); var normal = orientation * Vector3.up; var relative_constrained_position = Vector3.ProjectOnPlane(position_to_point, normal) + nearest_point; relative_constrained_position += orientation * position_offset; var constrained_position = spline.transform.TransformPoint(relative_constrained_position); transform.position = constrained_position; Vector3 up; if (allow_roll) { up = transform.up; } else { up = Vector3.up; } switch (rotation_constraint_mode) { default: case ERotationConstraintMode.None: break; case ERotationConstraintMode.Tangent: transform.rotation = Quaternion.LookRotation(tangent, up) * rotation_offset; break; case ERotationConstraintMode.Normal: transform.rotation = Quaternion.LookRotation(normal, up) * rotation_offset; break; case ERotationConstraintMode.Binormal: var binormal = Vector3.Cross(tangent, normal); transform.rotation = Quaternion.LookRotation(binormal, up) * rotation_offset; break; } }