CreateNodes() public method

public CreateNodes ( int number ) : void
number int
return void
		/** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
		public static void GenerateNodes (NavGraph graph, Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices) {
			
			if (!(graph is INavmesh)) {
				Debug.LogError ("The specified graph does not implement interface 'INavmesh'");
				originalVertices = vectorVertices;
				vertices = new Int3[0];
				graph.nodes = graph.CreateNodes (0);
				return;
			}
			
			if (vectorVertices.Length == 0 || triangles.Length == 0) {
				originalVertices = vectorVertices;
				vertices = new Int3[0];
				graph.nodes = graph.CreateNodes (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)graph.matrix.MultiplyPoint (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] = vertices[i];//vectorVertices[newVertices[i]];
			}
			
			Node[] nodes = graph.CreateNodes (triangles.Length/3);//new Node[triangles.Length/3];
			graph.nodes = nodes;
			for (int i=0;i<nodes.Length;i++) {
				
				MeshNode node = (MeshNode)nodes[i];//new MeshNode ();
				node.walkable = true;
				
				node.position = (vertices[triangles[i*3]] + vertices[triangles[i*3+1]] + vertices[triangles[i*3+2]])/3F;
				
				node.v1 = triangles[i*3];
				node.v2 = triangles[i*3+1];
				node.v3 = triangles[i*3+2];
				
				if (!Polygon.IsClockwise (vertices[node.v1],vertices[node.v2],vertices[node.v3])) {
					//Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
					//Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.red);
					//Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.red);
					
					int tmp = node.v1;
					node.v1 = node.v3;
					node.v3 = tmp;
				}
				
				if (Polygon.IsColinear (vertices[node.v1],vertices[node.v2],vertices[node.v3])) {
					Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
					Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.red);
					Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.red);
				}
				
				nodes[i] = node;
			}
			
			List<Node> connections = new List<Node> ();
			List<int> connectionCosts = new List<int> ();
			
			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]);
				
				Node 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 (vertices[triangles[x]],vertices[triangles[x+1]],Color.red);
						Debug.DrawLine (vertices[triangles[x]],vertices[triangles[x+2]],Color.red);
						Debug.DrawLine (vertices[triangles[x+2]],vertices[triangles[x+1]],Color.red);
						
					}
					
					if (count == 2) {
						Node other = nodes[x/3];
						connections.Add (other);
						connectionCosts.Add (Mathf.RoundToInt ((node.position-other.position).magnitude));
					}
				}
				
				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 (graph);
			
			//Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
		}
示例#2
0
        /** Generates a navmesh. Based on the supplied vertices and triangles. Memory usage is about O(n) */
        public static void GenerateNodes(NavGraph graph, Vector3[] vectorVertices, int[] triangles, out Vector3[] originalVertices, out Int3[] vertices)
        {
            if (!(graph is INavmesh))
            {
                Debug.LogError("The specified graph does not implement interface 'INavmesh'");
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                graph.nodes      = graph.CreateNodes(0);
                return;
            }

            if (vectorVertices.Length == 0 || triangles.Length == 0)
            {
                originalVertices = vectorVertices;
                vertices         = new Int3[0];
                graph.nodes      = graph.CreateNodes(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)graph.matrix.MultiplyPoint(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++)
            {
                originalVertices[i] = vectorVertices[newVertices[i]];
                vertices[i]         = totalIntVertices[newVertices[i]];        //(Int3)graph.matrix.MultiplyPoint (vectorVertices[i]);
            }

            Node[] nodes = graph.CreateNodes(triangles.Length / 3);           //new Node[triangles.Length/3];
            graph.nodes = nodes;
            for (int i = 0; i < nodes.Length; i++)
            {
                MeshNode node = (MeshNode)nodes[i];                //new MeshNode ();
                node.walkable = true;

                node.position = (vertices[triangles[i * 3]] + vertices[triangles[i * 3 + 1]] + vertices[triangles[i * 3 + 2]]) / 3F;

                node.v1 = triangles[i * 3];
                node.v2 = triangles[i * 3 + 1];
                node.v3 = triangles[i * 3 + 2];

                if (!Polygon.IsClockwise(vertices[node.v1], vertices[node.v2], vertices[node.v3]))
                {
                    //Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.red);
                    //Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.red);
                    //Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.red);

                    int tmp = node.v1;
                    node.v1 = node.v3;
                    node.v3 = tmp;
                }

                if (Polygon.IsColinear(vertices[node.v1], vertices[node.v2], vertices[node.v3]))
                {
                    Debug.DrawLine(vertices[node.v1], vertices[node.v2], Color.red);
                    Debug.DrawLine(vertices[node.v2], vertices[node.v3], Color.red);
                    Debug.DrawLine(vertices[node.v3], vertices[node.v1], Color.red);
                }

                nodes[i] = node;
            }

            List <Node> connections     = new List <Node> ();
            List <int>  connectionCosts = new List <int> ();

            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]);

                Node 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(vertices[triangles[x]], vertices[triangles[x + 1]], Color.red);
                        Debug.DrawLine(vertices[triangles[x]], vertices[triangles[x + 2]], Color.red);
                        Debug.DrawLine(vertices[triangles[x + 2]], vertices[triangles[x + 1]], Color.red);
                    }

                    if (count == 2)
                    {
                        Node other = nodes[x / 3];
                        connections.Add(other);
                        connectionCosts.Add(Mathf.RoundToInt((node.position - other.position).magnitude));
                    }
                }

                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(graph);

            //Debug.Log ("Graph Generation - NavMesh - Time to compute graph "+((Time.realtimeSinceStartup-startTime)*1000F).ToString ("0")+"ms");
        }