예제 #1
0
		/// <summary>
		/// 	Gets the previous point in the path. If this is the first point and
		/// 	and the path is closed, this method will return the last point.
		/// </summary>
		/// <returns>The previous point.</returns>
		/// <param name="point">Point.</param>
		public BezierPointAttribute GetPreviousPoint(BezierPointAttribute point)
		{
			int index = m_Points.IndexOf(point);
			return GetPreviousPoint(index);
		}
예제 #2
0
		/// <summary>
		/// 	Creates a bezier circle path.
		/// </summary>
		/// <param name="radius">Radius.</param>
		public static BezierPath Circle(float radius)
		{
			BezierPath path = CreateInstance<BezierPath>(null);
			path.closed = true;

			float controlDistance = radius * 4.0f * (s_Root2 - 1.0f) / 3.0f;

			Quaternion offset = Quaternion.identity;
			Quaternion increment = Quaternion.Euler(0.0f, 0.0f, 90.0f);

			BezierPointAttribute[] points = new BezierPointAttribute[4];

			for (int index = 0; index < 4; index++)
			{
				Vector3 position = Vector3.up * radius;
				Vector3 inTangent = Vector3.right * controlDistance;
				Vector3 outTangent = Vector3.left * controlDistance;

				BezierPointAttribute point = BezierPointAttribute.CreateInstance<BezierPointAttribute>();

				point.tangentMode = TangentMode.Smooth;
				point.position = offset * position;
				point.inTangent = offset * inTangent;
				point.outTangent = offset * outTangent;

				points[index] = point;

				offset *= increment;
			}

			path.points = points;

			return path;
		}
예제 #3
0
		/// <summary>
		/// 	Provides the patch and patch delta for the given path delta.
		/// </summary>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="patchDelta">Patch delta.</param>
		/// <param name="delta">Delta.</param>
		private void PatchForDelta(out BezierPointAttribute pointA, out BezierPointAttribute pointB, out float patchDelta,
								   float delta)
		{
			int patches = m_Points.Length - 1;
			if (m_Closed)
				patches++;

			if (patches < 1)
				throw new Exception("No patches in the path!");

			delta = Mathf.Repeat(delta, 1.0f);

			int patchIndex = HydraMathUtils.FloorToInt(delta * patches);

			pointA = m_Points[patchIndex];
			pointB = GetNextPoint(patchIndex);

			float singlePatchDelta = 1.0f / patches;

			patchDelta = delta - (patchIndex * singlePatchDelta);
			patchDelta *= patches;
		}
예제 #4
0
		/// <summary>
		/// 	Returns the normal at the given non-linear delta.
		/// </summary>
		/// <returns>The normal vector.</returns>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="delta">Delta.</param>
		public Vector3 Normal(BezierPointAttribute pointA, BezierPointAttribute pointB, float delta)
		{
			Vector3 position = Interpolate(pointA, pointB, delta);
			Vector3 tangent = Tangent(pointA, pointB, delta).normalized;

			// Cheat to get the next point along the curve
			float nextDelta = delta + NORMAL_INTERVAL;

			Vector3 position2 = Interpolate(pointA, pointB, nextDelta);
			Vector3 tangent2 = Tangent(pointA, pointB, nextDelta);
			tangent2 -= (position2 - position);
			tangent2 = tangent2.normalized;

			Vector3 c =
				new Vector3(tangent2.y * tangent.z - tangent2.z * tangent.y, tangent2.z * tangent.x - tangent2.x * tangent.z,
							tangent2.x * tangent.y - tangent2.y * tangent.x).normalized;

			Matrix4x4 r = Matrix4x4.identity;
			r.SetRow(0, new Vector4(c.x * c.x, c.x * c.y - c.z, c.x * c.z + c.y));
			r.SetRow(1, new Vector4(c.x * c.y + c.z, c.y * c.y, c.y * c.z - c.x));
			r.SetRow(2, new Vector4(c.x * c.z - c.y, c.y * c.z + c.x, c.z * c.z));

			return r.MultiplyVector(tangent);
		}
예제 #5
0
		/// <summary>
		/// 	Returns the tangent at the given non-linear delta.
		/// </summary>
		/// <returns>The tangent vector.</returns>
		/// <param name="pointA">Point a.</param>
		/// <param name="pointB">Point b.</param>
		/// <param name="delta">Delta.</param>
		public Vector3 Tangent(BezierPointAttribute pointA, BezierPointAttribute pointB, float delta)
		{
			BezierPointAttribute previousPoint = GetPreviousPoint(pointA);
			BezierPointAttribute nextPoint = GetNextPoint(pointB);

			Vector3 outTangent = GetOutTangent(previousPoint, pointA, pointB);
			Vector3 inTangent = GetInTangent(pointA, pointB, nextPoint);

			float x = ComputeBezierDerivative(pointA.position.x, outTangent.x, inTangent.x, pointB.position.x, delta);
			float y = ComputeBezierDerivative(pointA.position.y, outTangent.y, inTangent.y, pointB.position.y, delta);
			float z = ComputeBezierDerivative(pointA.position.z, outTangent.z, inTangent.z, pointB.position.z, delta);

			return new Vector3(x, y, z);
		}
예제 #6
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="deltas">Deltas.</param>
		public void Interpolate(ref Vector3[] output, BezierPointAttribute pointA, BezierPointAttribute pointB, float[] deltas)
		{
			BezierPointAttribute previousPoint = GetPreviousPoint(pointA);
			BezierPointAttribute nextPoint = GetNextPoint(pointB);

			Interpolate(ref output, previousPoint, pointA, pointB, nextPoint, deltas);
		}