Beispiel #1
0
        private DirectBitmap[] ResizeAndConverCubeToDirectBitmap(CubemapImages images)
        {
            Bitmap[] processedFaces = new Bitmap[6];
            bool     resize         = false;

            if (resize)
            {
                processedFaces[0] = ResizeImage(images.Back, images.Back.Width * 2, images.Back.Height * 2);
                processedFaces[1] = ResizeImage(images.Bottom, images.Bottom.Width * 2, images.Bottom.Height * 2);
                processedFaces[2] = ResizeImage(images.Front, images.Front.Width * 2, images.Front.Height * 2);
                processedFaces[3] = ResizeImage(images.Left, images.Left.Width * 2, images.Left.Height * 2);
                processedFaces[4] = ResizeImage(images.Right, images.Right.Width * 2, images.Right.Height * 2);
                processedFaces[5] = ResizeImage(images.Top, images.Top.Width * 2, images.Top.Height * 2);
            }
            else
            {
                processedFaces[0] = images.Back;
                processedFaces[1] = images.Bottom;
                processedFaces[2] = images.Front;
                processedFaces[3] = images.Left;
                processedFaces[4] = images.Right;
                processedFaces[5] = images.Top;
            }
            DirectBitmap[] faces = new DirectBitmap[6];
            faces[0] = CopyImageToDirectBitmap(processedFaces[0]);
            faces[1] = CopyImageToDirectBitmap(processedFaces[1]);
            faces[2] = CopyImageToDirectBitmap(processedFaces[2]);
            faces[3] = CopyImageToDirectBitmap(processedFaces[3]);
            faces[4] = CopyImageToDirectBitmap(processedFaces[4]);
            faces[5] = CopyImageToDirectBitmap(processedFaces[5]);
            return(faces);
        }
        public void ExportCubemapAsFaces(string fileSavePath, CubemapImages images)
        {
            var filenames = GetCubeFileNames(fileSavePath);

            ImageSaveService.Save(filenames[0], images.Back);
            ImageSaveService.Save(filenames[1], images.Bottom);
            ImageSaveService.Save(filenames[2], images.Front);
            ImageSaveService.Save(filenames[3], images.Left);
            ImageSaveService.Save(filenames[4], images.Right);
            ImageSaveService.Save(filenames[5], images.Top);
        }
        public void ExportCubemap(string fileSavePath, Node node, bool saveSeparately = false, bool exportAsSphericalProjection = false)
        {
            CubeMapImageSet imageSet;

            if (node.DepthMap != null)
            {
                imageSet = node.DepthMap;
            }
            else
            {
                imageSet = node.CubeMap;
            }

            CubemapImages images = GetCubemapImagesForImageSet(node, imageSet);

            if (!saveSeparately)
            {
                Bitmap finalImage;
                if (exportAsSphericalProjection)
                {
                    MessageBox.Show("Exporting as spherical projection may take up to around a minute to finish.");
                    finalImage = new SphericalProjectionService().ConstructProjection(images);
                }
                else
                {
                    finalImage = new CubeMapBuilder().ConstructCubemap(images);
                }

                ImageSaveService.Save(fileSavePath, finalImage);

                if (exportAsSphericalProjection)
                {
                    MessageBox.Show("Exporting as spherical projection has completed!");
                }
            }
            else
            {
                // with Revelation images need assembly, which create bitmaps in memory
                // the best output for images manipulated by the program as png files
                // that way they retain detail, without creating output files that are gigantic
                // saving as jpg would be too lossy

                // With Exile the original jpg image data can be saved directly from the original files
                // this avoids un-needed conversion and loss of detail or increase the output file size
                if (SelectedGame == "Exile")
                {
                    ExportCubemapDataDirectly(fileSavePath, node);
                }
                else
                {
                    ExportCubemapAsFaces(fileSavePath, images);
                }
            }
        }
        public CubemapImages GetCubemapImagesForImageSet(Node node, CubeMapImageSet imageSet)
        {
            var data = new CubemapImages();

            data.Back   = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Back.File));
            data.Bottom = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Bottom.File));
            data.Front  = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Front.File));
            data.Left   = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Left.File));
            data.Right  = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Right.File));
            data.Top    = BitmapUtils.LoadBitmapFromMemory(this.LookupFileImageData(node, imageSet.Top.File));
            return(data);
        }
        public void PopulateImages(Node node)
        {
            if (node == null)
            {
                return;
            }
            CubeMapImageSet imageSet = node.CubeMap;

            //if (mapTypeIsColor == true)
            //    imageSet = node.CubeMap;
            //else
            //    imageSet = node.CubeMaps.Depth;

            // some kind of check to validate images?
            CubemapImages data = App.GetCubemapImagesForImageSet(node, imageSet);

            var blank = Properties.Resources.picture_icon_large;

            backImage.BackgroundImage   = data.Back != null ? data.Back : blank;
            bottomImage.BackgroundImage = data.Bottom != null ? data.Bottom : blank;
            frontImage.BackgroundImage  = data.Front != null ? data.Front : blank;
            leftImage.BackgroundImage   = data.Left != null ? data.Left : blank;
            rightImage.BackgroundImage  = data.Right != null ? data.Right : blank;
            topImage.BackgroundImage    = data.Top != null ? data.Top : blank;

            backImage.Tag   = imageSet.Back.File;
            bottomImage.Tag = imageSet.Bottom.File;
            frontImage.Tag  = imageSet.Front.File;
            leftImage.Tag   = imageSet.Left.File;
            rightImage.Tag  = imageSet.Right.File;
            topImage.Tag    = imageSet.Top.File;

            fileNameLabel_Back.Text   = "Back: " + imageSet.Back.File;
            fileNameLabel_Bottom.Text = "Bottom: " + imageSet.Bottom.File;
            fileNameLabel_Front.Text  = "Front: " + imageSet.Front.File;
            fileNameLabel_Left.Text   = "Left: " + imageSet.Left.File;
            fileNameLabel_Right.Text  = "Right: " + imageSet.Right.File;
            fileNameLabel_Top.Text    = "Top: " + imageSet.Top.File;
        }
Beispiel #6
0
        private Texture GetCubeMapTexture()
        {
            var cubeMapImages = new CubemapImages(
                new Bitmap(@"Resources\data\water_pos_x.png"),
                new Bitmap(@"Resources\data\water_neg_x.png"),
                new Bitmap(@"Resources\data\water_pos_y.png"),
                new Bitmap(@"Resources\data\water_neg_y.png"),
                new Bitmap(@"Resources\data\water_pos_z.png"),
                new Bitmap(@"Resources\data\water_neg_z.png"));
            var cubemapFiller  = new CubemapImageFiller(cubeMapImages, 0, OpenGL.GL_RGBA, 0, OpenGL.GL_BGRA, OpenGL.GL_UNSIGNED_BYTE);
            var cubemapTexture = new Texture(TextureTarget.TextureCubeMap, cubemapFiller,
                                             new SamplerParameters(
                                                 TextureWrapping.ClampToEdge,
                                                 TextureWrapping.ClampToEdge,
                                                 TextureWrapping.ClampToEdge,
                                                 TextureFilter.Linear,
                                                 TextureFilter.Linear));

            cubemapTexture.Initialize();

            cubeMapImages.Dispose();
            return(cubemapTexture);
        }
Beispiel #7
0
        //https://stackoverflow.com/questions/34250742/converting-a-cubemap-into-equirectangular-panorama
        //https://github.com/adamb70/Python-Spherical-Projection/blob/master/cube2equi.py
        //https://stackoverflow.com/questions/11504584/cubic-to-equirectangular-projection-algorithm
        private Bitmap ConvertToEquirectangular(CubemapImages cubeMap)
        {
            CubemapHelper.FillAnyNullWithBlanks(cubeMap);
            CubemapHelper.UpsizeAnyPartials(cubeMap);

            DirectBitmap[] faces = ResizeAndConverCubeToDirectBitmap(cubeMap);

            int cubeFaceWidth  = faces[0].Width;
            int cubeFaceHeight = cubeFaceWidth;

            // this block is to calculate a size that has a comparable pixel density to that of the combined input images
            int factor          = 256;
            int nearestMultiple = 0;
            {
                int cubePixelCount      = cubeFaceHeight * cubeFaceWidth;
                int totalCubePixelCount = cubePixelCount * 6;

                int sizeToGetComparablePixelDensity = (int)Math.Sqrt(totalCubePixelCount / 2);
                nearestMultiple =
                    (int)Math.Round(
                        (sizeToGetComparablePixelDensity / (double)factor),
                        MidpointRounding.AwayFromZero
                        ) * factor;
            }
            int outputHeight = nearestMultiple + factor; // round it up
            int outputWidth  = outputHeight * 2;

            // make the projection a multiple of the width of the combined images
            int scale_factor     = 4;
            int projectionWidth  = (cubeFaceWidth * 4) * scale_factor;
            int projectionHeight = projectionWidth / 2;

            DirectBitmap equiTexture = new DirectBitmap(projectionWidth, projectionHeight);

            //Normalised UV texture coordinates, from 0 to 1, starting at lower left corner
            double u_coordinate;
            double v_coordinate;
            //Polar coordinates
            double latitude;
            double longitude;
            //Unit vector
            double x, y, z;
            double xAxis, yAxis, zAxis;
            double largestComponent;

            double[] vector = new double[3];

            Color color;
            Point pixelCoord;

            double normX;
            double normY;

            //int modulousFactorX = outputWidth / 16;
            //int modulousFactorY = outputHeight / 8;
            //bool horizontalMarker = false;
            //bool verticalMarker = false;

            for (int heightIndex = 0; heightIndex < equiTexture.Height; heightIndex++)
            {
                //verticalMarker = heightIndex % modulousFactorX == 0;

                v_coordinate = 1 - ((double)heightIndex / equiTexture.Height);
                latitude     = v_coordinate * Math.PI;

                for (int widthIndex = 0; widthIndex < equiTexture.Width; widthIndex++)
                {
                    //horizontalMarker = widthIndex % modulousFactorY == 0;

                    u_coordinate = ((double)widthIndex / equiTexture.Width);
                    longitude    = u_coordinate * 2 * Math.PI;

                    //assuming Y+ is up, X+ is right, Z+ is front

                    //Calculate unit vector
                    x = Math.Sin(longitude) * Math.Sin(latitude) * -1;
                    y = Math.Cos(latitude);
                    z = Math.Cos(longitude) * Math.Sin(latitude) * -1;

                    vector[0]        = Math.Abs(x);
                    vector[1]        = Math.Abs(y);
                    vector[2]        = Math.Abs(z);
                    largestComponent = vector.Max();
                    // PROBLEM : there are cases where the vertical boundary between cube faces
                    // results in both the x and z components to be equivalent
                    // so both axis return a 1, which

                    //Vector Parallel to the unit vector that lies on one of the cube faces
                    xAxis = x / largestComponent;
                    yAxis = y / largestComponent;
                    zAxis = z / largestComponent;

                    //bool debug = true;
                    //if (debug && verticalMarker && horizontalMarker)
                    //{
                    //    MessageBox.Show(
                    //        "h:" + heightIndex + " w:" + widthIndex +
                    //        "\r\nlat:" + latitude + " long:" + longitude +
                    //        "\r\nx:" + x + " y:" + y + " z:" + z
                    //        );
                    //    color = Color.Purple;
                    //}

                    if (xAxis == 1)
                    {
                        //Right
                        normX      = (((zAxis + 1f) / 2f) - 1f);
                        normY      = (((yAxis + 1f) / 2f));
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[4].Width, faces[4].Height);
                        color      = faces[4].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else if (xAxis == -1)
                    {
                        //Left
                        normX      = ((zAxis + 1) / 2);
                        normY      = ((yAxis + 1) / 2);
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[3].Width, faces[3].Height);
                        color      = faces[3].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else if (yAxis == -1)
                    {
                        //Up
                        normX      = ((xAxis + 1f) / 2f);
                        normY      = ((zAxis + 1f) / 2f);
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[5].Width, faces[5].Height);
                        color      = faces[5].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else if (yAxis == 1)
                    {
                        //Down
                        normX      = ((xAxis + 1f) / 2f);
                        normY      = (((zAxis + 1f) / 2f) - 1f);
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[1].Width, faces[1].Height);
                        color      = faces[1].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else if (zAxis == 1)
                    {
                        //Front
                        normX      = ((xAxis + 1f) / 2f);
                        normY      = ((yAxis + 1f) / 2f);
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[2].Width, faces[2].Height);
                        color      = faces[2].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else if (zAxis == -1)
                    {
                        //Back
                        normX      = (((xAxis + 1f) / 2f) - 1f);
                        normY      = ((yAxis + 1f) / 2f);
                        pixelCoord = GetPixelCoordinates(normX, normY, faces[0].Width, faces[0].Height);
                        color      = faces[0].GetPixel(pixelCoord.X, pixelCoord.Y);
                    }
                    else
                    {
                        throw new Exception("Unknown face, something went wrong");
                    }

                    equiTexture.SetPixel(widthIndex, heightIndex, color);
                }
            }
            var downscaled = ResizeImage(equiTexture.Bitmap, equiTexture.Width / scale_factor, equiTexture.Height / scale_factor);

            return(downscaled);
        }
Beispiel #8
0
 public Bitmap ConstructProjection(CubemapImages images)
 {
     return(ConvertToEquirectangular(images));
 }