コード例 #1
0
        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;
        }
コード例 #2
0
        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;
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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;
        }