Exemple #1
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);
        }
Exemple #2
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());
        }