public void GenerateCubes(string outputPath, SlicingOptions options) { CubeMetadata metadata = new CubeMetadata(size) { WorldBounds = ObjInstance.Size, VirtualWorldBounds = options.ForceCubicalCubes ? ObjInstance.CubicalSize : ObjInstance.Size, VertexCount = ObjInstance.VertexList.Count }; // Configure texture slicing metadata if (options.RequiresTextureProcessing()) { metadata.TextureSetSize = new Vector2(options.TextureSliceX, options.TextureSliceY); } else { metadata.TextureSetSize = new Vector2(1, 1); } // Create texture if there is one if (!string.IsNullOrEmpty(options.Texture)) { Texture t = new Texture(this.ObjInstance, options.Texture); options.TextureInstance = t; } // Generate the data if (options.Debug) { SpatialUtilities.EnumerateSpace(metadata.TextureSetSize, (x, y) => { var vertexCounts = GenerateCubesForTextureTileAsync(outputPath, new Vector2(x, y), options, new CancellationToken()).Result; foreach (var cube in vertexCounts.Keys) { metadata.CubeExists[cube.X, cube.Y, cube.Z] = vertexCounts[cube] > 0; } }); } else { SpatialUtilities.EnumerateSpaceParallel(metadata.TextureSetSize, (x, y) => { var vertexCounts = GenerateCubesForTextureTileAsync(outputPath, new Vector2(x, y), options, new CancellationToken()).Result; foreach (var cube in vertexCounts.Keys) { metadata.CubeExists[cube.X, cube.Y, cube.Z] = vertexCounts[cube] > 0; } }); } // Write out some json metadata string metadataPath = Path.Combine(outputPath, "metadata.json"); if (File.Exists(metadataPath)) { File.Delete(metadataPath); } string metadataString = JsonConvert.SerializeObject(metadata); File.WriteAllText(metadataPath, metadataString); }
private void WriteObjFormattedFile(string path, string mtlOverride, List <Face> chunkFaceList, Vector2 tile, SlicingOptions options, string comment = "") { // Build a list of vertices indexes needed for these faces List <int> requiredVertices = null; List <int> requiredTextureVertices = null; var tv = Task.Run(() => { requiredVertices = chunkFaceList.AsParallel().SelectMany(f => f.VertexIndexList).Distinct().ToList(); }); var ttv = Task.Run(() => { requiredTextureVertices = chunkFaceList.AsParallel().SelectMany(f => f.TextureVertexIndexList).Distinct().ToList(); }); Task.WaitAll(new Task[] { tv, ttv }); using (var outStream = File.OpenWrite(path)) using (var writer = new StreamWriter(outStream)) { // Write some header data writer.WriteLine("# Generated by PyriteCli"); if (!string.IsNullOrEmpty(comment)) { writer.WriteLine("# " + comment); } if (!string.IsNullOrEmpty(mtlOverride)) { writer.WriteLine("mtllib " + mtlOverride); } else if (!string.IsNullOrEmpty(_mtl) && !options.RequiresTextureProcessing()) { writer.WriteLine("mtllib " + _mtl); } else if (options.RequiresTextureProcessing() && options.WriteMtl) { writer.WriteLine("mtllib texture\\{0}_{1}.mtl", tile.X, tile.Y); } // Write each vertex and update faces _verticesRequireReset = true; int newVertexIndex = 0; Parallel.ForEach(requiredVertices, i => { Vertex moving = VertexList[i - 1]; int newIndex = WriteVertexWithNewIndex(moving, ref newVertexIndex, writer); var facesRequiringUpdate = chunkFaceList.Where(f => f.VertexIndexList.Contains(i)); foreach (var face in facesRequiringUpdate) { face.UpdateVertexIndex(moving.Index, newIndex); } }); // Write each texture vertex and update faces int newTextureVertexIndex = 0; Parallel.ForEach(requiredTextureVertices, i => { TextureVertex moving = TextureList[i - 1]; int newIndex = WriteVertexWithNewIndex(moving, ref newTextureVertexIndex, writer); var facesRequiringUpdate = chunkFaceList.Where(f => f.TextureVertexIndexList.Contains(i)); foreach (var face in facesRequiringUpdate) { face.UpdateTextureVertexIndex(moving.Index, newIndex); } }); // Write the faces chunkFaceList.ForEach(f => writer.WriteLine(f)); } }