/// <summary> /// Returns the angle from current position to another Control Point /// </summary> /// <param name="controlPoint">the reference Control point</param> /// <returns>an angle in degrees</returns> public float AngleTo(CurvySplineSegment controlPoint) { float a = 0; if (Spline && controlPoint) { Vector3 t0 = Spline.GetTangentFast(TF); Vector3 t1 = controlPoint.Spline.GetTangentFast(controlPoint.LocalFToTF(0)); bool flip = !controlPoint.Spline.Closed && ((controlPoint.IsFirstVisibleControlPoint && Direction == -1) || (controlPoint.IsLastVisibleControlPoint && Direction == 1)); if (flip) { t1 *= -1; } a = Vector3.Angle(t0, t1); } return(a); }
/// <summary> /// Sets the movement to follow a new spline and alter movement direction to best fit /// </summary> /// <param name="controlPoint">the Control Point on the new spline to start with</param> /// <param name="direction">the direction to use</param> public void Follow(CurvySplineSegment controlPoint, ConnectionHeadingEnum direction = ConnectionHeadingEnum.Auto) { // Change Delta (TF) to have the same distance on the new spline if (!WorldUnits) { Delta *= Spline.Length / controlPoint.Spline.Length; } // Change Spline float tf = controlPoint.LocalFToTF(0); SetPosition(controlPoint, 0); if (tf == 0 && Direction == -1 && Spline.Closed) { tf = 1; } if (tf == 0) { Direction = 1; } else if (tf == 1) { Direction = -1; } else { switch (direction) { case ConnectionHeadingEnum.Minus: Direction = -1; break; case ConnectionHeadingEnum.Plus: Direction = 1; break; } } }
/// <summary> /// Gets a TF value from a segment and a local F /// </summary> /// <param name="segment">a segment</param> /// <param name="localF">F of this segment in the range 0..1</param> /// <returns>a TF value in the range 0..1</returns> public override float SegmentToTF(CurvySplineSegment segment, float localF) { float splineTF = segment.LocalFToTF(localF); return(SplineToTF(segment.Spline, splineTF)); }
void DoInterpolate() { if (!mSegment.Spline.IsInitialized) { return; } bool calc = !Input.IsNone; if (calc) { System.Type metaType = System.Type.GetType(MetaDataType.Value); float inputF = (UseWorldUnits.Value) ? mSegment.DistanceToLocalF(Input.Value) : Input.Value; if (StorePosition.UseVariable) { StorePosition.Value = (UseCache.Value) ? mSegment.InterpolateFast(inputF) : mSegment.Interpolate(inputF); } if (StoreTangent.UseVariable) { StoreTangent.Value = mSegment.GetTangent(inputF); } if (StoreUpVector.UseVariable) { StoreUpVector.Value = mSegment.GetOrientationUpFast(inputF); } if (StoreRotation.UseVariable) { StoreRotation.Value = (StoreUpVector.IsNone) ? mSegment.GetOrientationFast(inputF) : Quaternion.LookRotation(mSegment.GetTangent(inputF), StoreUpVector.Value); } if (StoreScale.UseVariable) { StoreScale.Value = mSegment.InterpolateScale(inputF); } if (StoreTF.UseVariable) { StoreTF.Value = mSegment.LocalFToTF(inputF); } if (StoreSegmentDistance.UseVariable) { StoreSegmentDistance.Value = mSegment.LocalFToDistance(inputF); } if (StoreDistance.UseVariable) { StoreDistance.Value = (StoreSegmentDistance.UseVariable) ? StoreSegmentDistance.Value + mSegment.Distance : mSegment.LocalFToDistance(inputF) + mSegment.Distance; } if (StoreSegmentF.UseVariable) { StoreSegmentF.Value = inputF; } if (metaType != null) { if (StoreMetadata.UseVariable) { StoreMetadata.Value = mSegment.GetMetaData(metaType); } if (StoreInterpolatedMetadata.useVariable) { StoreInterpolatedMetadata.SetValue(mSegment.InterpolateMetadata(metaType, inputF)); } } } // General if (StoreLength.UseVariable) { StoreLength.Value = mSegment.Length; } if (StoreSegmentIndex.UseVariable) { StoreSegmentIndex.Value = mSegment.SegmentIndex; } if (StoreControlPointIndex.UseVariable) { StoreControlPointIndex.Value = mSegment.ControlPointIndex; } }
void DoInterpolate() { if (!mSegment.Spline.IsInitialized) { return; } bool calc = !Input.IsNone; if (calc) { System.Type metaType = System.Type.GetType(MetaDataType.Value); float inputF = (UseWorldUnits.Value) ? mSegment.DistanceToLocalF(Input.Value) : Input.Value; if (StorePosition.IsNone == false) { StorePosition.Value = (UseCache.Value) ? mSegment.InterpolateFast(inputF) : mSegment.Interpolate(inputF); } if (StoreTangent.IsNone == false) { StoreTangent.Value = mSegment.GetTangent(inputF); } if (StoreUpVector.IsNone == false) { StoreUpVector.Value = mSegment.GetOrientationUpFast(inputF); } if (StoreRotation.IsNone == false) { StoreRotation.Value = (StoreUpVector.IsNone) ? mSegment.GetOrientationFast(inputF) : Quaternion.LookRotation(mSegment.GetTangent(inputF), StoreUpVector.Value); } if (StoreScale.IsNone == false) { CurvySplineSegment nextControlPoint = mSegment.Spline.GetNextControlPoint(mSegment); StoreScale.Value = nextControlPoint ? Vector3.Lerp(mSegment.transform.lossyScale, nextControlPoint.transform.lossyScale, inputF) : mSegment.transform.lossyScale; } if (StoreTF.IsNone == false) { StoreTF.Value = mSegment.LocalFToTF(inputF); } if (StoreSegmentDistance.IsNone == false) { StoreSegmentDistance.Value = mSegment.LocalFToDistance(inputF); } if (StoreDistance.IsNone == false) { StoreDistance.Value = (StoreSegmentDistance.IsNone == false) ? StoreSegmentDistance.Value + mSegment.Distance : mSegment.LocalFToDistance(inputF) + mSegment.Distance; } if (StoreSegmentF.IsNone == false) { StoreSegmentF.Value = inputF; } if (metaType != null) { if (metaType.IsSubclassOf(typeof(CurvyMetadataBase)) == false) { //this if statement's branch does not exclude classes inheriting from CurvyMetadataBase but not from CurvyInterpolatableMetadataBase, but that's ok, those classes are handled below Debug.LogError("Meta data type " + metaType.FullName + " should be a subclass of CurvyInterpolatableMetadataBase<T>"); } else { if (StoreMetadata.IsNone == false) { MethodInfo genericMethodInfo = mSegment.GetType().GetMethod("GetMetadata").MakeGenericMethod(metaType); StoreMetadata.Value = (Object)genericMethodInfo.Invoke(mSegment, new System.Object[] { false }); } if (StoreInterpolatedMetadata.IsNone == false) { Type argumentType = CurvyGetValue.GetInterpolatableMetadataGenericType(metaType); if (argumentType == null) { Debug.LogError("Meta data type " + metaType.FullName + " should be a subclass of CurvyInterpolatableMetadataBase<T>"); } else { MethodInfo genericMethodInfo = mSegment.GetType().GetMethod("GetInterpolatedMetadata").MakeGenericMethod(metaType, argumentType); StoreInterpolatedMetadata.SetValue(genericMethodInfo.Invoke(mSegment, new System.Object[] { inputF })); } } } } } // General if (StoreLength.IsNone == false) { StoreLength.Value = mSegment.Length; } if (StoreSegmentIndex.IsNone == false) { StoreSegmentIndex.Value = mSegment.Spline.GetSegmentIndex(mSegment); } if (StoreControlPointIndex.IsNone == false) { StoreControlPointIndex.Value = mSegment.Spline.GetControlPointIndex(mSegment); } }
/// <summary> /// Gets a TF value from a segment and a local F /// </summary> /// <param name="segment">a segment</param> /// <param name="localF">F of this segment in the range 0..1</param> /// <returns>a TF value in the range 0..1</returns> public override float SegmentToTF(CurvySplineSegment segment, float localF) { float splineTF = segment.LocalFToTF(localF); return SplineToTF(segment.Spline, splineTF); }