//This is our "path decision function". It is called by the bSpline.Advance method once a junction has been passed and we need to decide //which path we want to use next. //The parameter currentParameter can be used as reference that we will base our decision on. //The parameter possiblePaths is a list of BranchingSplinePaths that can be taken. Please note that this list might contain some splines //twice. This happens when we hit a junction where a spline can be followed in two directions (e.g. a crossroads). //You can query the path's direction using the corresponding field: BranchingSplinePath.direction. BranchingSplinePath JunctionController( BranchingSplineParameter currentParameter, System.Collections.Generic.List<BranchingSplinePath> possiblePaths ) { //We just take a random path in this example... int randomIndex = (int)(Random.value*possiblePaths.Count); return possiblePaths[randomIndex]; }
//This is our "path decision function". It is called by the bSpline.Advance method once a junction has been passed and we need to decide //which path we want to use next. //The parameter currentParameter can be used as reference that we will base our decision on. //The parameter possiblePaths is a list of BranchingSplinePaths that can be taken. Please note that this list might contain some splines //twice. This happens when we hit a junction where a spline can be followed in two directions (e.g. a crossroads). //You can query the path's direction using the corresponding field: BranchingSplinePath.direction. BranchingSplinePath JunctionController(BranchingSplineParameter currentParameter, System.Collections.Generic.List <BranchingSplinePath> possiblePaths) { //We just take a random path in this example... int randomIndex = (int)(Random.value * possiblePaths.Count); return(possiblePaths[randomIndex]); }
/// <summary> /// This function returns a normal to the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A normal to the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public Vector3 GetNormal(BranchingSplineParameter bParam) { if (!SplinesAvailable) { return(Vector3.zero); } CheckParameter(bParam); return(bParam.spline.GetNormalToSpline(bParam.parameter)); }
/// <summary> /// This function returns a custom value on the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A custom value on the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public float GetCustomValue(BranchingSplineParameter bParam) { if (!SplinesAvailable) { return(0); } CheckParameter(bParam); return(bParam.spline.GetCustomValueOnSpline(bParam.parameter)); }
/// <summary> /// This function returns a rotation on the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A rotation on the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public Quaternion GetOrientation(BranchingSplineParameter bParam) { if (!SplinesAvailable) { return(Quaternion.identity); } CheckParameter(bParam); return(bParam.spline.GetOrientationOnSpline(bParam.parameter)); }
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 void CheckParameter(BranchingSplineParameter bParam) { if (!SplinesAvailable) { return; } else if (bParam.spline == null) { bParam.spline = splines[0]; } else if (!splines.Contains(bParam.spline)) { bParam.spline = splines[0]; } bParam.parameter = Mathf.Clamp01(bParam.parameter); }
/// <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 void CheckParameter( BranchingSplineParameter bParam ) { if( !SplinesAvailable ) return; else if( bParam.spline == null ) bParam.spline = splines[0]; else if( !splines.Contains( bParam.spline ) ) bParam.spline = splines[0]; bParam.parameter = Mathf.Clamp01( bParam.parameter ); }
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 ); }
/// <summary> /// This function returns a normal to the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A normal to the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public Vector3 GetNormal( BranchingSplineParameter bParam ) { if( !SplinesAvailable ) return Vector3.zero; CheckParameter( bParam ); return bParam.spline.GetNormalToSpline( bParam.parameter ); }
/// <summary> /// This function returns a custom value on the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A custom value on the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public float GetCustomValue( BranchingSplineParameter bParam ) { if( !SplinesAvailable ) return 0; CheckParameter( bParam ); return bParam.spline.GetCustomValueOnSpline( bParam.parameter ); }
/// <summary> /// This function returns a rotation on the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A rotation on the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public Quaternion GetOrientation( BranchingSplineParameter bParam ) { if( !SplinesAvailable ) return Quaternion.identity; CheckParameter( bParam ); return bParam.spline.GetOrientationOnSpline( bParam.parameter ); }
/// <summary> /// This function returns a point on the branched path for a BranchingSplineParameter. /// </summary> /// <returns> /// A point on the spline. /// </returns> /// <param name='bParam'> /// A BranchingSplineParameter. /// </param> public Vector3 GetPosition( BranchingSplineParameter bParam ) { if( !SplinesAvailable ) return Vector3.zero; CheckParameter( bParam ); return bParam.spline.GetPositionOnSpline( bParam.parameter ); }
/// <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); }