/// <summary> /// This function adds an offset to a BranchingSplineParameter while automatically switching splines when a juction is passed. /// </summary> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> /// <param name='distanceOffset'> /// An offset that shall be added to the BranchingSplineParameter (in game units). /// </param> /// <param name='bController'> /// A BranchingController-delegate that decides which path to follow if a junction is passed. /// </param> /// <returns> /// True if the spline used as reference path has been changed; False if not. /// </returns> public bool Advance( BranchingSplineParameter bParam, float distanceOffset, BranchingController bController ) { bool splineChange = false; if( !SplinesAvailable ) return false; if( ++recoursionCounter > 12 ) { recoursionCounter = 0; return false; } CheckParameter( bParam ); Spline currentSpline = bParam.spline; SplineNode currentNode = IsOnSplineNode( bParam.parameter, currentSpline ); //Parameter on node? if( currentNode != null ) { BranchingSplinePath nextPath = ChoseSpline( currentNode, bParam, bController, distanceOffset > 0 ); bParam.spline = nextPath.spline; bParam.direction = nextPath.direction; bParam.parameter = currentNode.Parameters[bParam.spline].PosInSpline; SplineNode[] adjacentNodes = GetAdjacentSegmentNodes( nextPath.spline, currentNode ); SplineNode nextNode = adjacentNodes[ForwardOnSpline( nextPath.direction, distanceOffset ) ? 1 : 0]; if( nextNode != null ) { bParam.parameter += (nextNode.Parameters[bParam.spline].PosInSpline - currentNode.Parameters[bParam.spline].PosInSpline) * 0.001f; Advance( bParam, distanceOffset, bController ); splineChange = false; } else { splineChange = false; } } else { SplineSegment currentSegment = currentSpline.GetSplineSegment( bParam.parameter ); float signedSplineLength = currentSpline.Length * (bParam.Forward ? 1 : -1); float normalizedOffsetDir = distanceOffset / signedSplineLength; float newParameter = bParam.parameter + normalizedOffsetDir; float clampedParameter = currentSegment.ClampParameterToSegment( newParameter ); float offsetDifference = newParameter - clampedParameter; bParam.parameter = clampedParameter; if( Mathf.Approximately( offsetDifference, 0 ) ) splineChange = false; else splineChange = Advance( bParam, offsetDifference * signedSplineLength, bController ); } recoursionCounter = 0; return splineChange; }
/// <summary> /// This function adds an offset to a BranchingSplineParameter while automatically switching splines when a juction is passed. /// </summary> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> /// <param name='distanceOffset'> /// An offset that shall be added to the BranchingSplineParameter (in game units). /// </param> /// <param name='bController'> /// A BranchingController-delegate that decides which path to follow if a junction is passed. /// </param> /// <returns> /// True if the spline used as reference path has been changed; False if not. /// </returns> public bool Advance(BranchingSplineParameter bParam, float distanceOffset, BranchingController bController) { bool splineChange = false; if (!SplinesAvailable) { return(false); } if (++recoursionCounter > 12) { recoursionCounter = 0; return(false); } CheckParameter(bParam); Spline currentSpline = bParam.spline; SplineNode currentNode = IsOnSplineNode(bParam.parameter, currentSpline); //Parameter on node? if (currentNode != null) { BranchingSplinePath nextPath = ChoseSpline(currentNode, bParam, bController, distanceOffset > 0); bParam.spline = nextPath.spline; bParam.direction = nextPath.direction; bParam.parameter = currentNode.Parameters[bParam.spline].PosInSpline; SplineNode[] adjacentNodes = GetAdjacentSegmentNodes(nextPath.spline, currentNode); SplineNode nextNode = adjacentNodes[ForwardOnSpline(nextPath.direction, distanceOffset) ? 1 : 0]; if (nextNode != null) { bParam.parameter += (nextNode.Parameters[bParam.spline].PosInSpline - currentNode.Parameters[bParam.spline].PosInSpline) * 0.001f; Advance(bParam, distanceOffset, bController); splineChange = false; } else { splineChange = false; } } else { SplineSegment currentSegment = currentSpline.GetSplineSegment(bParam.parameter); float signedSplineLength = currentSpline.Length * (bParam.Forward ? 1 : -1); float normalizedOffsetDir = distanceOffset / signedSplineLength; float newParameter = bParam.parameter + normalizedOffsetDir; float clampedParameter = currentSegment.ClampParameterToSegment(newParameter); float offsetDifference = newParameter - clampedParameter; bParam.parameter = clampedParameter; if (Mathf.Approximately(offsetDifference, 0)) { splineChange = false; } else { splineChange = Advance(bParam, offsetDifference * signedSplineLength, bController); } } recoursionCounter = 0; return(splineChange); }
private BranchingSplinePath ChoseSpline( SplineNode switchNode, BranchingSplineParameter currentPath, BranchingController bController, bool positiveValue ) { IList<Spline> possibleSplines = GetSplinesForNode( switchNode ); List<BranchingSplinePath> possiblePaths = new List<BranchingSplinePath>( ); //Eliminate unnecessary decisions if( possibleSplines.Count == 1 && possibleSplines[0] == currentPath.spline ) return new BranchingSplinePath( currentPath.spline, currentPath.direction ); if( IsMiddleNode( currentPath.spline, switchNode ) ) possiblePaths.Add( new BranchingSplinePath( currentPath.spline, currentPath.direction ) ); foreach( Spline spline in possibleSplines ) { if( spline == currentPath.spline ) continue; if( IsMiddleNode( spline, switchNode ) ) { possiblePaths.Add( new BranchingSplinePath( spline, BranchingSplinePath.Direction.Forwards ) ); possiblePaths.Add( new BranchingSplinePath( spline, BranchingSplinePath.Direction.Backwards ) ); } else { SplineNode[] splineNodes = spline.SplineNodes; int nodeIndex = System.Array.IndexOf( splineNodes, switchNode ); if( nodeIndex == 0 ) possiblePaths.Add( new BranchingSplinePath( spline, positiveValue?BranchingSplinePath.Direction.Forwards:BranchingSplinePath.Direction.Backwards ) ); if( nodeIndex == splineNodes.Length-1 ) possiblePaths.Add( new BranchingSplinePath( spline, !positiveValue?BranchingSplinePath.Direction.Forwards:BranchingSplinePath.Direction.Backwards ) ); } } return bController( currentPath, possiblePaths ); }
private BranchingSplinePath ChoseSpline(SplineNode switchNode, BranchingSplineParameter currentPath, BranchingController bController, bool positiveValue) { IList <Spline> possibleSplines = GetSplinesForNode(switchNode); List <BranchingSplinePath> possiblePaths = new List <BranchingSplinePath>( ); //Eliminate unnecessary decisions if (possibleSplines.Count == 1 && possibleSplines[0] == currentPath.spline) { return(new BranchingSplinePath(currentPath.spline, currentPath.direction)); } if (IsMiddleNode(currentPath.spline, switchNode)) { possiblePaths.Add(new BranchingSplinePath(currentPath.spline, currentPath.direction)); } foreach (Spline spline in possibleSplines) { if (spline == currentPath.spline) { continue; } if (IsMiddleNode(spline, switchNode)) { possiblePaths.Add(new BranchingSplinePath(spline, BranchingSplinePath.Direction.Forwards)); possiblePaths.Add(new BranchingSplinePath(spline, BranchingSplinePath.Direction.Backwards)); } else { SplineNode[] splineNodes = spline.SplineNodes; int nodeIndex = System.Array.IndexOf(splineNodes, switchNode); if (nodeIndex == 0) { possiblePaths.Add(new BranchingSplinePath(spline, positiveValue?BranchingSplinePath.Direction.Forwards:BranchingSplinePath.Direction.Backwards)); } if (nodeIndex == splineNodes.Length - 1) { possiblePaths.Add(new BranchingSplinePath(spline, !positiveValue?BranchingSplinePath.Direction.Forwards:BranchingSplinePath.Direction.Backwards)); } } } return(bController(currentPath, possiblePaths)); }