Beispiel #1
0
        /// <summary>
        ///     Gets the tangents.
        /// </summary>
        /// <param name="inTangent">In tangent.</param>
        /// <param name="outTangent">Out tangent.</param>
        /// <param name="previousPoint">Previous point.</param>
        /// <param name="point">Point.</param>
        /// <param name="nextPoint">Next point.</param>
        public static void GetTangents(out Vector3 inTangent, out Vector3 outTangent, IBezierPoint previousPoint,
                                       IBezierPoint point, IBezierPoint nextPoint)
        {
            switch (point.tangentMode)
            {
            case TangentMode.Smooth:
                inTangent  = point.inTangent;
                outTangent = point.inTangent * -1.0f;
                break;

            case TangentMode.Corner:
                inTangent  = point.inTangent;
                outTangent = point.outTangent;
                break;

            case TangentMode.Symmetric:
                GetSymmetricTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);
                break;

            case TangentMode.Auto:
                GetAutoTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Gets the out tangent.
        /// </summary>
        /// <returns>The out tangent.</returns>
        /// <param name="previousPoint">Previous point.</param>
        /// <param name="point">Point.</param>
        /// <param name="nextPoint">Next point.</param>
        public static Vector3 GetOutTangent(IBezierPoint previousPoint, IBezierPoint point, IBezierPoint nextPoint)
        {
            Vector3 inTangent;
            Vector3 outTangent;

            GetTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);

            return(outTangent);
        }
Beispiel #3
0
        /// <summary>
        ///     Using the curve between pointA and pointB we take a discrete number of line segments
        ///     and return all of the points that make those lines.
        /// </summary>
        /// <returns>The segment points.</returns>
        /// <param name="output">Output.</param>
        /// <param name="pointA">Point a.</param>
        /// <param name="pointB">Point b.</param>
        /// <param name="pointC">Point c.</param>
        /// <param name="pointD">Point d.</param>
        public static void GetSegmentPoints(ref Vector3[] output, IBezierPoint pointA, IBezierPoint pointB,
                                            IBezierPoint pointC, IBezierPoint pointD)
        {
            Array.Resize(ref s_SegmentPointDeltas, LENGTH_LINE_SEGMENTS + 1);

            for (int index = 0; index < LENGTH_LINE_SEGMENTS + 1; index++)
            {
                s_SegmentPointDeltas[index] = DELTA_LINE_SEGMENTS * index;
            }

            Interpolate(ref output, pointA, pointB, pointC, pointD, s_SegmentPointDeltas);
        }
Beispiel #4
0
        /// <summary>
        ///     Draws the handle for a bezier points tangents.
        /// </summary>
        /// <param name="pointA">Point a.</param>
        /// <param name="pointB">Point b.</param>
        /// <param name="pointC">Point c.</param>
        public static void BezierPointTangentsHandle(IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC)
        {
            if (pointA != null)
            {
                Vector3 inTangent = BezierPath.GetInTangent(pointA, pointB, pointC);
                pointB.inTangent = TangentHandle(pointB.position, inTangent);
            }

            if (pointC != null)
            {
                Vector3 outTangent = BezierPath.GetOutTangent(pointA, pointB, pointC);
                pointB.outTangent = TangentHandle(pointB.position, outTangent);
            }
        }
Beispiel #5
0
        /// <summary>
        ///     Returns the positions on the curve between the two points at the given deltas.
        ///
        ///     This method is faster than calling Interpolate multiple times for the same patch.
        /// </summary>
        /// <returns>The interpolated positions.</returns>
        /// <param name="output">Output.</param>
        /// <param name="pointA">Point a.</param>
        /// <param name="pointB">Point b.</param>
        /// <param name="pointC">Point c.</param>
        /// <param name="pointD">Point d.</param>
        /// <param name="deltas">Deltas.</param>
        public static void Interpolate(ref Vector3[] output, IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC,
                                       IBezierPoint pointD, float[] deltas)
        {
            Array.Resize(ref output, deltas.Length);

            Vector3 outTangent = GetOutTangent(pointA, pointB, pointC);
            Vector3 inTangent  = GetInTangent(pointB, pointC, pointD);

            for (int index = 0; index < deltas.Length; index++)
            {
                float delta = deltas[index];

                float x = ComputeBezier(pointB.position.x, outTangent.x, inTangent.x, pointC.position.x, delta);
                float y = ComputeBezier(pointB.position.y, outTangent.y, inTangent.y, pointC.position.y, delta);
                float z = ComputeBezier(pointB.position.z, outTangent.z, inTangent.z, pointC.position.z, delta);

                output[index] = new Vector3(x, y, z);
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Draws the bezier segment between pointB and pointC.
        /// </summary>
        /// <param name="pointA">Point a.</param>
        /// <param name="pointB">Point b.</param>
        /// <param name="pointC">Point c.</param>
        /// <param name="pointD">Point d.</param>
        public static void BezierSegmentHandle(IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC,
                                               IBezierPoint pointD)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            BezierPath.GetSegmentPoints(ref s_BezierPoints, pointA, pointB, pointC, pointD);

            HandleUtils.BeginGL(GL.LINES, HandleUtils.handleWireMaterial);

            for (int index = 0; index < s_BezierPoints.Length - 1; index++)
            {
                GL.Vertex(s_BezierPoints[index]);
                GL.Vertex(s_BezierPoints[index + 1]);
            }

            HandleUtils.EndGL();
        }
Beispiel #7
0
        /// <summary>
        ///     Draws the handles.
        /// </summary>
        public static void DrawHandles(SerializedProperty prop)
        {
            FindProperties(prop);

            for (int index = 0; index < s_PointsProp.arraySize; index++)
            {
                // Get all of the points to draw the patch
                IBezierPoint pointA = GetPoint(ref s_PointA, index - 1);
                IBezierPoint pointB = GetPoint(ref s_PointB, index);
                IBezierPoint pointC = GetPoint(ref s_PointC, index + 1);
                IBezierPoint pointD = GetPoint(ref s_PointD, index + 2);

                BezierPointHandle(pointB);

                if (pointC != null)
                {
                    BezierSegmentHandle(pointA, pointB, pointC, pointD);
                }

                switch (pointB.tangentMode)
                {
                case TangentMode.Corner:
                    BezierPointTangentsHandle(pointA, pointB, pointC);
                    break;

                case TangentMode.Smooth:
                    BezierPointTangentsHandle(pointA, pointB, pointC);
                    break;

                case TangentMode.Auto:
                    break;

                case TangentMode.Symmetric:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
Beispiel #8
0
        /// <summary>
        ///     Gets the symmetric tangents.
        /// </summary>
        /// <param name="inTangent">In tangent.</param>
        /// <param name="outTangent">Out tangent.</param>
        /// <param name="previousPoint">Previous point.</param>
        /// <param name="point">Point.</param>
        /// <param name="nextPoint">Next point.</param>
        private static void GetSymmetricTangents(out Vector3 inTangent, out Vector3 outTangent, IBezierPoint previousPoint,
                                                 IBezierPoint point, IBezierPoint nextPoint)
        {
            Vector3 previousToNext;
            Vector3 thisToPrevious = Vector3.zero;
            Vector3 thisToNext     = Vector3.zero;

            if (previousPoint != null)
            {
                thisToPrevious = previousPoint.position - point.position;
            }

            if (nextPoint != null)
            {
                thisToNext = nextPoint.position - point.position;
            }

            if (previousPoint == null)
            {
                previousToNext = thisToNext;
            }
            else if (nextPoint == null)
            {
                previousToNext = thisToPrevious;
            }
            else
            {
                previousToNext = nextPoint.position - previousPoint.position;
            }

            float inTangentMagnitude  = thisToPrevious.magnitude / 3.0f;
            float outTangentMagnitude = thisToNext.magnitude / 3.0f;
            float averageMagnitude    = (inTangentMagnitude + outTangentMagnitude) / 2.0f;

            inTangent  = -1.0f * averageMagnitude * previousToNext.normalized;
            outTangent = averageMagnitude * previousToNext.normalized;
        }
Beispiel #9
0
		/// <summary>
		/// 	Gets the out tangent.
		/// </summary>
		/// <returns>The out tangent.</returns>
		/// <param name="previousPoint">Previous point.</param>
		/// <param name="point">Point.</param>
		/// <param name="nextPoint">Next point.</param>
		public static Vector3 GetOutTangent(IBezierPoint previousPoint, IBezierPoint point, IBezierPoint nextPoint)
		{
			Vector3 inTangent;
			Vector3 outTangent;

			GetTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);

			return outTangent;
		}
		/// <summary>
		/// 	Draws the handle for a bezier points tangents.
		/// </summary>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="pointC">Point c.</param>
		public static void BezierPointTangentsHandle(IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC)
		{
			if (pointA != null)
			{
				Vector3 inTangent = BezierPath.GetInTangent(pointA, pointB, pointC);
				pointB.inTangent = TangentHandle(pointB.position, inTangent);
			}

			if (pointC != null)
			{
				Vector3 outTangent = BezierPath.GetOutTangent(pointA, pointB, pointC);
				pointB.outTangent = TangentHandle(pointB.position, outTangent);
			}
		}
Beispiel #11
0
		/// <summary>
		/// 	Returns the positions on the curve between the two points at the given deltas.
		/// 	
		/// 	This method is faster than calling Interpolate multiple times for the same patch.
		/// </summary>
		/// <returns>The interpolated positions.</returns>
		/// <param name="output">Output.</param>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="pointC">Point c.</param>
		/// <param name="pointD">Point d.</param>
		/// <param name="deltas">Deltas.</param>
		public static void Interpolate(ref Vector3[] output, IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC,
									   IBezierPoint pointD, float[] deltas)
		{
			Array.Resize(ref output, deltas.Length);

			Vector3 outTangent = GetOutTangent(pointA, pointB, pointC);
			Vector3 inTangent = GetInTangent(pointB, pointC, pointD);

			for (int index = 0; index < deltas.Length; index++)
			{
				float delta = deltas[index];

				float x = ComputeBezier(pointB.position.x, outTangent.x, inTangent.x, pointC.position.x, delta);
				float y = ComputeBezier(pointB.position.y, outTangent.y, inTangent.y, pointC.position.y, delta);
				float z = ComputeBezier(pointB.position.z, outTangent.z, inTangent.z, pointC.position.z, delta);

				output[index] = new Vector3(x, y, z);
			}
		}
Beispiel #12
0
        /// <summary>
        ///     Draws the handle for a bezier point.
        /// </summary>
        /// <param name="point">Point.</param>
        public static void BezierPointHandle(IBezierPoint point)
        {
            float pointSize = HandleUtils.GetDotSize(point.position);

            point.position = Handles.FreeMoveHandle(point.position, Quaternion.identity, pointSize, Vector3.zero, Handles.DotCap);
        }
Beispiel #13
0
		/// <summary>
		/// 	Using the curve between pointA and pointB we take a discrete number of line segments
		/// 	and return all of the points that make those lines.
		/// </summary>
		/// <returns>The segment points.</returns>
		/// <param name="output">Output.</param>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="pointC">Point c.</param>
		/// <param name="pointD">Point d.</param>
		public static void GetSegmentPoints(ref Vector3[] output, IBezierPoint pointA, IBezierPoint pointB,
											IBezierPoint pointC, IBezierPoint pointD)
		{
			Array.Resize(ref s_SegmentPointDeltas, LENGTH_LINE_SEGMENTS + 1);

			for (int index = 0; index < LENGTH_LINE_SEGMENTS + 1; index++)
				s_SegmentPointDeltas[index] = DELTA_LINE_SEGMENTS * index;

			Interpolate(ref output, pointA, pointB, pointC, pointD, s_SegmentPointDeltas);
		}
Beispiel #14
0
		/// <summary>
		/// 	Gets the auto tangents.
		/// </summary>
		/// <param name="inTangent">In tangent.</param>
		/// <param name="outTangent">Out tangent.</param>
		/// <param name="previousPoint">Previous point.</param>
		/// <param name="point">Point.</param>
		/// <param name="nextPoint">Next point.</param>
		private static void GetAutoTangents(out Vector3 inTangent, out Vector3 outTangent, IBezierPoint previousPoint,
											IBezierPoint point, IBezierPoint nextPoint)
		{
			Vector3 previousToNext;
			Vector3 thisToPrevious = Vector3.zero;
			Vector3 thisToNext = Vector3.zero;

			if (previousPoint != null)
				thisToPrevious = previousPoint.position - point.position;

			if (nextPoint != null)
				thisToNext = nextPoint.position - point.position;

			if (previousPoint == null)
				previousToNext = thisToNext;
			else if (nextPoint == null)
				previousToNext = thisToPrevious;
			else
				previousToNext = nextPoint.position - previousPoint.position;

			float inTangentMagnitude = thisToPrevious.magnitude / 3.0f;
			float outTangentMagnitude = thisToNext.magnitude / 3.0f;

			inTangent = -1.0f * inTangentMagnitude * previousToNext.normalized;
			outTangent = outTangentMagnitude * previousToNext.normalized;
		}
Beispiel #15
0
		/// <summary>
		/// 	Gets the tangents.
		/// </summary>
		/// <param name="inTangent">In tangent.</param>
		/// <param name="outTangent">Out tangent.</param>
		/// <param name="previousPoint">Previous point.</param>
		/// <param name="point">Point.</param>
		/// <param name="nextPoint">Next point.</param>
		public static void GetTangents(out Vector3 inTangent, out Vector3 outTangent, IBezierPoint previousPoint,
									   IBezierPoint point, IBezierPoint nextPoint)
		{
			switch (point.tangentMode)
			{
				case TangentMode.Smooth:
					inTangent = point.inTangent;
					outTangent = point.inTangent * -1.0f;
					break;

				case TangentMode.Corner:
					inTangent = point.inTangent;
					outTangent = point.outTangent;
					break;

				case TangentMode.Symmetric:
					GetSymmetricTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);
					break;

				case TangentMode.Auto:
					GetAutoTangents(out inTangent, out outTangent, previousPoint, point, nextPoint);
					break;

				default:
					throw new ArgumentOutOfRangeException();
			}
		}
		/// <summary>
		/// 	Draws the bezier segment between pointB and pointC.
		/// </summary>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="pointC">Point c.</param>
		/// <param name="pointD">Point d.</param>
		public static void BezierSegmentHandle(IBezierPoint pointA, IBezierPoint pointB, IBezierPoint pointC,
											   IBezierPoint pointD)
		{
			if (Event.current.type != EventType.Repaint)
				return;

			BezierPath.GetSegmentPoints(ref s_BezierPoints, pointA, pointB, pointC, pointD);

			HandleUtils.BeginGL(GL.LINES, HandleUtils.handleWireMaterial);

			for (int index = 0; index < s_BezierPoints.Length - 1; index++)
			{
				GL.Vertex(s_BezierPoints[index]);
				GL.Vertex(s_BezierPoints[index + 1]);
			}

			HandleUtils.EndGL();
		}
		/// <summary>
		/// 	Draws the handle for a bezier point.
		/// </summary>
		/// <param name="point">Point.</param>
		public static void BezierPointHandle(IBezierPoint point)
		{
			float pointSize = HandleUtils.GetDotSize(point.position);
			point.position = Handles.FreeMoveHandle(point.position, Quaternion.identity, pointSize, Vector3.zero, Handles.DotCap);
		}