public void GenerateNodes (Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices) {
if (vectorVertices.Length == 0 || triangles.Length == 0) {
originalVertices = vectorVertices;
vertices = new Int3[0];
//graph.CreateNodes (0);
nodes = new TriangleMeshNode[0];
return;
}
vertices = new Int3[vectorVertices.Length];
//Backup the original vertices
//for (int i=0;i<vectorVertices.Length;i++) {
// vectorVertices[i] = graph.matrix.MultiplyPoint (vectorVertices[i]);
//}
int c = 0;
/*int maxX = 0;
int maxZ = 0;
//Almost infinity
int minX = 0xFFFFFFF;
int minZ = 0xFFFFFFF;*/
for (int i=0;i<vertices.Length;i++) {
vertices[i] = (Int3)matrix.MultiplyPoint3x4 (vectorVertices[i]);
/*maxX = Mathfx.Max (vertices[i].x, maxX);
maxZ = Mathfx.Max (vertices[i].z, maxZ);
minX = Mathfx.Min (vertices[i].x, minX);
minZ = Mathfx.Min (vertices[i].z, minZ);*/
}
//maxX = maxX-minX;
//maxZ = maxZ-minZ;
Dictionary<Int3,int> hashedVerts = new Dictionary<Int3,int> ();
int[] newVertices = new int[vertices.Length];
for (int i=0;i<vertices.Length-1;i++) {
//int hash = Mathfx.ComputeVertexHash (vertices[i].x,vertices[i].y,vertices[i].z);
//(vertices[i].x-minX)+(vertices[i].z-minX)*maxX+vertices[i].y*maxX*maxZ;
//if (sortedVertices[i] != sortedVertices[i+1]) {
if (!hashedVerts.ContainsKey (vertices[i])) {
newVertices[c] = i;
hashedVerts.Add (vertices[i], c);
c++;
}// else {
//Debug.Log ("Hash Duplicate "+hash+" "+vertices[i].ToString ());
//}
}
newVertices[c] = vertices.Length-1;
//int hash2 = (newVertices[c].x-minX)+(newVertices[c].z-minX)*maxX+newVertices[c].y*maxX*maxZ;
//int hash2 = Mathfx.ComputeVertexHash (newVertices[c].x,newVertices[c].y,newVertices[c].z);
if (!hashedVerts.ContainsKey (vertices[newVertices[c]])) {
hashedVerts.Add (vertices[newVertices[c]], c);
c++;
}
for (int x=0;x<triangles.Length;x++) {
Int3 vertex = vertices[triangles[x]];
//int hash3 = (vertex.x-minX)+(vertex.z-minX)*maxX+vertex.y*maxX*maxZ;
//int hash3 = Mathfx.ComputeVertexHash (vertex.x,vertex.y,vertex.z);
//for (int y=0;y<newVertices.Length;y++) {
triangles[x] = hashedVerts[vertex];
}
/*for (int i=0;i<triangles.Length;i += 3) {
Vector3 offset = Vector3.forward*i*0.01F;
Debug.DrawLine (newVertices[triangles[i]]+offset,newVertices[triangles[i+1]]+offset,Color.blue);
Debug.DrawLine (newVertices[triangles[i+1]]+offset,newVertices[triangles[i+2]]+offset,Color.blue);
Debug.DrawLine (newVertices[triangles[i+2]]+offset,newVertices[triangles[i]]+offset,Color.blue);
}*/
//Debug.Log ("NavMesh - Old vertice count "+vertices.Length+", new vertice count "+c+" "+maxX+" "+maxZ+" "+maxX*maxZ);
Int3[] totalIntVertices = vertices;
vertices = new Int3[c];
originalVertices = new Vector3[c];
for (int i=0;i<c;i++) {
vertices[i] = totalIntVertices[newVertices[i]];//(Int3)graph.matrix.MultiplyPoint (vectorVertices[i]);
originalVertices[i] = (Vector3)vectorVertices[newVertices[i]];//vectorVertices[newVertices[i]];
}
//graph.CreateNodes (triangles.Length/3);//new Node[triangles.Length/3];
nodes = new TriangleMeshNode[triangles.Length/3];
for (int i=0;i<nodes.Length;i++) {
nodes[i] = new TriangleMeshNode(active);
TriangleMeshNode node = nodes[i];//new MeshNode ();
node.Penalty = initialPenalty;
node.Walkable = true;
node.v0 = triangles[i*3];
node.v1 = triangles[i*3+1];
node.v2 = triangles[i*3+2];
if (!Polygon.IsClockwise (vertices[node.v0],vertices[node.v1],vertices[node.v2])) {
//Debug.DrawLine (vertices[node.v0],vertices[node.v1],Color.red);
//Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
//Debug.DrawLine (vertices[node.v2],vertices[node.v0],Color.red);
int tmp = node.v0;
node.v0 = node.v2;
node.v2 = tmp;
}
if (Polygon.IsColinear (vertices[node.v0],vertices[node.v1],vertices[node.v2])) {
Debug.DrawLine ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],Color.red);
Debug.DrawLine ((Vector3)vertices[node.v1],(Vector3)vertices[node.v2],Color.red);
Debug.DrawLine ((Vector3)vertices[node.v2],(Vector3)vertices[node.v0],Color.red);
}
// Make sure position is correctly set
node.UpdatePositionFromVertices();
}
List<MeshNode> connections = new List<MeshNode> ();
List<uint> connectionCosts = new List<uint> ();
int identicalError = 0;
for (int i=0;i<triangles.Length;i+=3) {
connections.Clear ();
connectionCosts.Clear ();
//Int3 indices = new Int3(triangles[i],triangles[i+1],triangles[i+2]);
TriangleMeshNode node = nodes[i/3];
for (int x=0;x<triangles.Length;x+=3) {
if (x == i) {
continue;
}
int count = 0;
if (triangles[x] == triangles[i]) { count++; }
if (triangles[x+1] == triangles[i]) { count++; }
if (triangles[x+2] == triangles[i]) { count++; }
if (triangles[x] == triangles[i+1]) { count++; }
if (triangles[x+1] == triangles[i+1]) { count++; }
if (triangles[x+2] == triangles[i+1]) { count++; }
if (triangles[x] == triangles[i+2]) { count++; }
if (triangles[x+1] == triangles[i+2]) { count++; }
if (triangles[x+2] == triangles[i+2]) { count++; }
if (count >= 3) {
identicalError++;
Debug.DrawLine ((Vector3)vertices[triangles[x]],(Vector3)vertices[triangles[x+1]],Color.red);
Debug.DrawLine ((Vector3)vertices[triangles[x]],(Vector3)vertices[triangles[x+2]],Color.red);
Debug.DrawLine ((Vector3)vertices[triangles[x+2]],(Vector3)vertices[triangles[x+1]],Color.red);
}
if (count == 2) {
GraphNode other = nodes[x/3];
connections.Add (other as MeshNode);
connectionCosts.Add ((uint)(node.position-other.position).costMagnitude);
}
}
node.connections = connections.ToArray ();
node.connectionCosts = connectionCosts.ToArray ();
}
if (identicalError > 0) {
Debug.LogError ("One or more triangles are identical to other triangles, this is not a good thing to have in a navmesh\nIncreasing the scale of the mesh might help\nNumber of triangles with error: "+identicalError+"\n");
}
RebuildBBTree (this);
#if ASTARDEBUG
for (int i=0;i<nodes.Length;i++) {
TriangleMeshNode node = nodes[i] as TriangleMeshNode;
float a1 = Polygon.TriangleArea2 ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],(Vector3)vertices[node.v2]);
long a2 = Polygon.TriangleArea2 (vertices[node.v0],vertices[node.v1],vertices[node.v2]);
if (a1 * a2 < 0) Debug.LogError (a1+ " " + a2);
if (Polygon.IsClockwise (vertices[node.v0],vertices[node.v1],vertices[node.v2])) {
Debug.DrawLine ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],Color.green);
Debug.DrawLine ((Vector3)vertices[node.v1],(Vector3)vertices[node.v2],Color.green);
Debug.DrawLine ((Vector3)vertices[node.v2],(Vector3)vertices[node.v0],Color.green);
} else {
Debug.DrawLine ((Vector3)vertices[node.v0],(Vector3)vertices[node.v1],Color.red);
Debug.DrawLine ((Vector3)vertices[node.v1],(Vector3)vertices[node.v2],Color.red);
Debug.DrawLine ((Vector3)vertices[node.v2],(Vector3)vertices[node.v0],Color.red);
}
}
#endif
//Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
}