public WavefrontObj( List <CoordinateDecimal> vertices, Dictionary <string, List <FaceVertices> > collisionBoxes, Dictionary <BlockFaceTexture, List <TexturedFace> > texturedFaces, TextureCoordinateDictionary textureCoordinates, Dictionary <Block, List <FacedVolume> > facedVolumizedWorld) { this.vertices = vertices; this.collisionBoxes = collisionBoxes; this.texturedFaces = texturedFaces; this.textureCoordinates = textureCoordinates; }
public WavefrontObj( List<CoordinateDecimal> vertices, Dictionary<string, List<FaceVertices>> collisionBoxes, Dictionary<BlockFaceTexture, List<TexturedFace>> texturedFaces, TextureCoordinateDictionary textureCoordinates, Dictionary<Block, List<FacedVolume>> facedVolumizedWorld) { this.vertices = vertices; this.collisionBoxes = collisionBoxes; this.texturedFaces = texturedFaces; this.textureCoordinates = textureCoordinates; }
private static void AppendTexturedFaces(Dictionary<BlockFaceTexture, List<TexturedFace>> texturedFaces, TextureCoordinateDictionary textureCoordinates, Block blockType, Volume volume, Face face, FaceVertices faceVertices) { BlockFaceTexture blockFaceTexture = blockType.GetFaceTexture(face); TexturedFace texturedFace = new TexturedFace(volume, face, faceVertices); List<TexturedFace> texturedFacesList; if (texturedFaces.TryGetValue(blockFaceTexture, out texturedFacesList)) texturedFacesList.Add(texturedFace); else { texturedFacesList = new List<TexturedFace>(); texturedFacesList.Add(texturedFace); texturedFaces.Add(blockFaceTexture, texturedFacesList); } textureCoordinates.EnsureExists(texturedFace.textureMapping); }
private static void ProcessBlocks(string outputPath, Dictionary<CoordinateInt, Block> rawBlocks) { /* We need to identify any bricks that are hidden from vision. */ Console.WriteLine("Identifying invisible blocks."); HashSet<CoordinateInt> invisibleBricks = new HashSet<CoordinateInt>(); foreach (KeyValuePair<CoordinateInt, Block> pair in rawBlocks) if (IsInvisible(pair.Key, rawBlocks)) invisibleBricks.Add(pair.Key); foreach (CoordinateInt coord in invisibleBricks) rawBlocks.Remove(coord); Console.WriteLine("Identified {0} invisible bricks.", invisibleBricks.Count); /* Before we can start expanding cubes, we need to organize by block type. */ Console.WriteLine("Extracting largest volumes."); Dictionary<Block, List<Volume>> volumizedWorld = new Dictionary<Block, List<Volume>>(); foreach (KeyValuePair<Block, HashSet<CoordinateInt>> pair in OrganizeRawBlocks(rawBlocks)) volumizedWorld.Add(pair.Key, new List<Volume>(new LargestVolumeExtractor(pair.Value, invisibleBricks))); /* Scan for interior faces that we can remove. */ HiddenFaces.totalHiddenFaces = 0; Console.WriteLine("Identifying interior faces."); Dictionary<Block, List<FacedVolume>> facedVolumizedWorld = HiddenFaces.DetectHiddenFaces(volumizedWorld, rawBlocks); Console.WriteLine("Identified {0} interior faces.", HiddenFaces.totalHiddenFaces); /* Storage for the actual 3D geometry. */ List<CoordinateDecimal> vertices = new List<CoordinateDecimal>(); Dictionary<string, List<FaceVertices>> collisionBoxes = new Dictionary<string, List<FaceVertices>>(); Dictionary<BlockFaceTexture, List<TexturedFace>> texturedFaces = new Dictionary<BlockFaceTexture, List<TexturedFace>>(); TextureCoordinateDictionary textureCoordinates = new TextureCoordinateDictionary(); /* Build the textured faces from the volumes. */ foreach (KeyValuePair<Block, List<FacedVolume>> pair in facedVolumizedWorld) { List<FacedVolume> volumes = pair.Value; for (int idx = 0; idx < volumes.Count; idx++) { FacedVolume facedVolume = volumes[idx]; Iterators.FacesInVolume(vertices.Count, facedVolume.excludedFaces, (Face face, FaceVertices faceVertices) => { AppendTexturedFaces(texturedFaces, textureCoordinates, pair.Key, facedVolume.volume, face, faceVertices); }); Iterators.VerticesInVolume(volumes[idx].volume, (CoordinateDecimal a) => { vertices.Add(a); }); } } Console.WriteLine(textureCoordinates.mappingList.Count + " unique texture coordinates."); /* Delete duplicate vertices before adding collision UBXs because the UBX vertices will all be unique. */ Console.WriteLine("Detecting duplicate vertices."); int duplicatesRemoved = DuplicateVertices.DetectAndErase(vertices, texturedFaces); Console.WriteLine(duplicatesRemoved + " duplicate vertices removed."); Console.WriteLine("Generate UBX collision volumes."); foreach (KeyValuePair<Block, List<FacedVolume>> pair in facedVolumizedWorld) { List<FacedVolume> volumes = pair.Value; for (int idx = 0; idx < volumes.Count; idx++) #warning Potential for collision meshes to be far from visual mesh! MakeCollisionUBX("UBX_" + pair.Key.ToString() + string.Format("_{0:00}", idx), volumes[idx].volume, vertices, collisionBoxes); } /* Export the geometry to Wavefront's OBJ format. */ WavefrontObj objFile = new WavefrontObj(vertices, collisionBoxes, texturedFaces, textureCoordinates, facedVolumizedWorld); /* Save the OBJ file to the specified destination. */ File.WriteAllText(outputPath, objFile.ToString()); }