Example #1
0
 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;
 }
Example #2
0
 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;
 }
Example #3
0
        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);
        }
Example #4
0
        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());
        }