コード例 #1
0
 /** Releases contents of a contour set to caches */
 static void ReleaseContours(VoxelContourSet cset)
 {
     for (int i = 0; i < cset.conts.Count; i++)
     {
         VoxelContour cont = cset.conts[i];
         ReleaseIntArr(cont.verts);
         ReleaseIntArr(cont.rverts);
     }
     cset.conts = null;
 }
コード例 #2
0
ファイル: VoxelContour.cs プロジェクト: PerryW11/Androidema
        /// <summary>Releases contents of a contour set to caches</summary>
        static void ReleaseContours(VoxelContourSet cset)
        {
            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];
                Pathfinding.Util.ArrayPool <int> .Release(ref cont.verts);

                Pathfinding.Util.ArrayPool <int> .Release(ref cont.rverts);
            }
            cset.conts = null;
        }
コード例 #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");
        }
コード例 #4
0
ファイル: VoxelContour.cs プロジェクト: PerryW11/Androidema
        public void BuildContours(float maxError, int maxEdgeLength, VoxelContourSet cset, int buildFlags)
        {
            AstarProfiler.StartProfile("Build Contours");

            AstarProfiler.StartProfile("- Init");
            int w = voxelArea.width;
            int d = voxelArea.depth;

            int wd = w * d;

            //cset.bounds = voxelArea.bounds;

            int maxContours = Mathf.Max(8 /*Max Regions*/, 8);


            //cset.conts = new VoxelContour[maxContours];
            List <VoxelContour> contours = new List <VoxelContour>(maxContours);

            AstarProfiler.EndProfile("- Init");
            AstarProfiler.StartProfile("- Mark Boundaries");

            //cset.nconts = 0;

            //NOTE: This array may contain any data, but since we explicitly set all data in it before we use it, it's OK.
            ushort[] flags = voxelArea.tmpUShortArr;
            if (flags.Length < voxelArea.compactSpanCount)
            {
                flags = voxelArea.tmpUShortArr = new ushort[voxelArea.compactSpanCount];
            }

            // Mark boundaries. (@?)
            for (int z = 0; z < wd; z += voxelArea.width)
            {
                for (int x = 0; x < voxelArea.width; x++)
                {
                    CompactVoxelCell c = voxelArea.compactCells[x + z];

                    for (int i = (int)c.index, ci = (int)(c.index + c.count); i < ci; i++)
                    {
                        ushort           res = 0;
                        CompactVoxelSpan s   = voxelArea.compactSpans[i];

                        if (s.reg == 0 || (s.reg & BorderReg) == BorderReg)
                        {
                            flags[i] = 0;
                            continue;
                        }

                        for (int dir = 0; dir < 4; dir++)
                        {
                            int r = 0;

                            if (s.GetConnection(dir) != NotConnected)
                            {
                                int nx = x + voxelArea.DirectionX[dir];
                                int nz = z + voxelArea.DirectionZ[dir];

                                int ni = (int)voxelArea.compactCells[nx + nz].index + s.GetConnection(dir);
                                r = voxelArea.compactSpans[ni].reg;
                            }

                            //@TODO - Why isn't this inside the previous IF
                            if (r == s.reg)
                            {
                                res |= (ushort)(1 << dir);
                            }
                        }

                        //Inverse, mark non connected edges.
                        flags[i] = (ushort)(res ^ 0xf);
                    }
                }
            }

            AstarProfiler.EndProfile("- Mark Boundaries");

            AstarProfiler.StartProfile("- Simplify Contours");
            List <int> verts = Pathfinding.Util.ListPool <int> .Claim(256);          //new List<int> (256);

            List <int> simplified = Pathfinding.Util.ListPool <int> .Claim(64);      //new List<int> (64);

            for (int z = 0; z < wd; z += voxelArea.width)
            {
                for (int x = 0; x < voxelArea.width; x++)
                {
                    CompactVoxelCell c = voxelArea.compactCells[x + z];

                    for (int i = (int)c.index, ci = (int)(c.index + c.count); i < ci; i++)
                    {
                        //CompactVoxelSpan s = voxelArea.compactSpans[i];

                        if (flags[i] == 0 || flags[i] == 0xf)
                        {
                            flags[i] = 0;
                            continue;
                        }

                        int reg = voxelArea.compactSpans[i].reg;

                        if (reg == 0 || (reg & BorderReg) == BorderReg)
                        {
                            continue;
                        }

                        int area = voxelArea.areaTypes[i];

                        verts.Clear();
                        simplified.Clear();

                        WalkContour(x, z, i, flags, verts);

                        SimplifyContour(verts, simplified, maxError, maxEdgeLength, buildFlags);
                        RemoveDegenerateSegments(simplified);

                        VoxelContour contour = new VoxelContour();
                        contour.verts = Pathfinding.Util.ArrayPool <int> .Claim(simplified.Count);                       //simplified.ToArray ();

                        for (int j = 0; j < simplified.Count; j++)
                        {
                            contour.verts[j] = simplified[j];
                        }
#if ASTAR_RECAST_INCLUDE_RAW_VERTEX_CONTOUR
                        //Not used at the moment, just debug stuff
                        contour.rverts = ClaimIntArr(verts.Count);
                        for (int j = 0; j < verts.Count; j++)
                        {
                            contour.rverts[j] = verts[j];
                        }
#endif
                        contour.nverts = simplified.Count / 4;
                        contour.reg    = reg;
                        contour.area   = area;

                        contours.Add(contour);

#if ASTARDEBUG
                        for (int q = 0, j = (simplified.Count / 4) - 1; q < (simplified.Count / 4); j = q, q++)
                        {
                            int i4 = q * 4;
                            int j4 = j * 4;

                            Vector3 p1 = Vector3.Scale(
                                new Vector3(
                                    simplified[i4 + 0],
                                    simplified[i4 + 1],
                                    (simplified[i4 + 2] / (float)voxelArea.width)
                                    ),
                                cellScale)
                                         + voxelOffset;

                            Vector3 p2 = Vector3.Scale(
                                new Vector3(
                                    simplified[j4 + 0],
                                    simplified[j4 + 1],
                                    (simplified[j4 + 2] / (float)voxelArea.width)
                                    )
                                , cellScale)
                                         + voxelOffset;


                            if (CalcAreaOfPolygon2D(contour.verts, contour.nverts) > 0)
                            {
                                Debug.DrawLine(p1, p2, AstarMath.IntToColor(reg, 0.5F));
                            }
                            else
                            {
                                Debug.DrawLine(p1, p2, Color.red);
                            }
                        }
#endif
                    }
                }
            }

            Pathfinding.Util.ListPool <int> .Release(ref verts);

            Pathfinding.Util.ListPool <int> .Release(ref simplified);

            AstarProfiler.EndProfile("- Simplify Contours");

            AstarProfiler.StartProfile("- Fix Contours");

            // Check and merge droppings.
            // Sometimes the previous algorithms can fail and create several contours
            // per area. This pass will try to merge the holes into the main region.
            for (int i = 0; i < contours.Count; i++)
            {
                VoxelContour cont = contours[i];
                // Check if the contour is would backwards.
                if (CalcAreaOfPolygon2D(cont.verts, cont.nverts) < 0)
                {
                    // Find another contour which has the same region ID.
                    int mergeIdx = -1;
                    for (int j = 0; j < contours.Count; j++)
                    {
                        if (i == j)
                        {
                            continue;
                        }
                        if (contours[j].nverts > 0 && contours[j].reg == cont.reg)
                        {
                            // Make sure the polygon is correctly oriented.
                            if (CalcAreaOfPolygon2D(contours[j].verts, contours[j].nverts) > 0)
                            {
                                mergeIdx = j;
                                break;
                            }
                        }
                    }
                    if (mergeIdx == -1)
                    {
                        Debug.LogError("rcBuildContours: Could not find merge target for bad contour " + i + ".");
                    }
                    else
                    {
                        // Debugging
                        // Debug.LogWarning ("Fixing contour");

                        VoxelContour mcont = contours[mergeIdx];
                        // Merge by closest points.
                        int ia = 0, ib = 0;
                        GetClosestIndices(mcont.verts, mcont.nverts, cont.verts, cont.nverts, ref ia, ref ib);

                        if (ia == -1 || ib == -1)
                        {
                            Debug.LogWarning("rcBuildContours: Failed to find merge points for " + i + " and " + mergeIdx + ".");
                            continue;
                        }

#if ASTARDEBUG
                        int p4  = ia * 4;
                        int p42 = ib * 4;

                        Vector3 p12 = Vector3.Scale(
                            new Vector3(
                                mcont.verts[p4 + 0],
                                mcont.verts[p4 + 1],
                                (mcont.verts[p4 + 2] / (float)voxelArea.width)
                                ),
                            cellScale)
                                      + voxelOffset;

                        Vector3 p22 = Vector3.Scale(
                            new Vector3(
                                cont.verts[p42 + 0],
                                cont.verts[p42 + 1],
                                (cont.verts[p42 + 2] / (float)voxelArea.width)
                                )
                            , cellScale)
                                      + voxelOffset;

                        Debug.DrawLine(p12, p22, Color.green);
#endif

                        if (!MergeContours(ref mcont, ref cont, ia, ib))
                        {
                            Debug.LogWarning("rcBuildContours: Failed to merge contours " + i + " and " + mergeIdx + ".");
                            continue;
                        }

                        contours[mergeIdx] = mcont;
                        contours[i]        = cont;

#if ASTARDEBUG
                        Debug.Log(mcont.nverts);

                        for (int q = 0, j = (mcont.nverts) - 1; q < (mcont.nverts); j = q, q++)
                        {
                            int i4 = q * 4;
                            int j4 = j * 4;

                            Vector3 p1 = Vector3.Scale(
                                new Vector3(
                                    mcont.verts[i4 + 0],
                                    mcont.verts[i4 + 1],
                                    (mcont.verts[i4 + 2] / (float)voxelArea.width)
                                    ),
                                cellScale)
                                         + voxelOffset;

                            Vector3 p2 = Vector3.Scale(
                                new Vector3(
                                    mcont.verts[j4 + 0],
                                    mcont.verts[j4 + 1],
                                    (mcont.verts[j4 + 2] / (float)voxelArea.width)
                                    )
                                , cellScale)
                                         + voxelOffset;

                            Debug.DrawLine(p1, p2, Color.red);
                            //}
                        }
#endif
                    }
                }
            }

            cset.conts = contours;

            AstarProfiler.EndProfile("- Fix Contours");

            AstarProfiler.EndProfile("Build Contours");
        }
コード例 #5
0
ファイル: VoxelMesh.cs プロジェクト: Gapti/ClashOfClanRIP
		/** 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");
			
		}
コード例 #6
0
ファイル: VoxelMesh.cs プロジェクト: SpacesAdventure/Kio-2
		/** 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");
			
		}
コード例 #7
0
		protected void BuildTileMesh (Voxelize vox, int x, int z) {
			
			AstarProfiler.StartProfile ("Build Tile");
			
			AstarProfiler.StartProfile ("Init");
			
			//World size of tile
			float tcsx = tileSizeX*cellSize;
			float tcsz = tileSizeZ*cellSize;
			
			int voxelCharacterRadius = Mathf.CeilToInt (characterRadius/cellSize);			
			
			Vector3 forcedBoundsMin = forcedBounds.min;
			Vector3 forcedBoundsMax = forcedBounds.max;
			
			Bounds bounds = new Bounds ();
			bounds.SetMinMax(new Vector3 (x*tcsx, 0, z*tcsz) + forcedBoundsMin,
						new Vector3 ((x+1)*tcsx + forcedBoundsMin.x, forcedBoundsMax.y, (z+1)*tcsz + forcedBoundsMin.z)
				);
			vox.borderSize = voxelCharacterRadius + 3;
			
			//Expand borderSize voxels on each side
			bounds.Expand (new Vector3 (vox.borderSize,0,vox.borderSize)*cellSize*2);
			
			vox.forcedBounds = bounds;
			vox.width = tileSizeX + vox.borderSize*2;
			vox.depth = tileSizeZ + vox.borderSize*2;
			
			if (!useTiles && relevantGraphSurfaceMode == RelevantGraphSurfaceMode.OnlyForCompletelyInsideTile) {
				// This best reflects what the user would actually want
				vox.relevantGraphSurfaceMode = RelevantGraphSurfaceMode.RequireForAll;
			} else {
				vox.relevantGraphSurfaceMode = relevantGraphSurfaceMode;
			}
			
			vox.minRegionSize = Mathf.RoundToInt(minRegionSize / (cellSize*cellSize));
			
 #if ASTARDEBUG
			Debug.Log ("Building Tile " + x+","+z);
			Console.WriteLine ("Recast Graph -- Voxelizing");
#endif
			AstarProfiler.EndProfile ("Init");
			
			
			//Init voxelizer
			vox.Init ();
			
			vox.CollectMeshes ();
			
			vox.VoxelizeInput ();
			
			AstarProfiler.StartProfile ("Filter Ledges");
			
			if (importMode) {
				if (System.IO.File.Exists(Application.dataPath+"/tile."+x+"."+z)) {
					System.IO.FileStream fs = System.IO.File.OpenRead (Application.dataPath+"/tile."+x+"."+z);
					byte[] bytes = new byte[fs.Length];
					fs.Read (bytes,0,(int)fs.Length);
					VoxelArea tmpVox = new VoxelArea(vox.width,vox.depth);
					Pathfinding.Voxels.VoxelSerializeUtility.DeserializeVoxelAreaData (bytes,tmpVox);
					Pathfinding.Voxels.VoxelSerializeUtility.MergeVoxelAreaData(tmpVox,vox.voxelArea,vox.voxelWalkableClimb);
				}
			}
			if (exportMode) {
				System.IO.FileStream fs = System.IO.File.Create(Application.dataPath+"/tile."+x+"."+z);
				byte[] bytes = Pathfinding.Voxels.VoxelSerializeUtility.SerializeVoxelAreaData(vox.voxelArea);
				fs.Write(bytes,0,bytes.Length);
				fs.Close();
			}
			
			vox.FilterLedges (vox.voxelWalkableHeight, vox.voxelWalkableClimb, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);
			
			AstarProfiler.EndProfile ("Filter Ledges");
			
			AstarProfiler.StartProfile ("Filter Low Height Spans");
			vox.FilterLowHeightSpans (vox.voxelWalkableHeight, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);
			AstarProfiler.EndProfile ("Filter Low Height Spans");
			
			vox.BuildCompactField ();
			
			vox.BuildVoxelConnections ();
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Eroding");
#endif
			
			vox.ErodeWalkableArea (voxelCharacterRadius);
					
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Building Distance Field");
#endif
			
			vox.BuildDistanceField ();

#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Building Regions");
#endif
			
			vox.BuildRegions ();
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Building Contours");
#endif
			
			VoxelContourSet cset = new VoxelContourSet ();
			
			vox.BuildContours (contourMaxError,1,cset,Voxelize.RC_CONTOUR_TESS_WALL_EDGES);
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Building Poly Mesh");
#endif
			
			VoxelMesh mesh;
			
			vox.BuildPolyMesh (cset,3,out mesh);
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Building Nodes");
#endif
			
			//Vector3[] vertices = new Vector3[mesh.verts.Length];
			
			AstarProfiler.StartProfile ("Build Nodes");
			
			//matrix = Matrix4x4.TRS (vox.voxelOffset,Quaternion.identity,Int3.Precision*vox.cellScale);
			
			//Position the vertices correctly in the world
			for (int i=0;i<mesh.verts.Length;i++) {
				//Note the multiplication is Scalar multiplication of vectors
				mesh.verts[i] = ((mesh.verts[i]*Int3.Precision) * vox.cellScale) + (Int3)vox.voxelOffset;
				
				//Debug.DrawRay (matrix.MultiplyPoint3x4(vertices[i]),Vector3.up,Color.red);
			}
			
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Generating Nodes");
#endif
			
			//NavMeshGraph.GenerateNodes (this,vertices,mesh.tris, out _vectorVertices, out _vertices);
			
			/*NavmeshTile prevTile = tiles[x + z*tileXCount];
			if (prevTile != null) {
				for (int i=0;i<prevTile.nodes.Length;i++) {
					prevTile.nodes[i].v0 = -1;
					prevTile.nodes[i].v1 = -1;
					prevTile.nodes[i].v2 = -1;
				}
			}*/
			
			NavmeshTile tile = CreateTile (vox, mesh, x,z);
			tiles[tile.x + tile.z*tileXCount] = tile;
			
			AstarProfiler.EndProfile ("Build Nodes");
			
#if ASTARDEBUG
			Console.WriteLine ("Recast Graph -- Done");
#endif
			
			AstarProfiler.EndProfile ("Build Tile");
		}
コード例 #8
0
ファイル: VoxelContour.cs プロジェクト: Alx666/ProjectPhoenix
		public void BuildContours (float maxError, int maxEdgeLength, VoxelContourSet cset, int buildFlags) {
			AstarProfiler.StartProfile("Build Contours");

			AstarProfiler.StartProfile("- Init");
			int w = voxelArea.width;
			int d = voxelArea.depth;

			int wd = w*d;

			//cset.bounds = voxelArea.bounds;

			int maxContours = Mathf.Max(8 /*Max Regions*/, 8);


			//cset.conts = new VoxelContour[maxContours];
			List<VoxelContour> contours = new List<VoxelContour>(maxContours);

			AstarProfiler.EndProfile("- Init");
			AstarProfiler.StartProfile("- Mark Boundaries");

			//cset.nconts = 0;

			//NOTE: This array may contain any data, but since we explicitly set all data in it before we use it, it's OK.
			ushort[] flags = voxelArea.tmpUShortArr;
			if (flags.Length < voxelArea.compactSpanCount) {
				flags = voxelArea.tmpUShortArr = new ushort[voxelArea.compactSpanCount];
			}

			// Mark boundaries. (@?)
			for (int z = 0; z < wd; z += voxelArea.width) {
				for (int x = 0; x < voxelArea.width; x++) {
					CompactVoxelCell c = voxelArea.compactCells[x+z];

					for (int i = (int)c.index, ci = (int)(c.index+c.count); i < ci; i++) {
						ushort res = 0;
						CompactVoxelSpan s = voxelArea.compactSpans[i];

						if (s.reg == 0 || (s.reg & BorderReg) == BorderReg) {
							flags[i] = 0;
							continue;
						}

						for (int dir = 0; dir < 4; dir++) {
							int r = 0;

							if (s.GetConnection(dir) != NotConnected) {
								int nx = x + voxelArea.DirectionX[dir];
								int nz = z + voxelArea.DirectionZ[dir];

								int ni = (int)voxelArea.compactCells[nx+nz].index + s.GetConnection(dir);
								r = voxelArea.compactSpans[ni].reg;
							}

							//@TODO - Why isn't this inside the previous IF
							if (r == s.reg) {
								res |= (ushort)(1 << dir);
							}
						}

						//Inverse, mark non connected edges.
						flags[i] = (ushort)(res ^ 0xf);
					}
				}
			}

			AstarProfiler.EndProfile("- Mark Boundaries");

			AstarProfiler.StartProfile("- Simplify Contours");
			List<int> verts = Pathfinding.Util.ListPool<int>.Claim(256);//new List<int> (256);
			List<int> simplified = Pathfinding.Util.ListPool<int>.Claim(64);//new List<int> (64);

			for (int z = 0; z < wd; z += voxelArea.width) {
				for (int x = 0; x < voxelArea.width; x++) {
					CompactVoxelCell c = voxelArea.compactCells[x+z];

					for (int i = (int)c.index, ci = (int)(c.index+c.count); i < ci; i++) {
						//CompactVoxelSpan s = voxelArea.compactSpans[i];

						if (flags[i] == 0 || flags[i] == 0xf) {
							flags[i] = 0;
							continue;
						}

						int reg = voxelArea.compactSpans[i].reg;

						if (reg == 0 || (reg & BorderReg) == BorderReg) {
							continue;
						}

						int area = voxelArea.areaTypes[i];

						verts.Clear();
						simplified.Clear();

						WalkContour(x, z, i, flags, verts);

						SimplifyContour(verts, simplified, maxError, maxEdgeLength, buildFlags);
						RemoveDegenerateSegments(simplified);

						VoxelContour contour = new VoxelContour();
						contour.verts = ClaimIntArr(simplified.Count, false);//simplified.ToArray ();
						for (int j = 0; j < simplified.Count; j++) contour.verts[j] = simplified[j];
#if ASTAR_RECAST_INCLUDE_RAW_VERTEX_CONTOUR
						//Not used at the moment, just debug stuff
						contour.rverts = ClaimIntArr(verts.Count);
						for (int j = 0; j < verts.Count; j++) contour.rverts[j] = verts[j];
#endif
						contour.nverts = simplified.Count/4;
						contour.reg = reg;
						contour.area = area;

						contours.Add(contour);

						#if ASTARDEBUG
						for (int q = 0, j = (simplified.Count/4)-1; q < (simplified.Count/4); j = q, q++) {
							int i4 = q*4;
							int j4 = j*4;

							Vector3 p1 = Vector3.Scale(
								new Vector3(
									simplified[i4+0],
									simplified[i4+1],
									(simplified[i4+2]/(float)voxelArea.width)
									),
								cellScale)
										 +voxelOffset;

							Vector3 p2 = Vector3.Scale(
								new Vector3(
									simplified[j4+0],
									simplified[j4+1],
									(simplified[j4+2]/(float)voxelArea.width)
									)
								, cellScale)
										 +voxelOffset;


							if (CalcAreaOfPolygon2D(contour.verts, contour.nverts) > 0) {
								Debug.DrawLine(p1, p2, AstarMath.IntToColor(reg, 0.5F));
							} else {
								Debug.DrawLine(p1, p2, Color.red);
							}
						}
						#endif
					}
				}
			}

			Pathfinding.Util.ListPool<int>.Release(verts);
			Pathfinding.Util.ListPool<int>.Release(simplified);

			AstarProfiler.EndProfile("- Simplify Contours");

			AstarProfiler.StartProfile("- Fix Contours");

			// Check and merge droppings.
			// Sometimes the previous algorithms can fail and create several contours
			// per area. This pass will try to merge the holes into the main region.
			for (int i = 0; i < contours.Count; i++) {
				VoxelContour cont = contours[i];
				// Check if the contour is would backwards.
				if (CalcAreaOfPolygon2D(cont.verts, cont.nverts) < 0) {
					// Find another contour which has the same region ID.
					int mergeIdx = -1;
					for (int j = 0; j < contours.Count; j++) {
						if (i == j) continue;
						if (contours[j].nverts > 0 && contours[j].reg == cont.reg) {
							// Make sure the polygon is correctly oriented.
							if (CalcAreaOfPolygon2D(contours[j].verts, contours[j].nverts) > 0) {
								mergeIdx = j;
								break;
							}
						}
					}
					if (mergeIdx == -1) {
						Debug.LogError("rcBuildContours: Could not find merge target for bad contour "+i+".");
					} else {
						// Debugging
						//Debug.LogWarning ("Fixing contour");

						VoxelContour mcont = contours[mergeIdx];
						// Merge by closest points.
						int ia = 0, ib = 0;
						GetClosestIndices(mcont.verts, mcont.nverts, cont.verts, cont.nverts, ref ia, ref ib);

						if (ia == -1 || ib == -1) {
							Debug.LogWarning("rcBuildContours: Failed to find merge points for "+i+" and "+mergeIdx+".");
							continue;
						}

#if ASTARDEBUG
						int p4 = ia*4;
						int p42 = ib*4;

						Vector3 p12 = Vector3.Scale(
							new Vector3(
								mcont.verts[p4+0],
								mcont.verts[p4+1],
								(mcont.verts[p4+2]/(float)voxelArea.width)
								),
							cellScale)
									  +voxelOffset;

						Vector3 p22 = Vector3.Scale(
							new Vector3(
								cont.verts[p42+0],
								cont.verts[p42+1],
								(cont.verts[p42+2]/(float)voxelArea.width)
								)
							, cellScale)
									  +voxelOffset;

						Debug.DrawLine(p12, p22, Color.green);
#endif

						if (!MergeContours(ref mcont, ref cont, ia, ib)) {
							Debug.LogWarning("rcBuildContours: Failed to merge contours "+i+" and "+mergeIdx+".");
							continue;
						}

						contours[mergeIdx] = mcont;
						contours[i] = cont;

						#if ASTARDEBUG
						Debug.Log(mcont.nverts);

						for (int q = 0, j = (mcont.nverts)-1; q < (mcont.nverts); j = q, q++) {
							int i4 = q*4;
							int j4 = j*4;

							Vector3 p1 = Vector3.Scale(
								new Vector3(
									mcont.verts[i4+0],
									mcont.verts[i4+1],
									(mcont.verts[i4+2]/(float)voxelArea.width)
									),
								cellScale)
										 +voxelOffset;

							Vector3 p2 = Vector3.Scale(
								new Vector3(
									mcont.verts[j4+0],
									mcont.verts[j4+1],
									(mcont.verts[j4+2]/(float)voxelArea.width)
									)
								, cellScale)
										 +voxelOffset;

							Debug.DrawLine(p1, p2, Color.red);
							//}
						}
						#endif
					}
				}
			}

			cset.conts = contours;

			AstarProfiler.EndProfile("- Fix Contours");

			AstarProfiler.EndProfile("Build Contours");
		}
コード例 #9
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");
        }
コード例 #10
0
ファイル: VoxelContour.cs プロジェクト: Alx666/ProjectPhoenix
		/** Releases contents of a contour set to caches */
		static void ReleaseContours (VoxelContourSet cset) {
			for (int i = 0; i < cset.conts.Count; i++) {
				VoxelContour cont = cset.conts[i];
				ReleaseIntArr(cont.verts);
				ReleaseIntArr(cont.rverts);
			}
			cset.conts = null;
		}
コード例 #11
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");
        }
コード例 #12
0
ファイル: VoxelMesh.cs プロジェクト: liushengchao112/Ember
        /** 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");
        }
コード例 #13
0
ファイル: RecastGraph.cs プロジェクト: GameDiffs/TheForest
 protected void BuildTileMesh(Voxelize vox, int x, int z)
 {
     float num = (float)this.tileSizeX * this.cellSize;
     float num2 = (float)this.tileSizeZ * this.cellSize;
     int num3 = Mathf.CeilToInt(this.characterRadius / this.cellSize);
     Vector3 min = this.forcedBounds.min;
     Vector3 max = this.forcedBounds.max;
     Bounds forcedBounds = default(Bounds);
     forcedBounds.SetMinMax(new Vector3((float)x * num, 0f, (float)z * num2) + min, new Vector3((float)(x + 1) * num + min.x, max.y, (float)(z + 1) * num2 + min.z));
     vox.borderSize = num3 + 3;
     forcedBounds.Expand(new Vector3((float)vox.borderSize, 0f, (float)vox.borderSize) * this.cellSize * 2f);
     vox.forcedBounds = forcedBounds;
     vox.width = this.tileSizeX + vox.borderSize * 2;
     vox.depth = this.tileSizeZ + vox.borderSize * 2;
     if (!this.useTiles && this.relevantGraphSurfaceMode == RecastGraph.RelevantGraphSurfaceMode.OnlyForCompletelyInsideTile)
     {
         vox.relevantGraphSurfaceMode = RecastGraph.RelevantGraphSurfaceMode.RequireForAll;
     }
     else
     {
         vox.relevantGraphSurfaceMode = this.relevantGraphSurfaceMode;
     }
     vox.minRegionSize = Mathf.RoundToInt(this.minRegionSize / (this.cellSize * this.cellSize));
     vox.Init();
     vox.CollectMeshes();
     vox.VoxelizeInput();
     vox.FilterLedges(vox.voxelWalkableHeight, vox.voxelWalkableClimb, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);
     vox.FilterLowHeightSpans(vox.voxelWalkableHeight, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);
     vox.BuildCompactField();
     vox.BuildVoxelConnections();
     vox.ErodeWalkableArea(num3);
     vox.BuildDistanceField();
     vox.BuildRegions();
     VoxelContourSet cset = new VoxelContourSet();
     vox.BuildContours(this.contourMaxError, 1, cset, 1);
     VoxelMesh mesh;
     vox.BuildPolyMesh(cset, 3, out mesh);
     for (int i = 0; i < mesh.verts.Length; i++)
     {
         mesh.verts[i] = mesh.verts[i] * 1000 * vox.cellScale + (Int3)vox.voxelOffset;
     }
     RecastGraph.NavmeshTile navmeshTile = this.CreateTile(vox, mesh, x, z);
     this.tiles[navmeshTile.x + navmeshTile.z * this.tileXCount] = navmeshTile;
 }
コード例 #14
0
		protected void BuildTileMesh (Voxelize vox, int x, int z) {
			AstarProfiler.StartProfile("Build Tile");

			AstarProfiler.StartProfile("Init");

			//World size of tile
			float tcsx = tileSizeX*cellSize;
			float tcsz = tileSizeZ*cellSize;

			int voxelCharacterRadius = Mathf.CeilToInt(characterRadius/cellSize);

			Vector3 forcedBoundsMin = forcedBounds.min;
			Vector3 forcedBoundsMax = forcedBounds.max;

			var bounds = new Bounds();
			bounds.SetMinMax(new Vector3(x*tcsx, 0, z*tcsz) + forcedBoundsMin,
				new Vector3((x+1)*tcsx + forcedBoundsMin.x, forcedBoundsMax.y, (z+1)*tcsz + forcedBoundsMin.z)
				);
			vox.borderSize = voxelCharacterRadius + 3;

			//Expand borderSize voxels on each side
			bounds.Expand(new Vector3(vox.borderSize, 0, vox.borderSize)*cellSize*2);

			vox.forcedBounds = bounds;
			vox.width = tileSizeX + vox.borderSize*2;
			vox.depth = tileSizeZ + vox.borderSize*2;

			if (!useTiles && relevantGraphSurfaceMode == RelevantGraphSurfaceMode.OnlyForCompletelyInsideTile) {
				// This best reflects what the user would actually want
				vox.relevantGraphSurfaceMode = RelevantGraphSurfaceMode.RequireForAll;
			} else {
				vox.relevantGraphSurfaceMode = relevantGraphSurfaceMode;
			}

			vox.minRegionSize = Mathf.RoundToInt(minRegionSize / (cellSize*cellSize));

 #if ASTARDEBUG
			Debug.Log("Building Tile " + x+","+z);
			System.Console.WriteLine("Recast Graph -- Voxelizing");
#endif
			AstarProfiler.EndProfile("Init");


			//Init voxelizer
			vox.Init();

			vox.CollectMeshes();

			vox.VoxelizeInput();

			AstarProfiler.StartProfile("Filter Ledges");


			vox.FilterLedges(vox.voxelWalkableHeight, vox.voxelWalkableClimb, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);

			AstarProfiler.EndProfile("Filter Ledges");

			AstarProfiler.StartProfile("Filter Low Height Spans");
			vox.FilterLowHeightSpans(vox.voxelWalkableHeight, vox.cellSize, vox.cellHeight, vox.forcedBounds.min);
			AstarProfiler.EndProfile("Filter Low Height Spans");

			vox.BuildCompactField();

			vox.BuildVoxelConnections();

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Eroding");
#endif

			vox.ErodeWalkableArea(voxelCharacterRadius);

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Building Distance Field");
#endif

			vox.BuildDistanceField();

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Building Regions");
#endif

			vox.BuildRegions();

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Building Contours");
#endif

			var cset = new VoxelContourSet();

			vox.BuildContours(contourMaxError, 1, cset, Voxelize.RC_CONTOUR_TESS_WALL_EDGES);

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Building Poly Mesh");
#endif

			VoxelMesh mesh;

			vox.BuildPolyMesh(cset, 3, out mesh);

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Building Nodes");
#endif

			//Vector3[] vertices = new Vector3[mesh.verts.Length];

			AstarProfiler.StartProfile("Build Nodes");

			// Debug code
			//matrix = Matrix4x4.TRS (vox.voxelOffset,Quaternion.identity,Int3.Precision*vox.cellScale);

			//Position the vertices correctly in the world
			for (int i = 0; i < mesh.verts.Length; i++) {
				//Note the multiplication is Scalar multiplication of vectors
				mesh.verts[i] = ((mesh.verts[i]*Int3.Precision) * vox.cellScale) + (Int3)vox.voxelOffset;

				// Debug code
				//Debug.DrawRay (matrix.MultiplyPoint3x4(vertices[i]),Vector3.up,Color.red);
			}


#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Generating Nodes");
#endif

			NavmeshTile tile = CreateTile(vox, mesh, x, z);
			tiles[tile.x + tile.z*tileXCount] = tile;

			AstarProfiler.EndProfile("Build Nodes");

#if ASTARDEBUG
			System.Console.WriteLine("Recast Graph -- Done");
#endif

			AstarProfiler.EndProfile("Build Tile");
		}