/// <summary> /// Gets position of a car based on its lane and distance from the start in that lane. /// </summary> /// <param name="distance"></param> /// <param name="lane"></param> /// <param name="x"></param> /// <param name="z"></param> /// <param name="rotation">y rotation of the car, in radians.</param> public void GetPosition(float distance, float lane, out float x, out float z, out float rotation) { // keep distance in [0, length) distance -= Mathf.Floor(distance / length(lane)) * length(lane); Vector3 pos = Vector3.zero; Quaternion rot = Quaternion.identity; float pieceStartDistance = 0; float pieceEndDistance = 0; x = 0; z = 0; rotation = 0; for (int i = 0; i < 8; i++) { HighwayPiece piece = pieces[i]; pieceStartDistance = pieceEndDistance; pieceEndDistance += piece.length(lane); if (distance >= pieceEndDistance) { continue; } // inside piece i // position and rotation local to the piece float localX, localZ; if (i % 2 == 0) { // straight piece GetStraightPiecePosition(distance - pieceStartDistance, lane, out localX, out localZ, out rotation); } else { // curved piece GetCurvePiecePosition(distance - pieceStartDistance, lane, out localX, out localZ, out rotation); } // transform RotateAroundOrigin(localX, localZ, piece.startRotation, out x, out z); x += piece.startX; z += piece.startZ; rotation += piece.startRotation; break; } }
/// <summary> /// Gets distance in another lane that appears to be the same distance in the given lane. /// </summary> public float GetEquivalentDistance(float distance, float lane, float otherLane) { // keep distance in [0, length) distance = WrapDistance(distance, lane); float pieceStartDistance = 0; float pieceEndDistance = 0; float pieceStartDistanceOtherLane = 0; float pieceEndDistanceOtherLane = 0; for (int i = 0; i < 8; i++) { HighwayPiece piece = pieces[i]; pieceStartDistance = pieceEndDistance; pieceStartDistanceOtherLane = pieceEndDistanceOtherLane; pieceEndDistance += piece.length(lane); pieceEndDistanceOtherLane += piece.length(otherLane); if (distance >= pieceEndDistance) { continue; } // inside piece i if (i % 2 == 0) { // straight piece return(pieceStartDistanceOtherLane + distance - pieceStartDistance); } else { // curved piece float radius = curvePieceRadius(lane); float radiusOtherLane = curvePieceRadius(otherLane); return(pieceStartDistanceOtherLane + (distance - pieceStartDistance) * radiusOtherLane / radius); } } return(0); }