You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.8 KiB
115 lines
3.8 KiB
using System.Collections.Generic; |
|
using System.Linq; |
|
using EasyRoads3Dv3; |
|
using UnityEngine; |
|
|
|
namespace ERVertexPath |
|
{ |
|
//Create for every ER road on scene - will approximate spline path to vertex path |
|
public class ERPathToVertexPathWrapper : MonoBehaviour |
|
{ |
|
public float angleThreshold = 2f; |
|
public float scanStep = 1f; |
|
public float maxDistance = 50f; |
|
|
|
public bool isShowPathGizmo; |
|
|
|
private ERRoad road; |
|
private float totalDistance; |
|
private Vector3[] positions; |
|
private Vector3[] directions; |
|
//Side normals as Up x Direction |
|
private Vector3[] normals; |
|
private Quaternion[] rotations; |
|
private float[] distances; |
|
|
|
public float TotalDistance => totalDistance; |
|
|
|
public Vector3[] Positions => positions; |
|
|
|
public Vector3[] Directions => directions; |
|
|
|
public Vector3[] Normals => normals; |
|
|
|
public Quaternion[] Rotations => rotations; |
|
|
|
public float[] Distances => distances; |
|
|
|
public float Width => road.GetWidth(); |
|
|
|
public void Init(ERModularRoad modularRoad) |
|
{ |
|
road = new ERRoadNetwork().GetRoadByGameObject(modularRoad.gameObject); |
|
totalDistance = road.GetDistance(); |
|
buildRoadVertexPath(); |
|
} |
|
|
|
private void buildRoadVertexPath() |
|
{ |
|
var vertexList = new List<Vector3>(); |
|
var directionsList = new List<Vector3>(); |
|
var normalsList = new List<Vector3>(); |
|
var rotationsList = new List<Quaternion>(); |
|
var distanceList = new List<float>(); |
|
|
|
var prevPointDistance = 0f; |
|
|
|
var currentRoadElement = 0; |
|
for (var t = 0f; t < road.GetDistance(); t += scanStep) |
|
{ |
|
var p = road.GetPosition(t, ref currentRoadElement); |
|
var d = road.GetLookatSmooth(t, currentRoadElement); |
|
var r = Quaternion.LookRotation(d); |
|
|
|
var isSignificantVertex = vertexList.Count == 0 |
|
|| t - prevPointDistance > maxDistance |
|
|| Vector3.Angle(d, directionsList.Last()) > angleThreshold; |
|
|
|
if (isSignificantVertex) |
|
{ |
|
vertexList.Add(p); |
|
directionsList.Add(d); |
|
normalsList.Add(Vector3.Cross(Vector3.up, d)); |
|
rotationsList.Add(r); |
|
distanceList.Add(t); |
|
prevPointDistance = t; |
|
} |
|
} |
|
|
|
positions = vertexList.ToArray(); |
|
directions = directionsList.ToArray(); |
|
normals = normalsList.ToArray(); |
|
rotations = rotationsList.ToArray(); |
|
distances = distanceList.ToArray(); |
|
} |
|
|
|
public void ClearPathData() |
|
{ |
|
positions = null; |
|
directions = null; |
|
normals = null; |
|
rotations = null; |
|
distances = null; |
|
} |
|
|
|
private void FixedUpdate() |
|
{ |
|
if (!isShowPathGizmo) |
|
{ |
|
return; |
|
} |
|
|
|
var verticalOffset = Vector3.up * 0.5f; |
|
for (var i = 0; i < positions.Length; i++) |
|
{ |
|
var start = positions[i]; |
|
var end = i == positions.Length - 1 ? positions[0] : positions[i + 1]; |
|
start += verticalOffset; |
|
end += verticalOffset; |
|
Debug.DrawLine(start, end, i % 2 == 0 ? Color.white : Color.magenta); |
|
Debug.DrawLine(start, start + verticalOffset, Color.yellow); |
|
Debug.DrawLine(start, start + normals[i], Color.red); |
|
} |
|
} |
|
} |
|
} |