Esempio n. 1
0
        /** Builds a polygon mesh from a contour set.
         * \param nvp Maximum allowed vertices per polygon. \note Currently locked to 3
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
                //mesh = new VoxelMesh ();
                //yield break;
                //return;
            }

            //int[] vflags = new int[maxVertices];

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];

            //int[] regs = new int[maxTris];

            //int[] areas = new int[maxTris];

            Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int));
            //for (int i=0;i<polys.Length;i++) {
            //	polys[i] = 0xff;
            //}

            //int[] nexVert = new int[maxVertices];

            //int[] firstVert = new int[VERTEX_BUCKET_COUNT];

            int[] indices = new int[maxVertsPerCont];

            int[] tris = new int[maxVertsPerCont * 3];

            //ushort[] polys

            int vertexIndex = 0;
            int polyIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                //Skip null contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                //yield return (GameObject.FindObjectOfType (typeof(MonoBehaviour)) as MonoBehaviour).StartCoroutine (
                //Triangulate (cont.nverts, cont.verts, indices, tris);
                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                /*if (ntris > cont.nverts-2) {
                 *      Debug.LogError (ntris + " "+cont.nverts+" "+cont.verts.Length+" "+(cont.nverts-2));
                 * }
                 *
                 * if (ntris > maxVertsPerCont) {
                 *      Debug.LogError (ntris*3 + " "+maxVertsPerCont);
                 * }
                 *
                 * int tmp = polyIndex;
                 *
                 * Debug.Log (maxTris + " "+polyIndex+" "+polys.Length+" "+ntris+" "+(ntris*3) + " " + cont.nverts);*/
                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                /*int tmp2 = polyIndex;
                 * if (tmp+ntris*3 != tmp2) {
                 *      Debug.LogWarning (tmp+" "+(tmp+ntris*3)+" "+tmp2+" "+ntris*3);
                 * }*/

                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();
            //yield break;
            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris = new int[polyIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));
            //for (int i=0;i<polyIndex;i++) {
            //	trimmedTris[i] = polys[i];
            //}


            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;

            /*for (int i=0;i<mesh.tris.Length/3;i++) {
             *
             *      int p = i*3;
             *
             *      int p1 = mesh.tris[p];
             *      int p2 = mesh.tris[p+1];
             *      int p3 = mesh.tris[p+2];
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *
             * }*/

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Esempio n. 2
0
		/** Builds a polygon mesh from a contour set.
		 *
		 * \param cset contour set to build a mesh from.
		 * \param nvp Maximum allowed vertices per polygon. \warning Currently locked to 3.
		 * \param mesh Results will be written to this mesh.
		 */
		public void BuildPolyMesh (VoxelContourSet cset, int nvp, out VoxelMesh mesh) {
			
			AstarProfiler.StartProfile ("Build Poly Mesh");
			
			nvp = 3;
			
			int maxVertices = 0;
			int maxTris = 0;
			int maxVertsPerCont = 0;
			
			for (int i = 0; i < cset.conts.Count; i++) {
				
				// Skip null contours.
				if (cset.conts[i].nverts < 3) continue;
				
				maxVertices += cset.conts[i].nverts;
				maxTris += cset.conts[i].nverts - 2;
				maxVertsPerCont = AstarMath.Max (maxVertsPerCont, cset.conts[i].nverts);
			}
			
			if (maxVertices >= 65534)
			{
				Debug.LogWarning ("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
				//mesh = new VoxelMesh ();
				//yield break;
				//return;
			}
			
			/** \todo Could be cached to avoid allocations */
			Int3[] verts = new Int3[maxVertices];
			/** \todo Could be cached to avoid allocations */
			int[] polys = new int[maxTris*nvp];
			
			Pathfinding.Util.Memory.MemSet<int> (polys, 0xff, sizeof(int));
			
			int[] indices = new int[maxVertsPerCont];
			
			int[] tris = new int[maxVertsPerCont*3];
			
			int vertexIndex = 0;
			int polyIndex = 0;
			
			for (int i=0;i<cset.conts.Count;i++) {
				
				VoxelContour cont = cset.conts[i];
				
				//Skip null contours
				if (cont.nverts < 3) {
					continue;
				}
				
				for (int j=0; j < cont.nverts;j++) {
					indices[j] = j;
					cont.verts[j*4+2] /= voxelArea.width;
				}
				
				int ntris = Triangulate (cont.nverts, cont.verts, ref indices, ref tris);
				
				int startIndex = vertexIndex;
				for (int j=0;j<ntris*3; polyIndex++, j++) {
					//@Error sometimes
					polys[polyIndex] = tris[j]+startIndex;
				}
				
				for (int j=0;j<cont.nverts; vertexIndex++, j++) {
					verts[vertexIndex] = new Int3(cont.verts[j*4],cont.verts[j*4+1],cont.verts[j*4+2]);
				}
			}
			
			mesh = new VoxelMesh ();
			//yield break;
			Int3[] trimmedVerts = new Int3[vertexIndex];
			for (int i=0;i<vertexIndex;i++) {
				trimmedVerts[i] = verts[i];
			}
			
			int[] trimmedTris = new int[polyIndex];
			
			System.Buffer.BlockCopy (polys, 0, trimmedTris, 0, polyIndex*sizeof(int));
			
			mesh.verts = trimmedVerts;
			mesh.tris = trimmedTris;
			
			// Some debugging
			/*for (int i=0;i<mesh.tris.Length/3;i++) {
				
				int p = i*3;
				
				int p1 = mesh.tris[p];
				int p2 = mesh.tris[p+1];
				int p3 = mesh.tris[p+2];
				
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
	
				//Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
				//Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
				//Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
	
			}*/
			
			AstarProfiler.EndProfile ("Build Poly Mesh");
			
		}
Esempio n. 3
0
		/** Builds a polygon mesh from a contour set.
		 * \param nvp Maximum allowed vertices per polygon. \note Currently locked to 3
		 */
		public void BuildPolyMesh (VoxelContourSet cset, int nvp, out VoxelMesh mesh) {
			
			AstarProfiler.StartProfile ("Build Poly Mesh");
			
			nvp = 3;
			
			int maxVertices = 0;
			int maxTris = 0;
			int maxVertsPerCont = 0;
			
			for (int i = 0; i < cset.conts.Count; i++) {
				
				// Skip null contours.
				if (cset.conts[i].nverts < 3) continue;
				
				maxVertices += cset.conts[i].nverts;
				maxTris += cset.conts[i].nverts - 2;
				maxVertsPerCont = AstarMath.Max (maxVertsPerCont, cset.conts[i].nverts);
			}
			
			if (maxVertices >= 65534)
			{
				Debug.LogWarning ("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
				//mesh = new VoxelMesh ();
				//yield break;
				//return;
			}
			
			//int[] vflags = new int[maxVertices];
			
			/** \todo Could be cached to avoid allocations */
			Int3[] verts = new Int3[maxVertices];
			/** \todo Could be cached to avoid allocations */
			int[] polys = new int[maxTris*nvp];
			
			//int[] regs = new int[maxTris];
			
			//int[] areas = new int[maxTris];
			
			Pathfinding.Util.Memory.MemSet<int> (polys, 0xff, sizeof(int));
			//for (int i=0;i<polys.Length;i++) {
			//	polys[i] = 0xff;
			//}
			
			//int[] nexVert = new int[maxVertices];
			
			//int[] firstVert = new int[VERTEX_BUCKET_COUNT];
			
			int[] indices = new int[maxVertsPerCont];
			
			int[] tris = new int[maxVertsPerCont*3];
			
			//ushort[] polys 
			
			int vertexIndex = 0;
			int polyIndex = 0;
			
			for (int i=0;i<cset.conts.Count;i++) {
				
				VoxelContour cont = cset.conts[i];
				
				//Skip null contours
				if (cont.nverts < 3) {
					continue;
				}
				
				for (int j=0; j < cont.nverts;j++) {
					indices[j] = j;
					cont.verts[j*4+2] /= voxelArea.width;
				}
				
				//yield return (GameObject.FindObjectOfType (typeof(MonoBehaviour)) as MonoBehaviour).StartCoroutine (
				//Triangulate (cont.nverts, cont.verts, indices, tris);
				int ntris = Triangulate (cont.nverts, cont.verts, ref indices, ref tris);
				
				/*if (ntris > cont.nverts-2) {
					Debug.LogError (ntris + " "+cont.nverts+" "+cont.verts.Length+" "+(cont.nverts-2));
				}
				
				if (ntris > maxVertsPerCont) {
					Debug.LogError (ntris*3 + " "+maxVertsPerCont);
				}
				
				int tmp = polyIndex;
				
				Debug.Log (maxTris + " "+polyIndex+" "+polys.Length+" "+ntris+" "+(ntris*3) + " " + cont.nverts);*/
				int startIndex = vertexIndex;
				for (int j=0;j<ntris*3; polyIndex++, j++) {
					//@Error sometimes
					polys[polyIndex] = tris[j]+startIndex;
				}
				
				/*int tmp2 = polyIndex;
				if (tmp+ntris*3 != tmp2) {
					Debug.LogWarning (tmp+" "+(tmp+ntris*3)+" "+tmp2+" "+ntris*3);
				}*/
				
				for (int j=0;j<cont.nverts; vertexIndex++, j++) {
					verts[vertexIndex] = new Int3(cont.verts[j*4],cont.verts[j*4+1],cont.verts[j*4+2]);
				}
			}
			
			mesh = new VoxelMesh ();
			//yield break;
			Int3[] trimmedVerts = new Int3[vertexIndex];
			for (int i=0;i<vertexIndex;i++) {
				trimmedVerts[i] = verts[i];
			}
			
			int[] trimmedTris = new int[polyIndex];
			
			System.Buffer.BlockCopy (polys, 0, trimmedTris, 0, polyIndex*sizeof(int));
			//for (int i=0;i<polyIndex;i++) {
			//	trimmedTris[i] = polys[i];
			//}
			
			
			mesh.verts = trimmedVerts;
			mesh.tris = trimmedTris;
			
			/*for (int i=0;i<mesh.tris.Length/3;i++) {
				
				int p = i*3;
				
				int p1 = mesh.tris[p];
				int p2 = mesh.tris[p+1];
				int p3 = mesh.tris[p+2];
				
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
				//Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
	
				//Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
				//Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
				//Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
	
			}*/
			
			AstarProfiler.EndProfile ("Build Poly Mesh");
			
		}
Esempio n. 4
0
		/** Create a tile at tile index \a x , \a z from the mesh.
		 * \warning This implementation is not thread safe. It uses cached variables to improve performance
		 */
		NavmeshTile CreateTile (Voxelize vox, VoxelMesh mesh, int x, int z) {
			
			if (mesh.tris == null) throw new System.ArgumentNullException ("The mesh must be valid. tris is null.");
			if (mesh.verts == null) throw new System.ArgumentNullException ("The mesh must be valid. verts is null.");
			
			//Create a new navmesh tile and assign its settings
			NavmeshTile tile = new NavmeshTile();
			
			tile.x = x;
			tile.z = z;
			tile.w = 1;
			tile.d = 1;
			tile.tris = mesh.tris;
			tile.verts = mesh.verts;
			tile.bbTree = new BBTree(tile);
			
			if (tile.tris.Length % 3 != 0) throw new System.ArgumentException ("Indices array's length must be a multiple of 3 (mesh.tris)");
			
			if (tile.verts.Length >= VertexIndexMask) throw new System.ArgumentException ("Too many vertices per tile (more than "+VertexIndexMask+")." +
				"\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector");
			
			//Dictionary<Int3, int> firstVerts = new Dictionary<Int3, int> ();
			Dictionary<Int3, int> firstVerts = cachedInt3_int_dict;
			firstVerts.Clear();
			
			int[] compressedPointers = new int[tile.verts.Length];
			
			int count = 0;
			for (int i=0;i<tile.verts.Length;i++) {
				try {
					firstVerts.Add (tile.verts[i], count);
					compressedPointers[i] = count;
					tile.verts[count] = tile.verts[i];
					count++;
				} catch {
					//There are some cases, rare but still there, that vertices are identical
					compressedPointers[i] = firstVerts[tile.verts[i]];
				}
			}
			
			for (int i=0;i<tile.tris.Length;i++) {
				tile.tris[i] = compressedPointers[tile.tris[i]];
			}
			
			Int3[] compressed = new Int3[count];
			for (int i=0;i<count;i++) compressed[i] = tile.verts[i];
			
			tile.verts = compressed;
			
			TriangleMeshNode[] nodes = new TriangleMeshNode[tile.tris.Length/3];
			tile.nodes = nodes;
			
			//Here we are faking a new graph
			//The tile is not added to any graphs yet, but to get the position querys from the nodes
			//to work correctly (not throw exceptions because the tile is not calculated) we fake a new graph
			//and direct the position queries directly to the tile
			int graphIndex = AstarPath.active.astarData.graphs.Length;
			
			TriangleMeshNode.SetNavmeshHolder (graphIndex, tile);
			
			//This index will be ORed to the triangle indices
			int tileIndex = x + z*tileXCount;
			tileIndex <<= TileIndexOffset;
			
			//Create nodes and assign triangle indices
			for (int i=0;i<nodes.Length;i++) {
				TriangleMeshNode node = new TriangleMeshNode(active);
				nodes[i] = node;
				node.GraphIndex = (uint)graphIndex;
				node.v0 = tile.tris[i*3+0] | tileIndex;
				node.v1 = tile.tris[i*3+1] | tileIndex;
				node.v2 = tile.tris[i*3+2] | tileIndex;
				
				//Degenerate triangles might ocurr, but they will not cause any large troubles anymore
				//if (Polygon.IsColinear (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
				//	Debug.Log ("COLINEAR!!!!!!");
				//}
				
				//Make sure the triangle is clockwise
				if (!Polygon.IsClockwise (node.GetVertex(0), node.GetVertex(1), node.GetVertex(2))) {
					int tmp = node.v0;
					node.v0 = node.v2;
					node.v2 = tmp;
				}
				
				node.Walkable = true;
				node.Penalty = initialPenalty;
				node.UpdatePositionFromVertices();
				tile.bbTree.Insert (node);
			}
			
			CreateNodeConnections (tile.nodes);
			
			//Remove the fake graph
			TriangleMeshNode.SetNavmeshHolder (graphIndex, null);
			
			return tile;
		}
Esempio n. 5
0
        /** Builds a polygon mesh from a contour set.
         *
         * \param cset contour set to build a mesh from.
         * \param nvp Maximum allowed vertices per polygon. \warning Currently locked to 3.
         * \param mesh Results will be written to this mesh.
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = System.Math.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            Int3[] verts = ArrayPool <Int3> .Claim(maxVertices);

            int[] polys = ArrayPool <int> .Claim(maxTris *nvp);

            int[] areas = ArrayPool <int> .Claim(maxTris);

            Memory.MemSet <int>(polys, 0xff, sizeof(int));

            int[] indices = ArrayPool <int> .Claim(maxVertsPerCont);

            int[] tris = ArrayPool <int> .Claim(maxVertsPerCont *3);

            int vertexIndex = 0;
            int polyIndex   = 0;
            int areaIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                // Skip degenerate contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j] = j;
                    // Convert the z coordinate from the form z*voxelArea.width which is used in other places for performance
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                // Triangulate the contour
                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                // Assign the correct vertex indices
                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                // Mark all triangles generated by this contour
                // as having the area cont.area
                for (int j = 0; j < ntris; areaIndex++, j++)
                {
                    areas[areaIndex] = cont.area;
                }

                // Copy the vertex positions
                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh {
                verts = Memory.ShrinkArray(verts, vertexIndex),
                tris  = Memory.ShrinkArray(polys, polyIndex),
                areas = Memory.ShrinkArray(areas, areaIndex)
            };

            ArrayPool <Int3> .Release(ref verts);

            ArrayPool <int> .Release(ref polys);

            ArrayPool <int> .Release(ref areas);

            ArrayPool <int> .Release(ref indices);

            ArrayPool <int> .Release(ref tris);

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Esempio n. 6
0
        /** Builds a polygon mesh from a contour set.
         *
         * \param cset contour set to build a mesh from.
         * \param nvp Maximum allowed vertices per polygon. \warning Currently locked to 3.
         * \param mesh Results will be written to this mesh.
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
                //mesh = new VoxelMesh ();
                //yield break;
                //return;
            }

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];

            Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int));

            int[] indices = new int[maxVertsPerCont];

            int[] tris = new int[maxVertsPerCont * 3];

            int vertexIndex = 0;
            int polyIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                //Skip null contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();
            //yield break;
            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris = new int[polyIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));

            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;

            // Some debugging

            /*for (int i=0;i<mesh.tris.Length/3;i++) {
             *
             *      int p = i*3;
             *
             *      int p1 = mesh.tris[p];
             *      int p2 = mesh.tris[p+1];
             *      int p3 = mesh.tris[p+2];
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *
             * }*/

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Esempio n. 7
0
        /** Builds a polygon mesh from a contour set.
         *
         * \param cset contour set to build a mesh from.
         * \param nvp Maximum allowed vertices per polygon. \warning Currently locked to 3.
         * \param mesh Results will be written to this mesh.
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = System.Math.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
            }

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];
            int[] areas = new int[maxTris];

            Pathfinding.Util.Memory.MemSet <int>(polys, 0xff, sizeof(int));

            int[] indices = new int[maxVertsPerCont];
            int[] tris    = new int[maxVertsPerCont * 3];

            int vertexIndex = 0;
            int polyIndex   = 0;
            int areaIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                // Skip degenerate contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                // Triangulate the contour
                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                // Assign the correct vertex indices
                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                // Mark all triangles generated by this contour
                // as having the area cont.area
                for (int j = 0; j < ntris; areaIndex++, j++)
                {
                    areas[areaIndex] = cont.area;
                }

                // Copy the vertex positions
                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();

            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris  = new int[polyIndex];
            int[] trimmedAreas = new int[areaIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));
            System.Buffer.BlockCopy(areas, 0, trimmedAreas, 0, areaIndex * sizeof(int));

            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;
            mesh.areas = trimmedAreas;


            AstarProfiler.EndProfile("Build Poly Mesh");
        }
Esempio n. 8
0
 private RecastGraph.NavmeshTile CreateTile(Voxelize vox, VoxelMesh mesh, int x, int z)
 {
     if (mesh.tris == null)
     {
         throw new ArgumentNullException("mesh.tris");
     }
     if (mesh.verts == null)
     {
         throw new ArgumentNullException("mesh.verts");
     }
     RecastGraph.NavmeshTile navmeshTile = new RecastGraph.NavmeshTile();
     navmeshTile.x = x;
     navmeshTile.z = z;
     navmeshTile.w = 1;
     navmeshTile.d = 1;
     navmeshTile.tris = mesh.tris;
     navmeshTile.verts = mesh.verts;
     navmeshTile.bbTree = new BBTree();
     if (navmeshTile.tris.Length % 3 != 0)
     {
         throw new ArgumentException("Indices array's length must be a multiple of 3 (mesh.tris)");
     }
     if (navmeshTile.verts.Length >= 4095)
     {
         throw new ArgumentException("Too many vertices per tile (more than " + 4095 + ").\nTry enabling ASTAR_RECAST_LARGER_TILES under the 'Optimizations' tab in the A* Inspector");
     }
     Dictionary<Int3, int> dictionary = this.cachedInt3_int_dict;
     dictionary.Clear();
     int[] array = new int[navmeshTile.verts.Length];
     int num = 0;
     for (int i = 0; i < navmeshTile.verts.Length; i++)
     {
         if (!dictionary.ContainsKey(navmeshTile.verts[i]))
         {
             dictionary.Add(navmeshTile.verts[i], num);
             array[i] = num;
             navmeshTile.verts[num] = navmeshTile.verts[i];
             num++;
         }
         else
         {
             array[i] = dictionary[navmeshTile.verts[i]];
         }
     }
     for (int j = 0; j < navmeshTile.tris.Length; j++)
     {
         navmeshTile.tris[j] = array[navmeshTile.tris[j]];
     }
     Int3[] array2 = new Int3[num];
     for (int k = 0; k < num; k++)
     {
         array2[k] = navmeshTile.verts[k];
     }
     navmeshTile.verts = array2;
     TriangleMeshNode[] array3 = new TriangleMeshNode[navmeshTile.tris.Length / 3];
     navmeshTile.nodes = array3;
     int graphIndex = AstarPath.active.astarData.graphs.Length;
     TriangleMeshNode.SetNavmeshHolder(graphIndex, navmeshTile);
     int num2 = x + z * this.tileXCount;
     num2 <<= 12;
     for (int l = 0; l < array3.Length; l++)
     {
         TriangleMeshNode triangleMeshNode = new TriangleMeshNode(this.active);
         array3[l] = triangleMeshNode;
         triangleMeshNode.GraphIndex = (uint)graphIndex;
         triangleMeshNode.v0 = (navmeshTile.tris[l * 3] | num2);
         triangleMeshNode.v1 = (navmeshTile.tris[l * 3 + 1] | num2);
         triangleMeshNode.v2 = (navmeshTile.tris[l * 3 + 2] | num2);
         if (!Polygon.IsClockwise(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)))
         {
             int v = triangleMeshNode.v0;
             triangleMeshNode.v0 = triangleMeshNode.v2;
             triangleMeshNode.v2 = v;
         }
         triangleMeshNode.Walkable = true;
         triangleMeshNode.Penalty = this.initialPenalty;
         triangleMeshNode.UpdatePositionFromVertices();
     }
     navmeshTile.bbTree.RebuildFrom(array3);
     this.CreateNodeConnections(navmeshTile.nodes);
     TriangleMeshNode.SetNavmeshHolder(graphIndex, null);
     return navmeshTile;
 }