RoadRunner/Assets/RoadArchitect/Scripts/RoadConstructorBufferMaker.cs
2024-11-19 11:48:21 +01:00

2405 lines
106 KiB
C#

using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace RoadArchitect
{
public class RoadConstructorBufferMaker
{
#region "Vars"
public Road road;
public List<Vector3> RoadVectors;
public List<Vector3> ShoulderR_Vectors;
public List<Vector3> ShoulderL_Vectors;
public int[] tris;
public int[] tris_ShoulderR;
public int[] tris_ShoulderL;
public Vector3[] normals;
public Vector3[] normals_ShoulderR;
public Vector3[] normals_ShoulderL;
public List<int> normals_ShoulderR_averageStartIndexes;
public List<int> normals_ShoulderL_averageStartIndexes;
/// <summary> Road UVs </summary>
public Vector2[] uv;
/// <summary> Pavement UVs </summary>
public Vector2[] uv2;
/// <summary> Shoulder right UVs </summary>
public Vector2[] uv_SR;
/// <summary> Shoulder left UVs </summary>
public Vector2[] uv_SL;
public Vector4[] tangents;
public Vector4[] tangents2;
public Vector4[] tangents_SR;
public Vector4[] tangents_SL;
public List<List<Vector3>> cut_RoadVectors;
public List<Vector3> cut_RoadVectorsHome;
public List<List<Vector3>> cut_ShoulderR_Vectors;
public List<List<Vector3>> cut_ShoulderL_Vectors;
public List<Vector3> cut_ShoulderR_VectorsHome;
public List<Vector3> cut_ShoulderL_VectorsHome;
public List<int[]> cut_tris;
public List<int[]> cut_tris_ShoulderR;
public List<int[]> cut_tris_ShoulderL;
public List<Vector3[]> cut_normals;
public List<Vector3[]> cut_normals_ShoulderR;
public List<Vector3[]> cut_normals_ShoulderL;
public List<Vector2[]> cut_uv;
public List<Vector2[]> cut_uv_SR;
public List<Vector2[]> cut_uv_SL;
public List<Vector4[]> cut_tangents;
public List<Vector4[]> cut_tangents_SR;
public List<Vector4[]> cut_tangents_SL;
public List<Vector2[]> cut_uv_world;
public List<Vector2[]> cut_uv_SR_world;
public List<Vector2[]> cut_uv_SL_world;
public List<Vector4[]> cut_tangents_world;
public List<Vector4[]> cut_tangents_SR_world;
public List<Vector4[]> cut_tangents_SL_world;
//Road connections:
public List<Vector3[]> RoadConnections_verts;
public List<int[]> RoadConnections_tris;
public List<Vector3[]> RoadConnections_normals;
public List<Vector2[]> RoadConnections_uv;
public List<Vector4[]> RoadConnections_tangents;
//Back lanes:
public List<Vector3[]> iBLane0s;
public List<Vector3[]> iBLane1s;
public List<bool> iBLane1s_IsMiddleLane;
public List<Vector3[]> iBLane2s;
public List<Vector3[]> iBLane3s;
//Front lanes:
public List<Vector3[]> iFLane0s;
public List<Vector3[]> iFLane1s;
public List<bool> iFLane1s_IsMiddleLane;
public List<Vector3[]> iFLane2s;
public List<Vector3[]> iFLane3s;
//Main plates:
public List<Vector3[]> iBMainPlates;
public List<Vector3[]> iFMainPlates;
//Marker plates:
public List<Vector3[]> iBMarkerPlates;
public List<Vector3[]> iFMarkerPlates;
//Back lanes:
public List<int[]> iBLane0s_tris;
public List<int[]> iBLane1s_tris;
public List<int[]> iBLane2s_tris;
public List<int[]> iBLane3s_tris;
//Front lanes:
public List<int[]> iFLane0s_tris;
public List<int[]> iFLane1s_tris;
public List<int[]> iFLane2s_tris;
public List<int[]> iFLane3s_tris;
//Main plates:
public List<int[]> iBMainPlates_tris;
public List<int[]> iFMainPlates_tris;
//Marker plates:
public List<int[]> iBMarkerPlates_tris;
public List<int[]> iFMarkerPlates_tris;
//Back lanes:
public List<Vector3[]> iBLane0s_normals;
public List<Vector3[]> iBLane1s_normals;
public List<Vector3[]> iBLane2s_normals;
public List<Vector3[]> iBLane3s_normals;
//Front lanes:
public List<Vector3[]> iFLane0s_normals;
public List<Vector3[]> iFLane1s_normals;
public List<Vector3[]> iFLane2s_normals;
public List<Vector3[]> iFLane3s_normals;
//Main plates:
public List<Vector3[]> iBMainPlates_normals;
public List<Vector3[]> iFMainPlates_normals;
//Marker plates:
public List<Vector3[]> iBMarkerPlates_normals;
public List<Vector3[]> iFMarkerPlates_normals;
//Back lanes:
public List<RoadIntersection> iBLane0s_tID;
public List<RoadIntersection> iBLane1s_tID;
public List<RoadIntersection> iBLane2s_tID;
public List<RoadIntersection> iBLane3s_tID;
//Front lanes:
public List<RoadIntersection> iFLane0s_tID;
public List<RoadIntersection> iFLane1s_tID;
public List<RoadIntersection> iFLane2s_tID;
public List<RoadIntersection> iFLane3s_tID;
//Main plates:
public List<RoadIntersection> iBMainPlates_tID;
public List<RoadIntersection> iFMainPlates_tID;
//Marker plates:
public List<RoadIntersection> iBMarkerPlates_tID;
public List<RoadIntersection> iFMarkerPlates_tID;
//Back lanes:
public List<SplineN> iBLane0s_nID;
public List<SplineN> iBLane1s_nID;
public List<SplineN> iBLane2s_nID;
public List<SplineN> iBLane3s_nID;
//Front lanes:
public List<SplineN> iFLane0s_nID;
public List<SplineN> iFLane1s_nID;
public List<SplineN> iFLane2s_nID;
public List<SplineN> iFLane3s_nID;
//Main plates:
public List<SplineN> iBMainPlates_nID;
public List<SplineN> iFMainPlates_nID;
//Marker plates:
public List<SplineN> iBMarkerPlates_nID;
public List<SplineN> iFMarkerPlates_nID;
//Back lanes:
public List<Vector2[]> iBLane0s_uv;
public List<Vector2[]> iBLane1s_uv;
public List<Vector2[]> iBLane2s_uv;
public List<Vector2[]> iBLane3s_uv;
//Front lanes:
public List<Vector2[]> iFLane0s_uv;
public List<Vector2[]> iFLane1s_uv;
public List<Vector2[]> iFLane2s_uv;
public List<Vector2[]> iFLane3s_uv;
//Main plates:
public List<Vector2[]> iBMainPlates_uv;
public List<Vector2[]> iFMainPlates_uv;
public List<Vector2[]> iBMainPlates_uv2;
public List<Vector2[]> iFMainPlates_uv2;
//Marker plates:
public List<Vector2[]> iBMarkerPlates_uv;
public List<Vector2[]> iFMarkerPlates_uv;
//Back lanes:
public List<Vector4[]> iBLane0s_tangents;
public List<Vector4[]> iBLane1s_tangents;
public List<Vector4[]> iBLane2s_tangents;
public List<Vector4[]> iBLane3s_tangents;
//Front lanes:
public List<Vector4[]> iFLane0s_tangents;
public List<Vector4[]> iFLane1s_tangents;
public List<Vector4[]> iFLane2s_tangents;
public List<Vector4[]> iFLane3s_tangents;
//Main plates:
public List<Vector4[]> iBMainPlates_tangents;
public List<Vector4[]> iFMainPlates_tangents;
public List<Vector4[]> iBMainPlates_tangents2;
public List<Vector4[]> iFMainPlates_tangents2;
//Marker plates:
public List<Vector4[]> iBMarkerPlates_tangents;
public List<Vector4[]> iFMarkerPlates_tangents;
public Terrain tTerrain;
public List<Construction2DRect> tIntersectionBounds;
public HashSet<Vector3> ImmuneVects;
public Mesh tMesh;
public Mesh tMesh_SR;
public Mesh tMesh_SL;
public bool tMeshSkip = false;
public bool tMesh_SRSkip = false;
public bool tMesh_SLSkip = false;
public List<Mesh> tMesh_RoadCuts;
public List<Mesh> tMesh_SRCuts;
public List<Mesh> tMesh_SLCuts;
public List<Mesh> tMesh_RoadCuts_world;
public List<Mesh> tMesh_SRCuts_world;
public List<Mesh> tMesh_SLCuts_world;
public List<Mesh> tMesh_RoadConnections;
public List<Mesh> tMesh_iBLanes0;
public List<Mesh> tMesh_iBLanes1;
public List<Mesh> tMesh_iBLanes2;
public List<Mesh> tMesh_iBLanes3;
public List<Mesh> tMesh_iFLanes0;
public List<Mesh> tMesh_iFLanes1;
public List<Mesh> tMesh_iFLanes2;
public List<Mesh> tMesh_iFLanes3;
public List<Mesh> tMesh_iBMainPlates;
public List<Mesh> tMesh_iFMainPlates;
public List<Mesh> tMesh_iBMarkerPlates;
public List<Mesh> tMesh_iFMarkerPlates;
public RoadUpdateTypeEnum tUpdateType;
public bool isRoadOn = true;
public bool isTerrainOn = true;
public bool isBridgesOn = true;
public bool isInterseOn = true;
public List<int> RoadCuts;
public List<SplineN> RoadCutNodes;
public List<int> ShoulderCutsR;
public List<SplineN> ShoulderCutsRNodes;
public List<int> ShoulderCutsL;
public List<SplineN> ShoulderCutsLNodes;
#endregion
public enum SaveMeshTypeEnum { Road, Shoulder, Intersection, Railing, Center, Bridge, RoadCut, SCut, BSCut, RoadConn };
public RoadConstructorBufferMaker(Road _road, RoadUpdateTypeEnum _updateType)
{
tUpdateType = _updateType;
isRoadOn = (tUpdateType == RoadUpdateTypeEnum.Full || tUpdateType == RoadUpdateTypeEnum.Intersection || tUpdateType == RoadUpdateTypeEnum.Bridges);
isTerrainOn = (tUpdateType == RoadUpdateTypeEnum.Full || tUpdateType == RoadUpdateTypeEnum.Intersection || tUpdateType == RoadUpdateTypeEnum.Bridges);
isBridgesOn = (tUpdateType == RoadUpdateTypeEnum.Full || tUpdateType == RoadUpdateTypeEnum.Bridges);
isInterseOn = (tUpdateType == RoadUpdateTypeEnum.Full || tUpdateType == RoadUpdateTypeEnum.Intersection);
road = _road;
Nullify();
RoadVectors = new List<Vector3>();
ShoulderR_Vectors = new List<Vector3>();
ShoulderL_Vectors = new List<Vector3>();
normals_ShoulderR_averageStartIndexes = new List<int>();
normals_ShoulderL_averageStartIndexes = new List<int>();
cut_RoadVectors = new List<List<Vector3>>();
cut_RoadVectorsHome = new List<Vector3>();
cut_ShoulderR_Vectors = new List<List<Vector3>>();
cut_ShoulderL_Vectors = new List<List<Vector3>>();
cut_ShoulderR_VectorsHome = new List<Vector3>();
cut_ShoulderL_VectorsHome = new List<Vector3>();
cut_tris = new List<int[]>();
cut_tris_ShoulderR = new List<int[]>();
cut_tris_ShoulderL = new List<int[]>();
cut_normals = new List<Vector3[]>();
cut_normals_ShoulderR = new List<Vector3[]>();
cut_normals_ShoulderL = new List<Vector3[]>();
cut_uv = new List<Vector2[]>();
cut_uv_SR = new List<Vector2[]>();
cut_uv_SL = new List<Vector2[]>();
cut_tangents = new List<Vector4[]>();
cut_tangents_SR = new List<Vector4[]>();
cut_tangents_SL = new List<Vector4[]>();
cut_uv_world = new List<Vector2[]>();
cut_uv_SR_world = new List<Vector2[]>();
cut_uv_SL_world = new List<Vector2[]>();
cut_tangents_world = new List<Vector4[]>();
cut_tangents_SR_world = new List<Vector4[]>();
cut_tangents_SL_world = new List<Vector4[]>();
RoadCutNodes = new List<SplineN>();
ShoulderCutsRNodes = new List<SplineN>();
ShoulderCutsLNodes = new List<SplineN>();
RoadConnections_verts = new List<Vector3[]>();
RoadConnections_tris = new List<int[]>();
RoadConnections_normals = new List<Vector3[]>();
RoadConnections_uv = new List<Vector2[]>();
RoadConnections_tangents = new List<Vector4[]>();
RoadCuts = new List<int>();
ShoulderCutsR = new List<int>();
ShoulderCutsL = new List<int>();
//if(bInterseOn){
//Back lanes:
iBLane0s = new List<Vector3[]>();
iBLane1s = new List<Vector3[]>();
iBLane2s = new List<Vector3[]>();
iBLane3s = new List<Vector3[]>();
//Front lanes:
iFLane0s = new List<Vector3[]>();
iFLane1s = new List<Vector3[]>();
iFLane2s = new List<Vector3[]>();
iFLane3s = new List<Vector3[]>();
//Main plates:
iBMainPlates = new List<Vector3[]>();
iFMainPlates = new List<Vector3[]>();
//Marker plates:
iBMarkerPlates = new List<Vector3[]>();
iFMarkerPlates = new List<Vector3[]>();
//Back lanes:
iBLane0s_tris = new List<int[]>();
iBLane1s_tris = new List<int[]>();
iBLane2s_tris = new List<int[]>();
iBLane3s_tris = new List<int[]>();
//Front lanes:
iFLane0s_tris = new List<int[]>();
iFLane1s_tris = new List<int[]>();
iFLane2s_tris = new List<int[]>();
iFLane3s_tris = new List<int[]>();
//Main plates:
iBMainPlates_tris = new List<int[]>();
iFMainPlates_tris = new List<int[]>();
//Marker plates:
iBMarkerPlates_tris = new List<int[]>();
iFMarkerPlates_tris = new List<int[]>();
//Back lanes:
iBLane0s_normals = new List<Vector3[]>();
iBLane1s_normals = new List<Vector3[]>();
iBLane2s_normals = new List<Vector3[]>();
iBLane3s_normals = new List<Vector3[]>();
//Front lanes:
iFLane0s_normals = new List<Vector3[]>();
iFLane1s_normals = new List<Vector3[]>();
iFLane2s_normals = new List<Vector3[]>();
iFLane3s_normals = new List<Vector3[]>();
//Main plates:
iBMainPlates_normals = new List<Vector3[]>();
iFMainPlates_normals = new List<Vector3[]>();
//Marker plates:
iBMarkerPlates_normals = new List<Vector3[]>();
iFMarkerPlates_normals = new List<Vector3[]>();
//Back lanes:
iBLane0s_uv = new List<Vector2[]>();
iBLane1s_uv = new List<Vector2[]>();
iBLane2s_uv = new List<Vector2[]>();
iBLane3s_uv = new List<Vector2[]>();
//Front lanes:
iFLane0s_uv = new List<Vector2[]>();
iFLane1s_uv = new List<Vector2[]>();
iFLane2s_uv = new List<Vector2[]>();
iFLane3s_uv = new List<Vector2[]>();
//Main plates:
iBMainPlates_uv = new List<Vector2[]>();
iFMainPlates_uv = new List<Vector2[]>();
iBMainPlates_uv2 = new List<Vector2[]>();
iFMainPlates_uv2 = new List<Vector2[]>();
//Marker plates:
iBMarkerPlates_uv = new List<Vector2[]>();
iFMarkerPlates_uv = new List<Vector2[]>();
//Back lanes:
iBLane0s_tangents = new List<Vector4[]>();
iBLane1s_tangents = new List<Vector4[]>();
iBLane2s_tangents = new List<Vector4[]>();
iBLane3s_tangents = new List<Vector4[]>();
//Front lanes:
iFLane0s_tangents = new List<Vector4[]>();
iFLane1s_tangents = new List<Vector4[]>();
iFLane2s_tangents = new List<Vector4[]>();
iFLane3s_tangents = new List<Vector4[]>();
//Main plates:
iBMainPlates_tangents = new List<Vector4[]>();
iFMainPlates_tangents = new List<Vector4[]>();
iBMainPlates_tangents2 = new List<Vector4[]>();
iFMainPlates_tangents2 = new List<Vector4[]>();
//Marker plates:
iBMarkerPlates_tangents = new List<Vector4[]>();
iFMarkerPlates_tangents = new List<Vector4[]>();
iFLane1s_IsMiddleLane = new List<bool>();
iBLane1s_IsMiddleLane = new List<bool>();
//Back lanes:
iBLane0s_tID = new List<RoadIntersection>();
iBLane1s_tID = new List<RoadIntersection>();
iBLane2s_tID = new List<RoadIntersection>();
iBLane3s_tID = new List<RoadIntersection>();
//Front lanes:
iFLane0s_tID = new List<RoadIntersection>();
iFLane1s_tID = new List<RoadIntersection>();
iFLane2s_tID = new List<RoadIntersection>();
iFLane3s_tID = new List<RoadIntersection>();
//Main plates:
iBMainPlates_tID = new List<RoadIntersection>();
iFMainPlates_tID = new List<RoadIntersection>();
//Marker plates:
iBMarkerPlates_tID = new List<RoadIntersection>();
iFMarkerPlates_tID = new List<RoadIntersection>();
iBLane0s_nID = new List<SplineN>();
iBLane1s_nID = new List<SplineN>();
iBLane2s_nID = new List<SplineN>();
iBLane3s_nID = new List<SplineN>();
//Front lanes:
iFLane0s_nID = new List<SplineN>();
iFLane1s_nID = new List<SplineN>();
iFLane2s_nID = new List<SplineN>();
iFLane3s_nID = new List<SplineN>();
//Main plates:
iBMainPlates_nID = new List<SplineN>();
iFMainPlates_nID = new List<SplineN>();
//Marker plates:
iBMarkerPlates_nID = new List<SplineN>();
iFMarkerPlates_nID = new List<SplineN>();
//}
tTerrain = null;
tMesh = new Mesh();
tMesh_SR = new Mesh();
tMesh_SL = new Mesh();
tMesh_RoadCuts = new List<Mesh>();
tMesh_SRCuts = new List<Mesh>();
tMesh_SLCuts = new List<Mesh>();
tMesh_RoadCuts_world = new List<Mesh>();
tMesh_SRCuts_world = new List<Mesh>();
tMesh_SLCuts_world = new List<Mesh>();
tMesh_RoadConnections = new List<Mesh>();
//if(bInterseOn){
tMesh_iBLanes0 = new List<Mesh>();
tMesh_iBLanes1 = new List<Mesh>();
tMesh_iBLanes2 = new List<Mesh>();
tMesh_iBLanes3 = new List<Mesh>();
tMesh_iFLanes0 = new List<Mesh>();
tMesh_iFLanes1 = new List<Mesh>();
tMesh_iFLanes2 = new List<Mesh>();
tMesh_iFLanes3 = new List<Mesh>();
tMesh_iBMainPlates = new List<Mesh>();
tMesh_iFMainPlates = new List<Mesh>();
tMesh_iBMarkerPlates = new List<Mesh>();
tMesh_iFMarkerPlates = new List<Mesh>();
tIntersectionBounds = new List<Construction2DRect>();
ImmuneVects = new HashSet<Vector3>();
//}
InitGameObjects();
}
#region "Init and nullify"
private void InitGameObjects()
{
//Destry past objects:
if (road.MainMeshes != null)
{
MeshFilter[] MFArray = road.MainMeshes.GetComponentsInChildren<MeshFilter>();
MeshCollider[] MCArray = road.MainMeshes.GetComponentsInChildren<MeshCollider>();
int MFArrayCount = MFArray.Length;
int MCArrayCount = MCArray.Length;
for (int index = (MFArrayCount - 1); index > -1; index--)
{
MFArray[index].sharedMesh = null;
}
for (int index = (MCArrayCount - 1); index > -1; index--)
{
MCArray[index].sharedMesh = null;
}
Object.DestroyImmediate(road.MainMeshes);
}
//Main mesh object:
road.MainMeshes = new GameObject("MainMeshes");
road.MainMeshes.transform.parent = road.transform;
//Road and shoulders:
road.MeshRoad = new GameObject("RoadMesh");
road.MeshShoR = new GameObject("ShoulderR");
road.MeshShoL = new GameObject("ShoulderL");
road.MeshRoad.transform.parent = road.MainMeshes.transform;
road.MeshShoR.transform.parent = road.MainMeshes.transform;
road.MeshShoL.transform.parent = road.MainMeshes.transform;
//Intersections:
road.MeshiLanes = new GameObject("MeshiLanes");
road.MeshiLanes0 = new GameObject("MeshiLanes0");
road.MeshiLanes1 = new GameObject("MeshiLanes1");
road.MeshiLanes2 = new GameObject("MeshiLanes2");
road.MeshiLanes3 = new GameObject("MeshiLanes3");
road.MeshiMainPlates = new GameObject("MeshiMainPlates");
road.MeshiMarkerPlates = new GameObject("MeshiMarkerPlates");
road.MeshiLanes.transform.parent = road.MainMeshes.transform;
road.MeshiLanes0.transform.parent = road.MainMeshes.transform;
road.MeshiLanes1.transform.parent = road.MainMeshes.transform;
road.MeshiLanes2.transform.parent = road.MainMeshes.transform;
road.MeshiLanes3.transform.parent = road.MainMeshes.transform;
road.MeshiMainPlates.transform.parent = road.MainMeshes.transform;
road.MeshiMarkerPlates.transform.parent = road.MainMeshes.transform;
}
public void Nullify()
{
RoadVectors = null;
ShoulderR_Vectors = null;
ShoulderL_Vectors = null;
tris = null;
normals = null;
uv = null;
uv_SR = null;
uv_SL = null;
tangents = null;
tangents_SR = null;
tangents_SL = null;
tTerrain = null;
tIntersectionBounds = null;
ImmuneVects = null;
iBLane0s = null;
iBLane1s = null;
iBLane2s = null;
iBLane3s = null;
iFLane0s = null;
iFLane1s = null;
iFLane2s = null;
iFLane3s = null;
iBMainPlates = null;
iFMainPlates = null;
iBMarkerPlates = null;
iFMarkerPlates = null;
tMesh = null;
tMesh_SR = null;
tMesh_SL = null;
RootUtils.NullifyList(ref tMesh_iBLanes0);
RootUtils.NullifyList(ref tMesh_iBLanes1);
RootUtils.NullifyList(ref tMesh_iBLanes2);
RootUtils.NullifyList(ref tMesh_iBLanes3);
RootUtils.NullifyList(ref tMesh_iFLanes0);
RootUtils.NullifyList(ref tMesh_iFLanes1);
RootUtils.NullifyList(ref tMesh_iFLanes2);
RootUtils.NullifyList(ref tMesh_iFLanes3);
RootUtils.NullifyList(ref tMesh_iBMainPlates);
RootUtils.NullifyList(ref tMesh_iFMainPlates);
RootUtils.NullifyList(ref tMesh_iBMarkerPlates);
RootUtils.NullifyList(ref tMesh_iFMarkerPlates);
tMesh_RoadConnections = null;
iFLane1s_IsMiddleLane = null;
iBLane1s_IsMiddleLane = null;
RoadConnections_verts = null;
RoadConnections_tris = null;
RoadConnections_normals = null;
RoadConnections_uv = null;
RoadConnections_tangents = null;
RootUtils.NullifyList(ref cut_uv_world);
RootUtils.NullifyList(ref cut_uv_SR_world);
RootUtils.NullifyList(ref cut_uv_SL_world);
RootUtils.NullifyList(ref cut_tangents_world);
RootUtils.NullifyList(ref cut_tangents_SR_world);
RootUtils.NullifyList(ref cut_tangents_SL_world);
tMesh = null;
tMesh_SR = null;
tMesh_SL = null;
tMesh_SR = null;
tMesh_SL = null;
tMesh_RoadCuts = null;
tMesh_SRCuts = null;
tMesh_SLCuts = null;
tMesh_RoadCuts_world = null;
tMesh_SRCuts_world = null;
tMesh_SLCuts_world = null;
}
#endregion
#region "Mesh Setup1"
/// <summary>
/// Creates meshes and assigns vertices, triangles and normals. If multithreading enabled, this occurs inbetween threaded jobs since unity library can't be used in threads.
/// </summary>
public void MeshSetup1()
{
Mesh MeshBuffer = null;
if (isInterseOn)
{
MeshSetup1IntersectionObjectsSetup();
}
if (isRoadOn)
{
//Main road:
if (RoadVectors.Count < 64000)
{
if (tMesh == null)
{
tMesh = new Mesh();
}
tMesh = MeshSetup1Helper(ref tMesh, RoadVectors.ToArray(), ref tris, ref normals);
tMeshSkip = false;
}
else
{
tMeshSkip = true;
}
//Right shoulder:
if (ShoulderR_Vectors.Count < 64000)
{
if (tMesh_SR == null)
{
tMesh_SR = new Mesh();
}
tMesh_SR = MeshSetup1Helper(ref tMesh_SR, ShoulderR_Vectors.ToArray(), ref tris_ShoulderR, ref normals_ShoulderR);
tMesh_SRSkip = false;
}
else
{
tMesh_SRSkip = true;
}
//Left shoulder:
if (ShoulderL_Vectors.Count < 64000)
{
if (tMesh_SL == null)
{
tMesh_SL = new Mesh();
}
tMesh_SL = MeshSetup1Helper(ref tMesh_SL, ShoulderL_Vectors.ToArray(), ref tris_ShoulderL, ref normals_ShoulderL);
tMesh_SLSkip = false;
}
else
{
tMesh_SLSkip = true;
}
if (RoadConnections_verts.Count > 0)
{
Mesh qMesh = null;
for (int index = 0; index < RoadConnections_verts.Count; index++)
{
qMesh = new Mesh();
qMesh.vertices = RoadConnections_verts[index];
qMesh.triangles = RoadConnections_tris[index];
qMesh.normals = RoadConnections_normals[index];
qMesh.uv = RoadConnections_uv[index];
qMesh.RecalculateNormals();
RoadConnections_normals[index] = qMesh.normals;
tMesh_RoadConnections.Add(qMesh);
}
}
if ((road.isRoadCutsEnabled || road.isDynamicCutsEnabled) && RoadCuts.Count > 0)
{
int[] tTris = null;
Vector3[] tNormals = null;
int cCount = cut_RoadVectors.Count;
for (int index = 0; index < cCount; index++)
{
tTris = cut_tris[index];
tNormals = cut_normals[index];
MeshBuffer = new Mesh();
tMesh_RoadCuts.Add(MeshSetup1Helper(ref MeshBuffer, cut_RoadVectors[index].ToArray(), ref tTris, ref tNormals));
MeshBuffer = new Mesh();
tMesh_RoadCuts_world.Add(MeshSetup1Helper(ref MeshBuffer, cut_RoadVectors[index].ToArray(), ref tTris, ref tNormals));
cut_normals[index] = tNormals;
tMeshSkip = true;
}
}
if (road.isShoulderCutsEnabled || road.isDynamicCutsEnabled)
{
int[] tTris = null;
Vector3[] tNormals = null;
int rCount = cut_ShoulderR_Vectors.Count;
for (int index = 0; index < rCount; index++)
{
tTris = cut_tris_ShoulderR[index];
tNormals = cut_normals_ShoulderR[index];
MeshBuffer = new Mesh();
tMesh_SRCuts.Add(MeshSetup1Helper(ref MeshBuffer, cut_ShoulderR_Vectors[index].ToArray(), ref tTris, ref tNormals));
MeshBuffer = new Mesh();
tMesh_SRCuts_world.Add(MeshSetup1Helper(ref MeshBuffer, cut_ShoulderR_Vectors[index].ToArray(), ref tTris, ref tNormals));
cut_normals_ShoulderR[index] = tNormals;
tMesh_SRSkip = true;
}
if (rCount <= 0)
{
tMesh_SRSkip = false;
}
int lCount = cut_ShoulderL_Vectors.Count;
for (int index = 0; index < lCount; index++)
{
tTris = cut_tris_ShoulderL[index];
tNormals = cut_normals_ShoulderL[index];
MeshBuffer = new Mesh();
tMesh_SLCuts.Add(MeshSetup1Helper(ref MeshBuffer, cut_ShoulderL_Vectors[index].ToArray(), ref tTris, ref tNormals));
MeshBuffer = new Mesh();
tMesh_SLCuts_world.Add(MeshSetup1Helper(ref MeshBuffer, cut_ShoulderL_Vectors[index].ToArray(), ref tTris, ref tNormals));
cut_normals_ShoulderL[index] = tNormals;
tMesh_SLSkip = true;
}
if (lCount <= 0)
{
tMesh_SLSkip = false;
}
}
}
if (isInterseOn)
{
MeshSetup1IntersectionParts();
}
MeshBuffer = null;
}
#region "Intersection for MeshSetup1"
/// <summary> Cleanup and create intersection objects </summary>
private void MeshSetup1IntersectionObjectsSetup()
{
int nodeCount = road.spline.GetNodeCount();
List<RoadIntersection> roadIntersections = new List<RoadIntersection>();
for (int index = 0; index < nodeCount; index++)
{
if (road.spline.nodes[index].isIntersection)
{
if (!roadIntersections.Contains(road.spline.nodes[index].intersection))
{
roadIntersections.Add(road.spline.nodes[index].intersection);
}
}
}
//Cleanups:
foreach (RoadIntersection intersection in roadIntersections)
{
IntersectionObjects.CleanupIntersectionObjects(intersection.transform.gameObject);
if (intersection.intersectionStopType == RoadIntersection.iStopTypeEnum.StopSign_AllWay)
{
IntersectionObjects.CreateStopSignsAllWay(intersection.transform.gameObject, true);
}
else if (intersection.intersectionStopType == RoadIntersection.iStopTypeEnum.TrafficLight1)
{
IntersectionObjects.CreateTrafficLightBases(intersection.transform.gameObject, true);
}
else if (intersection.intersectionStopType == RoadIntersection.iStopTypeEnum.TrafficLight2)
{
}
else if (intersection.intersectionStopType == RoadIntersection.iStopTypeEnum.None)
{
//Do nothing.
}
}
}
/// <summary> Creates intersection meshes if road contains intersections </summary>
private void MeshSetup1IntersectionParts()
{
int mCount = road.spline.GetNodeCount();
bool bHasInter = false;
for (int index = 0; index < mCount; index++)
{
if (road.spline.nodes[index].isIntersection)
{
bHasInter = true;
break;
}
}
if (!bHasInter)
{
return;
}
int vCount = -1;
Mesh MeshBuffer = null;
Vector3[] tNormals = null;
int[] tTris = null;
//Back lanes:
vCount = iBLane0s.Count;
for (int i = 0; i < vCount; i++)
{
tNormals = iBLane0s_normals[i];
tTris = iBLane0s_tris[i];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iBLane0s[i], ref tTris, ref tNormals);
tMesh_iBLanes0.Add(MeshBuffer);
}
vCount = iBLane1s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iBLane1s_normals[index];
tTris = iBLane1s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iBLane1s[index], ref tTris, ref tNormals);
tMesh_iBLanes1.Add(MeshBuffer);
}
vCount = iBLane2s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iBLane2s_normals[index];
tTris = iBLane2s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iBLane2s[index], ref tTris, ref tNormals);
tMesh_iBLanes2.Add(MeshBuffer);
}
vCount = iBLane3s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iBLane3s_normals[index];
tTris = iBLane3s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iBLane3s[index], ref tTris, ref tNormals);
tMesh_iBLanes3.Add(MeshBuffer);
}
//Front lanes:
vCount = iFLane0s.Count;
for (int i = 0; i < vCount; i++)
{
tNormals = iFLane0s_normals[i];
tTris = iFLane0s_tris[i];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iFLane0s[i], ref tTris, ref tNormals);
tMesh_iFLanes0.Add(MeshBuffer);
}
vCount = iFLane1s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iFLane1s_normals[index];
tTris = iFLane1s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iFLane1s[index], ref tTris, ref tNormals);
tMesh_iFLanes1.Add(MeshBuffer);
}
vCount = iFLane2s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iFLane2s_normals[index];
tTris = iFLane2s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iFLane2s[index], ref tTris, ref tNormals);
tMesh_iFLanes2.Add(MeshBuffer);
}
vCount = iFLane3s.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iFLane3s_normals[index];
tTris = iFLane3s_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iFLane3s[index], ref tTris, ref tNormals);
tMesh_iFLanes3.Add(MeshBuffer);
}
//Main plates:
vCount = iBMainPlates.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iBMainPlates_normals[index];
tTris = iBMainPlates_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iBMainPlates[index], ref tTris, ref tNormals);
tMesh_iBMainPlates.Add(MeshBuffer);
}
vCount = iFMainPlates.Count;
for (int index = 0; index < vCount; index++)
{
tNormals = iFMainPlates_normals[index];
tTris = iFMainPlates_tris[index];
MeshBuffer = new Mesh();
MeshBuffer = MeshSetup1Helper(ref MeshBuffer, iFMainPlates[index], ref tTris, ref tNormals);
tMesh_iFMainPlates.Add(MeshBuffer);
}
MeshBuffer = null;
}
#endregion
/// <summary> Assigns mesh values to _mesh and returns _mesh </summary>
private Mesh MeshSetup1Helper(ref Mesh _mesh, Vector3[] _verts, ref int[] _tris, ref Vector3[] _normals)
{
_mesh.vertices = _verts;
_mesh.triangles = _tris;
_mesh.normals = _normals;
_mesh.RecalculateNormals();
_normals = _mesh.normals;
//_mesh.hideFlags = HideFlags.DontSave;
return _mesh;
}
#endregion
#region "Mesh Setup2"
/// <summary>
/// Assigns UV and tangents to meshes. If multithreading enabled, this occurs after the last threaded job since unity library can't be used in threads.
/// </summary>
public void MeshSetup2()
{
Mesh MeshMainBuffer = null;
Mesh MeshMarkerBuffer = null;
if (isRoadOn)
{
// Materials batched and extracted from inner for loops of mesh creation
Material[] markerMaterialsField = road.GetRoadMarkerMaterials();
Material[] roadMaterialsField = road.GetRoadWorldMaterials();
// shoulder fields only contain data when isShouldersEnabled
Material[] shoulderMaterialsField = road.GetShoulderWorldMaterials();
Material[] shoulderMarkerMaterialsField = road.GetShoulderMarkerMaterials();
//If road cuts is off, full size UVs:
if ((!road.isRoadCutsEnabled && !road.isDynamicCutsEnabled) || (RoadCuts == null || RoadCuts.Count <= 0))
{
if (tMesh != null)
{
tMesh = MeshSetup2Helper(ref tMesh, uv, tangents, ref road.MeshRoad, shoulderMaterialsField, markerMaterialsField, roadMaterialsField, true);
SaveMesh(SaveMeshTypeEnum.Road, tMesh, road, road.MeshRoad.transform.name);
Vector3[] ooVerts = new Vector3[tMesh.vertexCount];
int[] ooTris = new int[tMesh.triangles.Length];
Vector3[] ooNormals = new Vector3[tMesh.normals.Length];
Vector2[] ooUV = new Vector2[uv2.Length];
Vector4[] ooTangents = new Vector4[tangents2.Length];
// Copy mesh values
System.Array.Copy(tMesh.vertices, ooVerts, ooVerts.Length);
System.Array.Copy(tMesh.triangles, ooTris, ooTris.Length);
System.Array.Copy(tMesh.normals, ooNormals, ooNormals.Length);
System.Array.Copy(uv2, ooUV, ooUV.Length);
System.Array.Copy(tangents2, ooTangents, ooTangents.Length);
Mesh pMesh = new Mesh();
pMesh.vertices = ooVerts;
pMesh.triangles = ooTris;
pMesh.normals = ooNormals;
pMesh.uv = ooUV;
pMesh.tangents = ooTangents;
GameObject gObj = new GameObject("Pavement");
pMesh = MeshSetup2Helper(ref pMesh, uv2, tangents2, ref gObj, shoulderMaterialsField, markerMaterialsField, roadMaterialsField, false);
//Road markers stored on parent "MeshRoad" game object, with a "Pavement" child game object storing the asphalt.
gObj.transform.parent = road.MeshRoad.transform;
SaveMesh(SaveMeshTypeEnum.Road, pMesh, road, gObj.transform.name);
}
}
else
{
//If road cuts, change it to one material (pavement) with world mapping
int cCount = cut_RoadVectors.Count;
//Vector2[] tUV;
bool bHasMats;
GameObject CreatedMainObj;
GameObject CreatedMarkerObj;
for (int i = 0; i < cCount; i++)
{
CreatedMainObj = null;
MeshMainBuffer = tMesh_RoadCuts_world[i];
if (MeshMainBuffer != null)
{
MeshSetup2HelperRoadCuts(i, ref MeshMainBuffer, cut_uv_world[i], cut_tangents_world[i], ref road.MeshRoad, false, out CreatedMainObj, markerMaterialsField, roadMaterialsField);
SaveMesh(SaveMeshTypeEnum.RoadCut, MeshMainBuffer, road, "RoadCut" + i.ToString());
}
CreatedMarkerObj = null;
MeshMarkerBuffer = tMesh_RoadCuts[i];
if (MeshMarkerBuffer != null)
{
bHasMats = MeshSetup2HelperRoadCuts(i, ref MeshMarkerBuffer, cut_uv[i], cut_tangents[i], ref CreatedMainObj, true, out CreatedMarkerObj, markerMaterialsField, roadMaterialsField);
if (bHasMats)
{
SaveMesh(SaveMeshTypeEnum.RoadCut, MeshMarkerBuffer, road, "RoadCutMarker" + i.ToString());
}
else
{
//Destroy if no marker materials:
Object.DestroyImmediate(CreatedMarkerObj);
Object.DestroyImmediate(MeshMarkerBuffer);
}
}
}
//Remove main mesh stuff if necessary:
if (road.MeshRoad != null)
{
MeshCollider tMC = road.MeshRoad.GetComponent<MeshCollider>();
MeshRenderer tMR = road.MeshRoad.GetComponent<MeshRenderer>();
Object.DestroyImmediate(tMC);
Object.DestroyImmediate(tMR);
}
Object.DestroyImmediate(tMesh);
}
//Shoulders:
if (road.isShouldersEnabled)
{
if ((!road.isShoulderCutsEnabled && !road.isDynamicCutsEnabled) || (ShoulderCutsL == null || cut_ShoulderL_Vectors.Count <= 0))
{
//Right road shoulder:
if (tMesh_SR != null)
{
tMesh_SR = MeshSetup2Helper(ref tMesh_SR, uv_SR, tangents_SR, ref road.MeshShoR, shoulderMaterialsField, markerMaterialsField, roadMaterialsField, false, true);
SaveMesh(SaveMeshTypeEnum.Shoulder, tMesh_SR, road, road.MeshShoR.transform.name);
}
//Left road shoulder:
if (tMesh_SL != null)
{
tMesh_SL = MeshSetup2Helper(ref tMesh_SL, uv_SL, tangents_SL, ref road.MeshShoL, shoulderMaterialsField, markerMaterialsField, roadMaterialsField, false, true);
SaveMesh(SaveMeshTypeEnum.Shoulder, tMesh_SL, road, road.MeshShoL.transform.name);
}
}
else
{
bool bHasMats;
GameObject CreatedMainObj;
GameObject CreatedMarkerObj;
int rCount = cut_ShoulderR_Vectors.Count;
for (int index = 0; index < rCount; index++)
{
CreatedMainObj = null;
MeshMainBuffer = tMesh_SRCuts_world[index];
if (MeshMainBuffer != null)
{
MeshSetup2HelperCutsShoulder(index, ref MeshMainBuffer, cut_uv_SR_world[index], cut_tangents_SR_world[index], ref road.MeshShoR, false, false, out CreatedMainObj, shoulderMarkerMaterialsField, shoulderMaterialsField);
SaveMesh(SaveMeshTypeEnum.SCut, MeshMainBuffer, road, "SCutR" + index.ToString());
}
CreatedMarkerObj = null;
MeshMarkerBuffer = tMesh_SRCuts[index];
if (MeshMarkerBuffer != null)
{
bHasMats = MeshSetup2HelperCutsShoulder(index, ref MeshMarkerBuffer, cut_uv_SR[index], cut_tangents_SR[index], ref CreatedMainObj, false, true, out CreatedMarkerObj, shoulderMarkerMaterialsField, shoulderMaterialsField);
if (bHasMats)
{
SaveMesh(SaveMeshTypeEnum.SCut, MeshMarkerBuffer, road, "SCutRMarker" + index.ToString());
}
else
{
//Destroy if no marker materials:
Object.DestroyImmediate(CreatedMarkerObj);
Object.DestroyImmediate(MeshMarkerBuffer);
}
}
}
int lCount = cut_ShoulderL_Vectors.Count;
for (int index = 0; index < lCount; index++)
{
CreatedMainObj = null;
MeshMainBuffer = tMesh_SLCuts_world[index];
if (MeshMainBuffer != null)
{
MeshSetup2HelperCutsShoulder(index, ref MeshMainBuffer, cut_uv_SL_world[index], cut_tangents_SL_world[index], ref road.MeshShoL, true, false, out CreatedMainObj, shoulderMarkerMaterialsField, shoulderMaterialsField);
SaveMesh(SaveMeshTypeEnum.SCut, MeshMainBuffer, road, "SCutL" + index.ToString());
}
CreatedMarkerObj = null;
MeshMarkerBuffer = tMesh_SLCuts[index];
if (MeshMarkerBuffer != null)
{
bHasMats = MeshSetup2HelperCutsShoulder(index, ref MeshMarkerBuffer, cut_uv_SL[index], cut_tangents_SL[index], ref CreatedMainObj, true, true, out CreatedMarkerObj, shoulderMarkerMaterialsField, shoulderMaterialsField);
if (bHasMats)
{
SaveMesh(SaveMeshTypeEnum.SCut, MeshMarkerBuffer, road, "SCutLMarker" + index.ToString());
}
else
{
//Destroy if no marker materials:
Object.DestroyImmediate(CreatedMarkerObj);
Object.DestroyImmediate(MeshMarkerBuffer);
}
}
}
if (road.isUsingMeshColliders)
{
//MeshSetup2IntersectionsFixNormals();
}
RemoveMainMeshes();
}
}
else
{
RemoveMainMeshes();
int xCount = tMesh_SRCuts_world.Count;
for (int index = 0; index < xCount; index++)
{
Object.DestroyImmediate(tMesh_SRCuts_world[index]);
}
tMesh_SRCuts_world.Clear();
xCount = tMesh_SRCuts.Count;
for (int index = 0; index < xCount; index++)
{
Object.DestroyImmediate(tMesh_SRCuts[index]);
}
tMesh_SRCuts.Clear();
xCount = tMesh_SLCuts_world.Count;
for (int index = 0; index < xCount; index++)
{
Object.DestroyImmediate(tMesh_SLCuts_world[index]);
}
tMesh_SLCuts_world.Clear();
xCount = tMesh_SLCuts.Count;
for (int index = 0; index < xCount; index++)
{
Object.DestroyImmediate(tMesh_SLCuts[index]);
}
tMesh_SLCuts.Clear();
Object.DestroyImmediate(road.MeshShoR);
Object.DestroyImmediate(road.MeshShoL);
}
string basePath = RoadEditorUtility.GetBasePath();
for (int index = 0; index < RoadConnections_tangents.Count; index++)
{
tMesh_RoadConnections[index].tangents = RoadConnections_tangents[index];
GameObject tObj = new GameObject("RoadConnectionMarker");
MeshFilter MF = tObj.AddComponent<MeshFilter>();
MeshRenderer MR = tObj.AddComponent<MeshRenderer>();
float fDist = Vector3.Distance(RoadConnections_verts[index][2], RoadConnections_verts[index][3]);
fDist = Mathf.Round(fDist);
if (road.laneAmount == 2)
{
if (fDist == Mathf.Round(road.RoadWidth() * 2f))
{
RoadEditorUtility.SetRoadMaterial(basePath + "/Materials/Markers/RoadConn-4L.mat", MR);
}
else if (fDist == Mathf.Round(road.RoadWidth() * 3f))
{
RoadEditorUtility.SetRoadMaterial(basePath + "/Materials/Markers/RoadConn-6L-2L.mat", MR);
}
}
else if (road.laneAmount == 4)
{
if (fDist == Mathf.Round(road.RoadWidth() * 1.5f))
{
RoadEditorUtility.SetRoadMaterial(basePath + "/Materials/Markers/RoadConn-6L-4L.mat", MR);
}
}
MF.sharedMesh = tMesh_RoadConnections[index];
tObj.transform.parent = road.MeshRoad.transform;
Mesh vMesh = new Mesh();
vMesh.vertices = RoadConnections_verts[index];
vMesh.triangles = RoadConnections_tris[index];
vMesh.normals = RoadConnections_normals[index];
Vector2[] vUV = new Vector2[4];
vUV[0] = new Vector2(RoadConnections_verts[index][0].x / 5f, RoadConnections_verts[index][0].z / 5f);
vUV[1] = new Vector2(RoadConnections_verts[index][1].x / 5f, RoadConnections_verts[index][1].z / 5f);
vUV[2] = new Vector2(RoadConnections_verts[index][2].x / 5f, RoadConnections_verts[index][2].z / 5f);
vUV[3] = new Vector2(RoadConnections_verts[index][3].x / 5f, RoadConnections_verts[index][3].z / 5f);
vMesh.uv = vUV;
vMesh.RecalculateNormals();
RoadConnections_normals[index] = vMesh.normals;
vMesh.tangents = RootUtils.ProcessTangents(vMesh.triangles, vMesh.normals, vMesh.uv, vMesh.vertices);
tObj = new GameObject("RoadConnectionBase");
MF = tObj.AddComponent<MeshFilter>();
MR = tObj.AddComponent<MeshRenderer>();
MeshCollider MC = tObj.AddComponent<MeshCollider>();
MF.sharedMesh = vMesh;
MC.sharedMesh = MF.sharedMesh;
RoadEditorUtility.SetRoadMaterial(basePath + "/Materials/Road1.mat", MR);
tObj.transform.parent = road.MeshRoad.transform;
SaveMesh(SaveMeshTypeEnum.RoadConn, vMesh, road, "RoadConn" + index.ToString());
}
}
if (isInterseOn)
{
MeshSetup2Intersections();
}
Object.DestroyImmediate(road.MeshiLanes);
Object.DestroyImmediate(road.MeshiLanes0);
Object.DestroyImmediate(road.MeshiLanes1);
Object.DestroyImmediate(road.MeshiLanes2);
Object.DestroyImmediate(road.MeshiLanes3);
Object.DestroyImmediate(road.MeshiMainPlates);
Object.DestroyImmediate(road.MeshiMarkerPlates);
//Updates the road and shoulder cut materials if necessary.
//Note: Cycling through all nodes in case the road cuts and shoulder cut numbers don't match.
if (road.isRoadCutsEnabled || road.isShoulderCutsEnabled || road.isDynamicCutsEnabled)
{
int mCount = road.spline.GetNodeCount();
for (int index = 0; index < mCount; index++)
{
road.spline.nodes[index].UpdateCuts();
}
}
}
private void RemoveMainMeshes()
{
//Remove main mesh stuff if necessary:
Object.DestroyImmediate(tMesh_SR);
Object.DestroyImmediate(tMesh_SL);
if (road.MeshShoR != null)
{
MeshCollider tMC = road.MeshShoR.GetComponent<MeshCollider>();
MeshRenderer tMR = road.MeshShoR.GetComponent<MeshRenderer>();
Object.DestroyImmediate(tMC);
Object.DestroyImmediate(tMR);
}
if (road.MeshShoL != null)
{
MeshCollider tMC = road.MeshShoL.GetComponent<MeshCollider>();
MeshRenderer tMR = road.MeshShoL.GetComponent<MeshRenderer>();
Object.DestroyImmediate(tMC);
Object.DestroyImmediate(tMR);
}
}
#region "MeshSetup2 - Intersections"
//private void MeshSetup2IntersectionsFixNormals()
//{
// int mCount = tRoad.spline.GetNodeCount();
// SplineN tNode = null;
// RoadIntersection roadIntersection = null;
// float MaxDist = 0f;
// float[] tDists = new float[2];
// Collider[] tColliders = null;
// List<GameObject> tCuts = null;
//
// for(int h=0; h<mCount; h++)
// {
// tNode=tRoad.spline.mNodes[h];
// if(tNode.bIsIntersection)
// {
// roadIntersection = tNode.roadIntersection;
//
// tColliders = Physics.OverlapSphere(roadIntersection.CornerRR_Outer,tRoad.opt_ShoulderWidth*1.25f);
// tCuts = new List<GameObject>();
// foreach(Collider tCollider in tColliders)
// {
// if(tCollider.transform.name.Contains("cut"))
// {
// tCuts.Add(tCollider.transform.gameObject);
// }
// }
//
//
// foreach(GameObject tObj in tCuts)
// {
// MeshFilter MF1 = tCuts[0].GetComponent<MeshFilter>();
// if(MF1 == null)
// {
// continue;
// }
// Mesh zMesh1 = MF1.sharedMesh;
// Vector3[] tVerts1 = zMesh1.vertices;
// Vector3[] tNormals1 = zMesh1.normals;
// int MVL1 = tVerts1.Length;
// for(int i=0; i<MVL1; i++)
// {
// if(tVerts1[i] == roadIntersection.CornerRR)
// {
// tNormals1[i] = Vector3.up;
// }
// else if(tVerts1[i] == roadIntersection.CornerRR_Outer)
// {
// tNormals1[i] = Vector3.up;
// }
// }
// }
// }
// }
//}
/// <summary> Creates main roads of the intersections if road contains intersections </summary>
private void MeshSetup2Intersections()
{
int mCount = road.spline.GetNodeCount();
bool bHasInter = false;
for (int index = 0; index < mCount; index++)
{
if (road.spline.nodes[index].isIntersection)
{
bHasInter = true;
break;
}
}
if (!bHasInter)
{
return;
}
int vCount = -1;
Mesh xMesh = null;
Vector2[] tUV = null;
Vector4[] tTangents = null;
MeshFilter MF = null;
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane0 = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane1 = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane2 = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane3 = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_MainPlate = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_MainPlateM = new Dictionary<RoadIntersection, List<MeshFilter>>();
HashSet<RoadIntersection> uniqueRoadIntersection = new HashSet<RoadIntersection>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane1_Disabled = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane2_Disabled = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane2_DisabledActive = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane2_DisabledActiveR = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane3_Disabled = new Dictionary<RoadIntersection, List<MeshFilter>>();
Dictionary<RoadIntersection, List<MeshFilter>> tCombineDict_Lane1_DisabledActive = new Dictionary<RoadIntersection, List<MeshFilter>>();
string basePath = RoadEditorUtility.GetBasePath();
vCount = iBLane0s.Count;
for (int index = 0; index < vCount; index++)
{
tUV = iBLane0s_uv[index];
tTangents = iBLane0s_tangents[index];
xMesh = tMesh_iBLanes0[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes0, "Lane0B", basePath + "/Materials/Markers/InterWhiteLYellowR.mat");
if (!tCombineDict_Lane0.ContainsKey(iBLane0s_tID[index]))
{
tCombineDict_Lane0.Add(iBLane0s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane0[iBLane0s_tID[index]].Add(MF);
}
vCount = iBLane1s.Count;
for (int index = 0; index < vCount; index++)
{
bool isPrimaryNode = (iBLane1s_tID[index].node1 == iBLane1s_nID[index]);
if (!isPrimaryNode && iBLane1s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && (iBLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.TurnLane || iBLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes) && !iBLane1s_tID[index].isNode2BLeftTurnLane)
{
tUV = iBLane1s_uv[index];
tTangents = iBLane1s_tangents[index];
xMesh = tMesh_iBLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "LaneD1B", basePath + "/Materials/Markers/InterLaneDisabled.mat");
if (!tCombineDict_Lane1_Disabled.ContainsKey(iBLane1s_tID[index]))
{
tCombineDict_Lane1_Disabled.Add(iBLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1_Disabled[iBLane1s_tID[index]].Add(MF);
}
else if (isPrimaryNode && iBLane1s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iBLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes)
{
tUV = iBLane1s_uv[index];
tTangents = iBLane1s_tangents[index];
xMesh = tMesh_iBLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "LaneDA1B", basePath + "/Materials/Markers/InterLaneDisabledOuter.mat");
if (!tCombineDict_Lane1_DisabledActive.ContainsKey(iBLane1s_tID[index]))
{
tCombineDict_Lane1_DisabledActive.Add(iBLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1_DisabledActive[iBLane1s_tID[index]].Add(MF);
}
else
{
tUV = iBLane1s_uv[index];
tTangents = iBLane1s_tangents[index];
xMesh = tMesh_iBLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "Lane1B", basePath + "/Materials/Markers/InterYellowLWhiteR.mat");
if (!tCombineDict_Lane1.ContainsKey(iBLane1s_tID[index]))
{
tCombineDict_Lane1.Add(iBLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1[iBLane1s_tID[index]].Add(MF);
}
}
vCount = iBLane2s.Count;
for (int index = 0; index < vCount; index++)
{
bool bPrimaryNode = (iBLane2s_tID[index].node1 == iBLane2s_nID[index]);
if (!bPrimaryNode && iBLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && (iBLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.TurnLane || iBLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes) && !iBLane2s_tID[index].isNode2BLeftTurnLane)
{
tUV = iBLane2s_uv[index];
tTangents = iBLane2s_tangents[index];
xMesh = tMesh_iBLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneDA2B", basePath + "/Materials/Markers/InterLaneDisabledOuter.mat");
if (!tCombineDict_Lane2_DisabledActive.ContainsKey(iBLane2s_tID[index]))
{
tCombineDict_Lane2_DisabledActive.Add(iBLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_DisabledActive[iBLane2s_tID[index]].Add(MF);
}
else if (!bPrimaryNode && iBLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iBLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes && !iBLane2s_tID[index].isNode2BRightTurnLane)
{
tUV = iBLane2s_uv[index];
tTangents = iBLane2s_tangents[index];
xMesh = tMesh_iBLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneDA2B", basePath + "/Materials/Markers/InterLaneDisabledOuterR.mat");
if (!tCombineDict_Lane2_DisabledActiveR.ContainsKey(iBLane2s_tID[index]))
{
tCombineDict_Lane2_DisabledActiveR.Add(iBLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_DisabledActiveR[iBLane2s_tID[index]].Add(MF);
}
else if (bPrimaryNode && iBLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iBLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes)
{
tUV = iBLane2s_uv[index];
tTangents = iBLane2s_tangents[index];
xMesh = tMesh_iBLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneD2B", basePath + "/Materials/Markers/InterLaneDisabled.mat");
if (!tCombineDict_Lane2_Disabled.ContainsKey(iBLane2s_tID[index]))
{
tCombineDict_Lane2_Disabled.Add(iBLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_Disabled[iBLane2s_tID[index]].Add(MF);
}
else
{
tUV = iBLane2s_uv[index];
tTangents = iBLane2s_tangents[index];
xMesh = tMesh_iBLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "Lane2B", basePath + "/Materials/Markers/InterWhiteR.mat");
if (!tCombineDict_Lane2.ContainsKey(iBLane2s_tID[index]))
{
tCombineDict_Lane2.Add(iBLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2[iBLane2s_tID[index]].Add(MF);
}
}
vCount = iBLane3s.Count;
for (int index = 0; index < vCount; index++)
{
bool bPrimaryNode = (iBLane3s_tID[index].node1 == iBLane3s_nID[index]);
if (!bPrimaryNode && iBLane3s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iBLane3s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes && !iBLane3s_tID[index].isNode2BRightTurnLane)
{
tUV = iBLane3s_uv[index];
tTangents = iBLane3s_tangents[index];
xMesh = tMesh_iBLanes3[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes3, "LaneD3B", basePath + "/Materials/Markers/InterLaneDisabled.mat");
if (!tCombineDict_Lane3_Disabled.ContainsKey(iBLane3s_tID[index]))
{
tCombineDict_Lane3_Disabled.Add(iBLane3s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane3_Disabled[iBLane3s_tID[index]].Add(MF);
}
else
{
tUV = iBLane3s_uv[index];
tTangents = iBLane3s_tangents[index];
xMesh = tMesh_iBLanes3[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes3, "Lane3B", basePath + "/Materials/Markers/InterWhiteR.mat");
if (!tCombineDict_Lane3.ContainsKey(iBLane3s_tID[index]))
{
tCombineDict_Lane3.Add(iBLane3s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane3[iBLane3s_tID[index]].Add(MF);
}
}
//Front lanes:
vCount = iFLane0s.Count;
for (int index = 0; index < vCount; index++)
{
tUV = iFLane0s_uv[index];
tTangents = iFLane0s_tangents[index];
xMesh = tMesh_iFLanes0[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes0, "Lane0F", basePath + "/Materials/Markers/InterWhiteLYellowR.mat");
if (!tCombineDict_Lane0.ContainsKey(iFLane0s_tID[index]))
{
tCombineDict_Lane0.Add(iFLane0s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane0[iFLane0s_tID[index]].Add(MF);
}
vCount = iFLane1s.Count;
for (int index = 0; index < vCount; index++)
{
bool bPrimaryNode = (iFLane1s_tID[index].node1 == iFLane1s_nID[index]);
if (!bPrimaryNode && iFLane1s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && (iFLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes || iFLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.TurnLane) && !iFLane1s_tID[index].isNode2FLeftTurnLane)
{
tUV = iFLane1s_uv[index];
tTangents = iFLane1s_tangents[index];
xMesh = tMesh_iFLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "LaneD1F", basePath + "/Materials/Markers/InterLaneDisabled.mat");
if (!tCombineDict_Lane1_Disabled.ContainsKey(iFLane1s_tID[index]))
{
tCombineDict_Lane1_Disabled.Add(iFLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1_Disabled[iFLane1s_tID[index]].Add(MF);
}
else if (bPrimaryNode && iFLane1s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iFLane1s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes)
{
tUV = iFLane1s_uv[index];
tTangents = iFLane1s_tangents[index];
xMesh = tMesh_iFLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "LaneDAR1F", basePath + "/Materials/Markers/InterLaneDisabledOuterR.mat");
if (!tCombineDict_Lane1_DisabledActive.ContainsKey(iFLane1s_tID[index]))
{
tCombineDict_Lane1_DisabledActive.Add(iFLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1_DisabledActive[iFLane1s_tID[index]].Add(MF);
}
else
{
tUV = iFLane1s_uv[index];
tTangents = iFLane1s_tangents[index];
xMesh = tMesh_iFLanes1[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes1, "Lane1F", basePath + "/Materials/Markers/InterYellowLWhiteR.mat");
if (!tCombineDict_Lane1.ContainsKey(iFLane1s_tID[index]))
{
tCombineDict_Lane1.Add(iFLane1s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane1[iFLane1s_tID[index]].Add(MF);
}
}
vCount = iFLane2s.Count;
for (int index = 0; index < vCount; index++)
{
bool bPrimaryNode = (iFLane2s_tID[index].node1 == iFLane2s_nID[index]);
if (!bPrimaryNode && iFLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && (iFLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes || iFLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.TurnLane) && !iFLane2s_tID[index].isNode2FLeftTurnLane)
{
tUV = iFLane2s_uv[index];
tTangents = iFLane2s_tangents[index];
xMesh = tMesh_iFLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneDA2F", basePath + "/Materials/Markers/InterLaneDisabledOuter.mat");
if (!tCombineDict_Lane2_DisabledActive.ContainsKey(iFLane2s_tID[index]))
{
tCombineDict_Lane2_DisabledActive.Add(iFLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_DisabledActive[iFLane2s_tID[index]].Add(MF);
}
else if (!bPrimaryNode && iFLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iFLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes && !iFLane2s_tID[index].isNode2FRightTurnLane)
{
tUV = iFLane2s_uv[index];
tTangents = iFLane2s_tangents[index];
xMesh = tMesh_iFLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneDAR2F", basePath + "/Materials/Markers/InterLaneDisabledOuterR.mat");
if (!tCombineDict_Lane2_DisabledActiveR.ContainsKey(iFLane2s_tID[index]))
{
tCombineDict_Lane2_DisabledActiveR.Add(iFLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_DisabledActiveR[iFLane2s_tID[index]].Add(MF);
}
else if (bPrimaryNode && iFLane2s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iFLane2s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes)
{
tUV = iFLane2s_uv[index];
tTangents = iFLane2s_tangents[index];
xMesh = tMesh_iFLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "LaneD2F", basePath + "/Materials/Markers/InterLaneDisabled.mat");
if (!tCombineDict_Lane2_Disabled.ContainsKey(iFLane2s_tID[index]))
{
tCombineDict_Lane2_Disabled.Add(iFLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2_Disabled[iFLane2s_tID[index]].Add(MF);
}
else
{
tUV = iFLane2s_uv[index];
tTangents = iFLane2s_tangents[index];
xMesh = tMesh_iFLanes2[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes2, "Lane2F", basePath + "/Materials/Markers/InterWhiteR.mat");
if (!tCombineDict_Lane2.ContainsKey(iFLane2s_tID[index]))
{
tCombineDict_Lane2.Add(iFLane2s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane2[iFLane2s_tID[index]].Add(MF);
}
}
vCount = iFLane3s.Count;
for (int index = 0; index < vCount; index++)
{
bool bPrimaryNode = (iFLane3s_tID[index].node1 == iFLane3s_nID[index]);
if (!bPrimaryNode && iFLane3s_tID[index].intersectionType == RoadIntersection.IntersectionTypeEnum.ThreeWay && iFLane3s_tID[index].roadType == RoadIntersection.RoadTypeEnum.BothTurnLanes && !iFLane3s_tID[index].isNode2FRightTurnLane)
{
tUV = iFLane3s_uv[index];
tTangents = iFLane3s_tangents[index];
xMesh = tMesh_iFLanes3[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes3, "LaneD3F", basePath + "/Materials/Markers/InterWhiteR.mat");
if (!tCombineDict_Lane3_Disabled.ContainsKey(iFLane3s_tID[index]))
{
tCombineDict_Lane3_Disabled.Add(iFLane3s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane3_Disabled[iFLane3s_tID[index]].Add(MF);
}
else
{
tUV = iFLane3s_uv[index];
tTangents = iFLane3s_tangents[index];
xMesh = tMesh_iFLanes3[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiLanes3, "Lane3F", basePath + "/Materials/Markers/InterWhiteR.mat");
if (!tCombineDict_Lane3.ContainsKey(iFLane3s_tID[index]))
{
tCombineDict_Lane3.Add(iFLane3s_tID[index], new List<MeshFilter>());
}
tCombineDict_Lane3[iFLane3s_tID[index]].Add(MF);
}
}
//Main plates:
vCount = iBMainPlates.Count;
for (int index = 0; index < vCount; index++)
{
tUV = iBMainPlates_uv[index];
tTangents = iBMainPlates_tangents[index];
xMesh = tMesh_iBMainPlates[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiMainPlates, "MainPlateB", basePath + "/Materials/Road1.mat", false);
if (!tCombineDict_MainPlate.ContainsKey(iBMainPlates_tID[index]))
{
tCombineDict_MainPlate.Add(iBMainPlates_tID[index], new List<MeshFilter>());
}
tCombineDict_MainPlate[iBMainPlates_tID[index]].Add(MF);
Mesh fMesh = new Mesh();
fMesh.vertices = iBMainPlates[index];
fMesh.triangles = iBMainPlates_tris[index];
fMesh.normals = iBMainPlates_normals[index];
tUV = iBMainPlates_uv2[index];
tTangents = iBMainPlates_tangents2[index];
MF = MeshSetup2IntersectionHelper(ref fMesh, ref tUV, ref tTangents, ref road.MeshiMainPlates, "MainPlateBM", basePath + "/Materials/InterMainPlate1.mat");
if (!tCombineDict_MainPlateM.ContainsKey(iBMainPlates_tID[index]))
{
tCombineDict_MainPlateM.Add(iBMainPlates_tID[index], new List<MeshFilter>());
}
tCombineDict_MainPlateM[iBMainPlates_tID[index]].Add(MF);
}
vCount = iFMainPlates.Count;
for (int index = 0; index < vCount; index++)
{
tUV = iFMainPlates_uv[index];
tTangents = iFMainPlates_tangents[index];
xMesh = tMesh_iFMainPlates[index];
MF = MeshSetup2IntersectionHelper(ref xMesh, ref tUV, ref tTangents, ref road.MeshiMainPlates, "MainPlateFM", basePath + "/Materials/Road1.mat", false);
if (!tCombineDict_MainPlate.ContainsKey(iFMainPlates_tID[index]))
{
tCombineDict_MainPlate.Add(iFMainPlates_tID[index], new List<MeshFilter>());
}
tCombineDict_MainPlate[iFMainPlates_tID[index]].Add(MF);
Mesh tMesh = new Mesh();
tMesh.vertices = iFMainPlates[index];
tMesh.triangles = iFMainPlates_tris[index];
tMesh.normals = iFMainPlates_normals[index];
tUV = iFMainPlates_uv2[index];
tTangents = iFMainPlates_tangents2[index];
MF = MeshSetup2IntersectionHelper(ref tMesh, ref tUV, ref tTangents, ref road.MeshiMainPlates, "MainPlateFM", basePath + "/Materials/InterMainPlate1.mat");
if (!tCombineDict_MainPlateM.ContainsKey(iFMainPlates_tID[index]))
{
tCombineDict_MainPlateM.Add(iFMainPlates_tID[index], new List<MeshFilter>());
}
tCombineDict_MainPlateM[iFMainPlates_tID[index]].Add(MF);
}
vCount = road.spline.GetNodeCount();
SplineN tNode = null;
for (int index = 0; index < vCount; index++)
{
tNode = road.spline.nodes[index];
if (tNode.isIntersection && tNode.intersection != null && tNode.intersection.node1 == tNode)
{
//Create center plate
Vector3[] xVerts = new Vector3[4];
xVerts[0] = tNode.intersection.cornerLR;
xVerts[1] = tNode.intersection.cornerRR;
xVerts[2] = tNode.intersection.cornerLL;
xVerts[3] = tNode.intersection.cornerRL;
int[] xTris = new int[6];
xTris[0] = 0;
xTris[1] = 2;
xTris[2] = 1;
xTris[3] = 2;
xTris[4] = 3;
xTris[5] = 1;
Vector2[] xUV = new Vector2[4];
xUV[0] = new Vector2(xVerts[0].x / 5f, xVerts[0].z / 5f);
xUV[1] = new Vector2(xVerts[1].x / 5f, xVerts[1].z / 5f);
xUV[2] = new Vector2(xVerts[2].x / 5f, xVerts[2].z / 5f);
xUV[3] = new Vector2(xVerts[3].x / 5f, xVerts[3].z / 5f);
Vector2[] xUV2 = new Vector2[4];
xUV2[0] = new Vector2(0f, 0f);
xUV2[1] = new Vector2(1f, 0f);
xUV2[2] = new Vector2(0f, 1f);
xUV2[3] = new Vector2(1f, 1f);
Mesh vMesh = new Mesh();
vMesh.vertices = xVerts;
vMesh.triangles = xTris;
vMesh.normals = new Vector3[4];
vMesh.uv = xUV;
vMesh.RecalculateBounds();
vMesh.RecalculateNormals();
vMesh.tangents = RootUtils.ProcessTangents(xTris, vMesh.normals, xUV, xVerts);
if (road.isLightmapped)
{
//EngineIntegration.GenerateSecondaryUVSet(vMesh);
}
Transform intersectionChild;
int cCount = tNode.intersection.transform.childCount - 1;
for (int j = cCount; j >= 0; j--)
{
intersectionChild = tNode.intersection.transform.GetChild(j);
if (intersectionChild.name.ToLower() == "tcenter")
{
Object.DestroyImmediate(intersectionChild.gameObject);
continue;
}
if (intersectionChild.name.ToLower() == "markcenter")
{
Object.DestroyImmediate(intersectionChild.gameObject);
}
}
GameObject tCenter = new GameObject("tCenter");
MF = tCenter.AddComponent<MeshFilter>();
MF.sharedMesh = vMesh;
tCenter.transform.parent = tNode.intersection.transform;
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(tCenter);
}
if (road.isStatic)
{
tCenter.isStatic = true;
}
Mesh mMesh = new Mesh();
Vector3[] bVerts = new Vector3[4];
mMesh.vertices = xVerts;
mMesh.triangles = xTris;
mMesh.normals = new Vector3[4];
mMesh.uv = xUV2;
mMesh.RecalculateBounds();
mMesh.RecalculateNormals();
mMesh.tangents = RootUtils.ProcessTangents(xTris, vMesh.normals, xUV, xVerts);
GameObject tMarker = new GameObject("CenterMarkers");
//tMarker.transform.localPosition = default(Vector3);
MF = tMarker.AddComponent<MeshFilter>();
MF.sharedMesh = mMesh;
MeshRenderer MR = tMarker.AddComponent<MeshRenderer>();
MR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
//if(tNode.roadIntersection.MarkerCenter != null)
//{
//// MR.material = tNode.roadIntersection.MarkerCenter;
//}
tMarker.transform.parent = tNode.intersection.transform;
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(tMarker);
}
if (road.isStatic)
{
tMarker.isStatic = true;
}
bVerts = MF.sharedMesh.vertices;
for (int j = 0; j < 4; j++)
{
bVerts[j].y = tNode.intersection.signHeight;
}
int zCount = bVerts.Length;
for (int z = 0; z < zCount; z++)
{
bVerts[z] -= tNode.transform.position;
}
MF.sharedMesh.vertices = bVerts;
MR.transform.position = tNode.intersection.transform.position;
mMesh.RecalculateBounds();
if (road.isLightmapped)
{
//EngineIntegration.GenerateSecondaryUVSet(mMesh);
}
SaveMesh(SaveMeshTypeEnum.Intersection, MF.sharedMesh, road, tNode.intersection.transform.name + "-" + "CenterMarkers");
}
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane0)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "Lane0");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane1)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "Lane1");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane2)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "Lane2");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane3)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "Lane3");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_MainPlate)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "TiledExt", true);
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_MainPlateM)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "StretchExt");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane1_Disabled)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneD1");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane3_Disabled)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneD3");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane2_DisabledActive)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneDA2");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane2_DisabledActiveR)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneDAR2");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane2_Disabled)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneD2");
}
foreach (KeyValuePair<RoadIntersection, List<MeshFilter>> KVP in tCombineDict_Lane1_DisabledActive)
{
if (!uniqueRoadIntersection.Contains(KVP.Key))
{
uniqueRoadIntersection.Add(KVP.Key);
}
MeshSetup2CombineIntersections(KVP, KVP.Key.transform.name + "-" + "LaneDA1");
}
foreach (RoadIntersection roadIntersection in uniqueRoadIntersection)
{
roadIntersection.UpdateMaterials();
}
}
/// <summary> Combines all intersections in _valuePair into an single mesh </summary>
private void MeshSetup2CombineIntersections(KeyValuePair<RoadIntersection, List<MeshFilter>> _valuePair, string _name, bool _isMainPlates = false)
{
int vCount = _valuePair.Value.Count;
if (vCount < 1)
{
return;
}
_name = road.name + "-" + _name;
Transform child;
GameObject tCenter = null;
int cCount = _valuePair.Key.transform.childCount - 1;
for (int index = cCount; index >= 0; index--)
{
child = _valuePair.Key.transform.GetChild(index);
if (child.name.ToLower() == _name.ToLower())
{
Object.DestroyImmediate(child.gameObject);
continue;
}
if (_isMainPlates && child.name.ToLower() == "tcenter")
{
tCenter = child.gameObject;
}
}
int CombineCount = vCount;
if (tCenter != null)
{
CombineCount += 1;
}
CombineInstance[] combine = new CombineInstance[CombineCount];
for (int index = 0; index < vCount; index++)
{
combine[index].mesh = _valuePair.Value[index].sharedMesh;
combine[index].transform = _valuePair.Value[index].transform.localToWorldMatrix;
}
int SpecialVertCount = 0;
if (tCenter != null)
{
for (int index = 0; index < (CombineCount - 1); index++)
{
SpecialVertCount += combine[index].mesh.vertexCount;
}
MeshFilter tMF = tCenter.GetComponent<MeshFilter>();
Vector3[] xVerts = tMF.sharedMesh.vertices;
float xHeight = combine[0].mesh.vertices[combine[0].mesh.vertexCount - 1].y;
for (int index = 0; index < xVerts.Length; index++)
{
xVerts[index].y = xHeight;
}
tMF.sharedMesh.vertices = xVerts;
combine[CombineCount - 1].mesh = tMF.sharedMesh;
combine[CombineCount - 1].transform = tMF.transform.localToWorldMatrix;
}
GameObject tObj = new GameObject(_name);
MeshFilter MF = tObj.AddComponent<MeshFilter>();
Mesh tMesh = new Mesh();
tMesh.CombineMeshes(combine);
MF.sharedMesh = tMesh;
MeshRenderer MR = tObj.AddComponent<MeshRenderer>();
MR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
tObj.transform.parent = _valuePair.Key.transform;
Vector3[] tVerts = MF.sharedMesh.vertices;
Vector3 tVect = tObj.transform.localPosition;
for (int index = 0; index < tVerts.Length; index++)
{
tVerts[index] += tVect;
if (_name.ToLower().EndsWith("-stretchext"))
{
tVerts[index] += new Vector3(0f, 0.01f);
}
}
MF.sharedMesh.vertices = tVerts;
tObj.transform.localPosition = new Vector3(0f, 0f, 0f);
MF.sharedMesh.RecalculateBounds();
MF.sharedMesh.RecalculateNormals();
MF.sharedMesh.tangents = RootUtils.ProcessTangents(MF.sharedMesh.triangles, MF.sharedMesh.normals, MF.sharedMesh.uv, MF.sharedMesh.vertices);
if (road.isLightmapped)
{
EngineIntegration.GenerateSecondaryUVSet(MF.sharedMesh);
EngineIntegration.SetStaticEditorFlags(tObj);
}
if (road.isStatic)
{
tObj.isStatic = true;
}
if (_isMainPlates)
{
MeshCollider MC = tObj.AddComponent<MeshCollider>();
MC.sharedMesh = MF.sharedMesh;
MC.material = road.RoadPhysicMaterial;
MC.material.name = MC.material.name.Replace(" (Instance)", "");
Object.DestroyImmediate(tCenter);
}
SaveMesh(SaveMeshTypeEnum.Intersection, MF.sharedMesh, road, _name);
}
/// <summary> Assigns values to _mesh and returns the MeshFilter of a new GO </summary>
private MeshFilter MeshSetup2IntersectionHelper(ref Mesh _mesh, ref Vector2[] _uv, ref Vector4[] _tangents, ref GameObject _masterObj, string _name, string _mat, bool _isCollider = false)
{
if (_mesh == null)
{
return null;
}
_mesh.uv = _uv;
_mesh.tangents = _tangents;
if (road.isLightmapped)
{
EngineIntegration.GenerateSecondaryUVSet(_mesh);
}
GameObject tObj = new GameObject(_name);
tObj.transform.parent = _masterObj.transform;
MeshFilter MF = tObj.AddComponent<MeshFilter>();
MF.sharedMesh = _mesh;
if (_isCollider)
{
MeshCollider MC = tObj.AddComponent<MeshCollider>();
MC.sharedMesh = MF.sharedMesh;
}
if (_mat.Length < 1)
{
return null;
}
MeshRenderer MR = tObj.AddComponent<MeshRenderer>();
MR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
RoadEditorUtility.SetRoadMaterial(_mat, MR);
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(tObj);
}
if (road.isStatic)
{
tObj.isStatic = true;
}
return MF;
}
#endregion
/// <summary> Assigns values to _mesh </summary>
private Mesh MeshSetup2Helper(ref Mesh _mesh, Vector2[] _uv, Vector4[] _tangents, ref GameObject _obj, Material[] _shoulderMaterials, Material[] _markerMaterials, Material[] _roadMaterials, bool _isMarker, bool _isShoulder = false, bool _isBridge = false)
{
_mesh.uv = _uv;
_mesh.tangents = _tangents;
if (road.isLightmapped)
{
EngineIntegration.GenerateSecondaryUVSet(_mesh);
}
MeshFilter MF = _obj.AddComponent<MeshFilter>();
MF.sharedMesh = _mesh;
MeshCollider MC = null;
if (road.isUsingMeshColliders)
{
MC = _obj.AddComponent<MeshCollider>();
MC.sharedMesh = MF.sharedMesh;
}
MeshRenderer MR = _obj.AddComponent<MeshRenderer>();
if (_isShoulder)
{
if (_shoulderMaterials.Length > 0)
{
MR.materials = _shoulderMaterials;
}
}
else
{
if (_isMarker)
{
// It should not be necessary to check this, but I let it until I'm sure this does not break anything.
if (_markerMaterials.Length > 0)
{
MR.materials = _markerMaterials;
}
}
else
{
if (_roadMaterials.Length > 0)
{
MR.materials = _roadMaterials;
}
if (MC)
{
MC.sharedMaterial = road.RoadPhysicMaterial;
}
}
}
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(_obj);
}
if (road.isStatic)
{
_obj.isStatic = true;
}
return _mesh;
}
/// <summary> Creates a GameObject and adds mesh collider / renderer and configures mesh to be static etc. </summary>
private bool MeshSetup2HelperRoadCuts(int _i, ref Mesh _mesh, Vector2[] _uv, Vector4[] _tangents, ref GameObject _masterObj, bool _isMarkers, out GameObject _createdObj, Material[] _markerMaterials, Material[] _roadMaterials)
{
if (!_isMarkers)
{
_createdObj = new GameObject("RoadCut" + _i.ToString());
RoadCutNodes[_i].roadCutWorld = _createdObj;
}
else
{
_createdObj = new GameObject("Markers" + _i.ToString());
RoadCutNodes[_i].roadCutMarker = _createdObj;
}
_createdObj.transform.position = cut_RoadVectorsHome[_i];
_mesh.uv = _uv;
_mesh.tangents = _tangents;
if (road.isLightmapped)
{
EngineIntegration.GenerateSecondaryUVSet(_mesh);
}
MeshFilter MF = _createdObj.AddComponent<MeshFilter>();
MF.sharedMesh = _mesh;
MeshCollider MC = null;
if (road.isUsingMeshColliders && !_isMarkers)
{
MC = _createdObj.AddComponent<MeshCollider>();
if (MC.sharedMesh == null)
{
MC.sharedMesh = MF.sharedMesh;
}
}
MeshRenderer MR = _createdObj.AddComponent<MeshRenderer>();
//Disable shadows for road cuts and markers:
MR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
bool isUsingMaterials = false;
//Apply Materials:
if (_isMarkers)
{
if (_markerMaterials.Length > 0)
{
MR.materials = _markerMaterials;
isUsingMaterials = true;
}
}
else
{
if (_roadMaterials.Length > 0)
{
MR.materials = _roadMaterials;
isUsingMaterials = true;
}
}
_createdObj.transform.parent = _masterObj.transform;
if (!_isMarkers && MC != null)
{
MC.sharedMaterial = road.RoadPhysicMaterial;
}
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(_createdObj);
}
if (road.isStatic)
{
_createdObj.isStatic = true;
}
return isUsingMaterials;
}
/// <summary> Inserts new GO into according shoulder collection at _i; Assigns values to _mesh </summary>
private bool MeshSetup2HelperCutsShoulder(int _i, ref Mesh _mesh, Vector2[] _uv, Vector4[] _tangents, ref GameObject _masterObj, bool _isLeft, bool _isMarkers, out GameObject _createdObj, Material[] _shoulderMarkerMaterials, Material[] _shoulderMaterials)
{
if (_isMarkers)
{
_createdObj = new GameObject("Markers" + _i.ToString());
if (_isLeft)
{
_createdObj.transform.position = cut_ShoulderL_VectorsHome[_i];
ShoulderCutsLNodes[_i].shoulderCutLMarker = _createdObj;
}
else
{
_createdObj.transform.position = cut_ShoulderR_VectorsHome[_i];
ShoulderCutsRNodes[_i].shoulderCutRMarker = _createdObj;
}
}
else
{
if (_isLeft)
{
_createdObj = new GameObject("SCutL" + _i.ToString());
_createdObj.transform.position = cut_ShoulderL_VectorsHome[_i];
ShoulderCutsLNodes[_i].shoulderCutLWorld = _createdObj;
}
else
{
_createdObj = new GameObject("SCutR" + _i.ToString());
_createdObj.transform.position = cut_ShoulderR_VectorsHome[_i];
ShoulderCutsRNodes[_i].shoulderCutRWorld = _createdObj;
}
}
MeshCollider MC = null;
if (road.isUsingMeshColliders)
{
MC = _createdObj.AddComponent<MeshCollider>();
}
_mesh.uv = _uv;
_mesh.tangents = _tangents;
if (road.isLightmapped)
{
EngineIntegration.GenerateSecondaryUVSet(_mesh);
}
MeshFilter MF = _createdObj.AddComponent<MeshFilter>();
MF.sharedMesh = _mesh;
if (road.isUsingMeshColliders)
{
if (MC.sharedMesh == null)
{
MC.sharedMesh = MF.sharedMesh;
}
}
bool bHasMats = false;
//Disable shadows for road cuts and markers:
MeshRenderer MR = _createdObj.AddComponent<MeshRenderer>();
MR.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
if (_isMarkers)
{
if (_shoulderMarkerMaterials.Length > 0)
{
MR.materials = _shoulderMarkerMaterials;
bHasMats = true;
}
}
else
{
if (_shoulderMaterials.Length > 0)
{
MR.materials = _shoulderMaterials;
MR = null;
bHasMats = true;
}
}
if (!_isMarkers && MC != null)
{
MC.sharedMaterial = road.ShoulderPhysicMaterial;
}
_createdObj.transform.parent = _masterObj.transform;
if (road.isLightmapped)
{
EngineIntegration.SetStaticEditorFlags(_createdObj);
}
if (road.isStatic)
{
_createdObj.isStatic = true;
}
MF = null;
MC = null;
return bHasMats;
}
#endregion
/// <summary> Saves Mesh as an asset </summary>
private static void SaveMesh(SaveMeshTypeEnum _saveType, Mesh _mesh, Road _road, string _name)
{
if (!_road.isSavingMeshes)
{
return;
}
string sceneName;
sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
sceneName = sceneName.Replace("/", "");
sceneName = sceneName.Replace(".", "");
string folderName = Path.Combine(RoadEditorUtility.GetBasePath(), "Mesh");
folderName = Path.Combine(folderName, "Generated");
if (_saveType == SaveMeshTypeEnum.Road)
{
folderName = Path.Combine(folderName, "Roads");
}
else if (_saveType == SaveMeshTypeEnum.Shoulder)
{
folderName = Path.Combine(folderName, "Shoulders");
}
else if (_saveType == SaveMeshTypeEnum.Intersection)
{
folderName = Path.Combine(folderName, "Intersections");
}
else if (_saveType == SaveMeshTypeEnum.Railing)
{
folderName = Path.Combine(folderName, "Railings");
}
else if (_saveType == SaveMeshTypeEnum.Center)
{
folderName = Path.Combine(folderName, "CenterDividers");
}
else if (_saveType == SaveMeshTypeEnum.RoadCut)
{
folderName = Path.Combine(Path.Combine(folderName, "Roads"), "Cuts");
}
else if (_saveType == SaveMeshTypeEnum.SCut)
{
folderName = Path.Combine(Path.Combine(folderName, "Shoulders"), "Cuts");
}
else if (_saveType == SaveMeshTypeEnum.RoadConn)
{
folderName = Path.Combine(folderName, "RoadConn");
}
string path = Path.GetDirectoryName(Application.dataPath);
path = Path.Combine(path, folderName);
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);
}
string roadName = _road.transform.name;
string finalName = Path.Combine(folderName, sceneName + "-" + roadName + "-" + _name + ".asset");
if (_saveType == SaveMeshTypeEnum.Intersection)
{
finalName = Path.Combine(folderName, sceneName + "-" + _name + ".asset");
}
finalName = EngineIntegration.GetUnityFilePath(finalName);
EngineIntegration.CreateAsset(_mesh, finalName);
}
}
}