public static Spline ToSpline(this IEditablePath path) { var count = path.pointCount * 3; if (path.isOpenEnded) { count -= 2; } var spline = new Spline() { isOpenEnded = path.isOpenEnded, points = new Vector3[count] }; for (var i = 0; i < path.pointCount; ++i) { var point = path.GetPoint(i); spline.points[i * 3] = point.position; if (i * 3 + 1 < count) { var nextIndex = EditablePathUtility.Mod(i + 1, path.pointCount); spline.points[i * 3 + 1] = path.CalculateRightTangent(i); spline.points[i * 3 + 2] = path.CalculateLeftTangent(nextIndex); } } return(spline); }
public static void MirrorTangent(this IEditablePath path, int index) { var localToWorldMatrix = path.localToWorldMatrix; path.localToWorldMatrix = Matrix4x4.identity; var controlPoint = path.GetPoint(index); if (controlPoint.tangentMode == TangentMode.Linear) { return; } if (!Mathf.Approximately((controlPoint.localLeftTangent + controlPoint.localRightTangent).sqrMagnitude, 0f)) { if (controlPoint.mirrorLeft) { controlPoint.localLeftTangent = -controlPoint.localRightTangent; } else { controlPoint.localRightTangent = -controlPoint.localLeftTangent; } controlPoint.StoreTangents(); path.SetPoint(index, controlPoint); } path.localToWorldMatrix = localToWorldMatrix; }
public static void UpdateTangentMode(this IEditablePath path, int index) { var localToWorldMatrix = path.localToWorldMatrix; path.localToWorldMatrix = Matrix4x4.identity; var controlPoint = path.GetPoint(index); var isLeftTangentLinear = controlPoint.localLeftTangent == Vector3.zero; var isRightTangentLinear = controlPoint.localRightTangent == Vector3.zero; if (isLeftTangentLinear && isRightTangentLinear) { controlPoint.tangentMode = TangentMode.Linear; } else if (isLeftTangentLinear || isRightTangentLinear) { controlPoint.tangentMode = TangentMode.Broken; } else if (controlPoint.tangentMode != TangentMode.Continuous) { controlPoint.tangentMode = TangentMode.Broken; } controlPoint.StoreTangents(); path.SetPoint(index, controlPoint); path.localToWorldMatrix = localToWorldMatrix; }
public void AddPath(IEditablePath path) { if (!m_Paths.Contains(path)) { m_Paths.Add(path); } }
public static void UpdateTangentsFromMode(this IEditablePath path) { const float kEpsilon = 0.001f; var localToWorldMatrix = path.localToWorldMatrix; path.localToWorldMatrix = Matrix4x4.identity; for (var i = 0; i < path.pointCount; ++i) { var controlPoint = path.GetPoint(i); if (controlPoint.tangentMode == TangentMode.Linear) { controlPoint.localLeftTangent = Vector3.zero; controlPoint.localRightTangent = Vector3.zero; } else if (controlPoint.tangentMode == TangentMode.Broken) { var isLeftEndpoint = path.isOpenEnded && i == 0; var prevPoint = path.GetPrevPoint(i); var nextPoint = path.GetNextPoint(i); var liniarLeftPosition = (prevPoint.position - controlPoint.position) / 3f; var isLeftTangentLinear = isLeftEndpoint || (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < kEpsilon; if (isLeftTangentLinear) { controlPoint.localLeftTangent = Vector3.zero; } var isRightEndpoint = path.isOpenEnded && i == path.pointCount - 1; var liniarRightPosition = (nextPoint.position - controlPoint.position) / 3f; var isRightTangentLinear = isRightEndpoint || (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < kEpsilon; if (isRightTangentLinear) { controlPoint.localRightTangent = Vector3.zero; } if (isLeftTangentLinear && isRightTangentLinear) { controlPoint.tangentMode = TangentMode.Linear; } } else if (controlPoint.tangentMode == TangentMode.Continuous) { //TODO: ensure tangent continuity } controlPoint.StoreTangents(); path.SetPoint(i, controlPoint); } path.localToWorldMatrix = localToWorldMatrix; }
public static Polygon ToPolygon(this IEditablePath path) { var polygon = new Polygon() { isOpenEnded = path.isOpenEnded, points = new Vector3[path.pointCount] }; for (var i = 0; i < path.pointCount; ++i) { polygon.points[i] = path.GetPoint(i).position; } return(polygon); }
public static Vector3 CalculateRightTangent(this IEditablePath path, int index) { var point = path.GetPoint(index); var isTangentLinear = point.localRightTangent == Vector3.zero; var isEndpoint = path.isOpenEnded && index == path.pointCount - 1; var tangent = point.rightTangent; if (isEndpoint) { return(point.position); } if (isTangentLinear) { var nextPoint = path.GetNextPoint(index); var v = nextPoint.position - point.position; tangent = point.position + v.normalized * (v.magnitude / 3f); } return(tangent); }
private void MakeClosedSpline(IEditablePath editablePath) { var points = new Vector3[] { new Vector2(100f, 100f), new Vector2(100f, 200f), new Vector2(200f, 200f), new Vector2(200f, 100f), }; IShape shape = points.ToPolygon(false).ToSpline(); var controlPoints = shape.ToControlPoints(); editablePath.shapeType = shape.type; editablePath.isOpenEnded = shape.isOpenEnded; foreach (var controlPoint in controlPoints) { editablePath.AddPoint(controlPoint); } }
public static Vector3 CalculateLocalRightTangent(this IEditablePath path, int index) { return(path.CalculateRightTangent(index) - path.GetPoint(index).position); }
public static void SetTangentMode(this IEditablePath path, int index, TangentMode tangentMode) { var localToWorldMatrix = path.localToWorldMatrix; path.localToWorldMatrix = Matrix4x4.identity; var controlPoint = path.GetPoint(index); var isEndpoint = path.isOpenEnded && (index == 0 || index == path.pointCount - 1); var oldTangentMode = controlPoint.tangentMode; controlPoint.tangentMode = tangentMode; controlPoint.RestoreTangents(); if (tangentMode == TangentMode.Linear) { controlPoint.localLeftTangent = Vector3.zero; controlPoint.localRightTangent = Vector3.zero; } else if (tangentMode == TangentMode.Continuous && !isEndpoint) { var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; var isRightLinear = controlPoint.localRightTangent == Vector3.zero; var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized); var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) < 0.001f; var isLinear = isLeftLinear && isRightLinear; if ((isLinear || oldTangentMode == TangentMode.Broken) && !isContinous) { var prevPoint = path.GetPrevPoint(index); var nextPoint = path.GetNextPoint(index); var vLeft = prevPoint.position - controlPoint.position; var vRight = nextPoint.position - controlPoint.position; var rightDirection = Vector3.Cross(Vector3.Cross(vLeft, vRight), vLeft.normalized + vRight.normalized).normalized; var scale = 1f / 3f; if (isLeftLinear) { controlPoint.localLeftTangent = vLeft.magnitude * scale * -rightDirection; } else { controlPoint.localLeftTangent = controlPoint.localLeftTangent.magnitude * -rightDirection; } if (isRightLinear) { controlPoint.localRightTangent = vRight.magnitude * scale * rightDirection; } else { controlPoint.localRightTangent = controlPoint.localRightTangent.magnitude * rightDirection; } } } else { var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero; var isRightLinear = controlPoint.localRightTangent == Vector3.zero; if (isLeftLinear || isRightLinear) { if (isLeftLinear) { controlPoint.localLeftTangent = path.CalculateLocalLeftTangent(index); } if (isRightLinear) { controlPoint.localRightTangent = path.CalculateLocalRightTangent(index); } } } controlPoint.StoreTangents(); path.SetPoint(index, controlPoint); path.localToWorldMatrix = localToWorldMatrix; }
public static ControlPoint GetNextPoint(this IEditablePath path, int index) { return(path.GetPoint(EditablePathUtility.Mod(index + 1, path.pointCount))); }
public void RemovePath(IEditablePath path) { m_Paths.Remove(path); }