public static void DeserializeVoxelAreaData (byte[] bytes, VoxelArea target) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(); System.IO.MemoryStream stream = new System.IO.MemoryStream(); stream.Write(bytes,0,bytes.Length); stream.Position = 0; zip = Ionic.Zip.ZipFile.Read(stream); System.IO.MemoryStream stream2 = new System.IO.MemoryStream(); zip["data"].Extract (stream2); stream2.Position = 0; System.IO.BinaryReader reader = new System.IO.BinaryReader(stream2); int width = reader.ReadInt32(); int depth = reader.ReadInt32(); if (target.width != width) throw new System.ArgumentException ("target VoxelArea has a different width than the data ("+target.width + " != " + width + ")"); if (target.depth != depth) throw new System.ArgumentException ("target VoxelArea has a different depth than the data ("+target.depth + " != " + depth + ")"); LinkedVoxelSpan[] spans = new LinkedVoxelSpan[reader.ReadInt32()]; for (int i=0;i<spans.Length;i++) { spans[i].area = reader.ReadInt32(); spans[i].bottom = reader.ReadUInt32(); spans[i].next = reader.ReadInt32(); spans[i].top = reader.ReadUInt32(); } target.linkedSpans = spans; #else throw new System.NotImplementedException ("This method only works with !ASTAR_RECAST_CLASS_BASED_LINKED_LIST"); #endif }
public static byte[] SerializeVoxelAreaData (VoxelArea v) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST System.IO.MemoryStream stream = new System.IO.MemoryStream(); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); writer.Write (v.width); writer.Write (v.depth); writer.Write (v.linkedSpans.Length); for (int i=0;i<v.linkedSpans.Length;i++) { writer.Write(v.linkedSpans[i].area); writer.Write(v.linkedSpans[i].bottom); writer.Write(v.linkedSpans[i].next); writer.Write(v.linkedSpans[i].top); } //writer.Close(); writer.Flush(); Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(); stream.Position = 0; zip.AddEntry ("data",stream); System.IO.MemoryStream stream2 = new System.IO.MemoryStream(); zip.Save(stream2); byte[] bytes = stream2.ToArray(); stream.Close(); stream2.Close(); return bytes; #else throw new System.NotImplementedException ("This method only works with !ASTAR_RECAST_CLASS_BASED_LINKED_LIST"); #endif }
public static byte[] SerializeVoxelAreaCompactData (VoxelArea v) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST System.IO.MemoryStream stream = new System.IO.MemoryStream(); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); writer.Write (v.width); writer.Write (v.depth); writer.Write (v.compactCells.Length); writer.Write(v.compactSpans.Length); writer.Write(v.areaTypes.Length); for (int i=0;i<v.compactCells.Length;i++) { writer.Write(v.compactCells[i].index); writer.Write(v.compactCells[i].count); } for (int i=0;i<v.compactSpans.Length;i++) { writer.Write(v.compactSpans[i].con); writer.Write(v.compactSpans[i].h); writer.Write(v.compactSpans[i].reg); writer.Write(v.compactSpans[i].y); } for (int i=0;i<v.areaTypes.Length;i++) { //TODO: RLE encoding writer.Write(v.areaTypes[i]); } writer.Close(); return stream.ToArray(); #else throw new System.NotImplementedException ("This method only works with !ASTAR_RECAST_CLASS_BASED_LINKED_LIST"); #endif }
public void Init () { //Initialize the voxel area if (voxelArea == null || voxelArea.width != width || voxelArea.depth != depth) voxelArea = new VoxelArea (width, depth); else voxelArea.Reset (); }
public static void MergeVoxelAreaData (VoxelArea source, VoxelArea merge, int voxelWalkableClimb) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST LinkedVoxelSpan[] spans1 = source.linkedSpans; int wd = source.width*source.depth; for (int x=0;x<wd;x++) { int i = x; if (spans1[i].bottom == VoxelArea.InvalidSpanValue) continue; while (i != -1) { merge.AddLinkedSpan(x,spans1[i].bottom,spans1[i].top,spans1[i].area,voxelWalkableClimb); i = spans1[i].next; } } #else throw new System.NotImplementedException ("This method only works with !ASTAR_RECAST_CLASS_BASED_LINKED_LIST"); #endif }
public static void DeserializeVoxelAreaCompactData (byte[] bytes, VoxelArea target) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes); System.IO.BinaryReader reader = new System.IO.BinaryReader(stream); int width = reader.ReadInt32(); int depth = reader.ReadInt32(); if (target.width != width) throw new System.ArgumentException ("target VoxelArea has a different width than the data ("+target.width + " != " + width + ")"); if (target.depth != depth) throw new System.ArgumentException ("target VoxelArea has a different depth than the data ("+target.depth + " != " + depth + ")"); CompactVoxelCell[] cells = new CompactVoxelCell[reader.ReadInt32()]; CompactVoxelSpan[] spans = new CompactVoxelSpan[reader.ReadInt32()]; int[] areas = new int[reader.ReadInt32()]; for (int i=0;i<cells.Length;i++) { cells[i].index = reader.ReadUInt32(); cells[i].count = reader.ReadUInt32(); } for (int i=0;i<spans.Length;i++) { spans[i].con = reader.ReadUInt32(); spans[i].h = reader.ReadUInt32(); spans[i].reg = reader.ReadInt32(); spans[i].y = reader.ReadUInt16(); } for (int i=0;i<areas.Length;i++) { areas[i] = reader.ReadInt32(); } target.compactCells = cells; target.compactSpans = spans; target.areaTypes = areas; #else throw new System.NotImplementedException ("This method only works with !ASTAR_RECAST_CLASS_BASED_LINKED_LIST"); #endif }
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"); #if ASTAR_RECAST_VOXEL_DEBUG if (importMode) { if (File.Exists(Application.dataPath+"/tile."+x+"."+z)) { FileStream fs = 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) { FileStream fs = File.Create(Application.dataPath+"/tile."+x+"."+z); byte[] bytes = Pathfinding.Voxels.VoxelSerializeUtility.SerializeVoxelAreaData(vox.voxelArea); fs.Write(bytes,0,bytes.Length); fs.Close(); } #endif 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"); }