/** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
void GenerateNodes(Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
{
Profiler.BeginSample("Init");
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];
int c = 0;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = (Int3)matrix.MultiplyPoint3x4(vectorVertices[i]);
}
var hashedVerts = new Dictionary <Int3, int> ();
var newVertices = new int[vertices.Length];
Profiler.EndSample();
Profiler.BeginSample("Hashing");
for (int i = 0; i < vertices.Length; i++)
{
if (!hashedVerts.ContainsKey(vertices[i]))
{
newVertices[c] = i;
hashedVerts.Add(vertices[i], c);
c++;
}
}
for (int x = 0; x < triangles.Length; x++)
{
Int3 vertex = vertices[triangles[x]];
triangles[x] = hashedVerts[vertex];
}
Int3[] totalIntVertices = vertices;
vertices = new Int3[c];
originalVertices = new Vector3[c];
for (int i = 0; i < c; i++)
{
vertices[i] = totalIntVertices[newVertices[i]];
originalVertices[i] = vectorVertices[newVertices[i]];
}
Profiler.EndSample();
Profiler.BeginSample("Constructing Nodes");
nodes = new TriangleMeshNode[triangles.Length / 3];
int graphIndex = active.astarData.GetGraphIndex(this);
// Does not have to set this, it is set in ScanInternal
//TriangleMeshNode.SetNavmeshHolder ((int)graphIndex,this);
for (int i = 0; i < nodes.Length; i++)
{
nodes[i] = new TriangleMeshNode(active);
TriangleMeshNode node = nodes[i]; //new MeshNode ();
node.GraphIndex = (uint)graphIndex;
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();
}
Profiler.EndSample();
var sides = new Dictionary <Int2, TriangleMeshNode>();
for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
{
sides[new Int2(triangles[i + 0], triangles[i + 1])] = nodes[j];
sides[new Int2(triangles[i + 1], triangles[i + 2])] = nodes[j];
sides[new Int2(triangles[i + 2], triangles[i + 0])] = nodes[j];
}
Profiler.BeginSample("Connecting Nodes");
var connections = new List <MeshNode> ();
var connectionCosts = new List <uint> ();
for (int i = 0, j = 0; i < triangles.Length; j += 1, i += 3)
{
connections.Clear();
connectionCosts.Clear();
TriangleMeshNode node = nodes[j];
for (int q = 0; q < 3; q++)
{
TriangleMeshNode other;
if (sides.TryGetValue(new Int2(triangles[i + ((q + 1) % 3)], triangles[i + q]), out other))
{
connections.Add(other);
connectionCosts.Add((uint)(node.position - other.position).costMagnitude);
}
}
node.connections = connections.ToArray();
node.connectionCosts = connectionCosts.ToArray();
}
Profiler.EndSample();
Profiler.BeginSample("Rebuilding BBTree");
RebuildBBTree(this);
Profiler.EndSample();
#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");
}