예제 #1
0
		//public System.Object lockObject;
		
		public void AddSpan (uint bottom, uint top, int area, int voxelWalkableClimb) {
			VoxelSpan span = new VoxelSpan (bottom,top,area);
				
			if (firstSpan == null) {
				firstSpan = span;
				return;
			}
			
			VoxelSpan prev = null;
			VoxelSpan cSpan = firstSpan;
			
			while (cSpan != null) {
				if (cSpan.bottom > span.top) {
					break;
					
				} else if (cSpan.top < span.bottom) {
					prev = cSpan;
					cSpan = cSpan.next;
				} else {
					if (cSpan.bottom < bottom) {
						span.bottom = cSpan.bottom;
					}
					if (cSpan.top > top) {
						span.top = cSpan.top;
					}
					
					//1 is flagMergeDistance, when a walkable flag is favored before an unwalkable one
					if (AstarMath.Abs ((int)span.top - (int)cSpan.top) <= voxelWalkableClimb) {
						span.area = AstarMath.Max (span.area,cSpan.area);
					}
					
					VoxelSpan next = cSpan.next;
					if (prev != null) {
						prev.next = next;
					} else {
						firstSpan = next;
					}
					cSpan = next;
				}
			}
			
			if (prev != null) {
				span.next = prev.next;
				prev.next = span;
			} else {
				span.next = firstSpan;
				firstSpan = span;
			}
		}
예제 #2
0
        public void BuildCompactField()
        {
            AstarProfiler.StartProfile("Build Compact Voxel Field");

            //Build compact representation
            int spanCount = voxelArea.GetSpanCount();

            voxelArea.compactSpanCount = spanCount;
            if (voxelArea.compactSpans == null || voxelArea.compactSpans.Length < spanCount)
            {
                voxelArea.compactSpans = new CompactVoxelSpan[spanCount];
                voxelArea.areaTypes    = new int[spanCount];
            }

            uint idx = 0;

            int w  = voxelArea.width;
            int d  = voxelArea.depth;
            int wd = w * d;

            if (this.voxelWalkableHeight >= 0xFFFF)
            {
                Debug.LogWarning("Too high walkable height to guarantee correctness. Increase voxel height or lower walkable height.");
            }

#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
            LinkedVoxelSpan[] spans = voxelArea.linkedSpans;
#endif

            //Parallel.For (0, voxelArea.depth, delegate (int pz) {
            for (int z = 0, pz = 0; z < wd; z += w, pz++)
            {
                for (int x = 0; x < w; x++)
                {
#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
                    int spanIndex = x + z;
                    if (spans[spanIndex].bottom == VoxelArea.InvalidSpanValue)
                    {
                        voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0);
                        continue;
                    }

                    uint index = idx;
                    uint count = 0;

                    //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset;

                    while (spanIndex != -1)
                    {
                        if (spans[spanIndex].area != UnwalkableArea)
                        {
                            int bottom = (int)spans[spanIndex].top;
                            int next   = spans[spanIndex].next;
                            int top    = next != -1 ? (int)spans[next].bottom : VoxelArea.MaxHeightInt;

                            voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)(bottom > 0xFFFF ? 0xFFFF : bottom), (uint)(top - bottom > 0xFFFF ? 0xFFFF : top - bottom));
                            voxelArea.areaTypes[idx]    = spans[spanIndex].area;
                            idx++;
                            count++;
                        }
                        spanIndex = spans[spanIndex].next;
                    }

                    voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count);
#else
                    VoxelSpan s = voxelArea.cells[x + z].firstSpan;

                    if (s == null)
                    {
                        voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0);
                        continue;
                    }

                    uint index = idx;
                    uint count = 0;

                    //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset;

                    while (s != null)
                    {
                        if (s.area != UnwalkableArea)
                        {
                            int bottom = (int)s.top;
                            int top    = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt;

                            voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)Mathf.Clamp(bottom, 0, 0xffff), (uint)Mathf.Clamp(top - bottom, 0, 0xffff));
                            voxelArea.areaTypes[idx]    = s.area;
                            idx++;
                            count++;
                        }
                        s = s.next;
                    }

                    voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count);
#endif
                }
            }

            AstarProfiler.EndProfile("Build Compact Voxel Field");
        }