예제 #1
0
        public static BitmapSource BuildOptTexture(Texture texture, int paletteIndex = TextureUtils.DefaultPalette, int level = 0)
        {
            if (texture == null || paletteIndex < 0 || paletteIndex > 15 || level < 0 || level >= texture.MipmapsCount)
                return null;

            int bpp = texture.BitsPerPixel;

            if (bpp == 8)
            {
                var palette = new BitmapPalette(Enumerable.Range(0, 256)
                    .Select(i =>
                    {
                        ushort c = BitConverter.ToUInt16(texture.Palette, paletteIndex * 512 + i * 2);

                        byte r = (byte)((c & 0xF800) >> 11);
                        byte g = (byte)((c & 0x7E0) >> 5);
                        byte b = (byte)(c & 0x1F);

                        r = (byte)((r * (0xffU * 2) + 0x1fU) / (0x1fU * 2));
                        g = (byte)((g * (0xffU * 2) + 0x3fU) / (0x3fU * 2));
                        b = (byte)((b * (0xffU * 2) + 0x1fU) / (0x1fU * 2));

                        return Color.FromRgb(r, g, b);
                    })
                    .ToList());

                int texWidth;
                int texHeight;
                byte[] texImageData = texture.GetMipmapImageData(level, out texWidth, out texHeight);

                int size = texWidth * texHeight;
                byte[] imageData = new byte[size * 4];

                for (int i = 0; i < size; i++)
                {
                    int colorIndex = texImageData[i];

                    imageData[i * 4 + 0] = palette.Colors[colorIndex].B;
                    imageData[i * 4 + 1] = palette.Colors[colorIndex].G;
                    imageData[i * 4 + 2] = palette.Colors[colorIndex].R;
                    imageData[i * 4 + 3] = texture.AlphaData == null ? (byte)255 : texture.AlphaData[i];
                }

                return BitmapSource.Create(texWidth, texHeight, 96, 96, PixelFormats.Bgra32, null, imageData, texWidth * 4);
            }
            else if (bpp == 32)
            {
                int texWidth;
                int texHeight;
                byte[] texImageData = texture.GetMipmapImageData(level, out texWidth, out texHeight);

                return BitmapSource.Create(texWidth, texHeight, 96, 96, PixelFormats.Bgra32, null, texImageData, texWidth * 4);
            }
            else
            {
                return null;
            }
        }
예제 #2
0
        private void ExecuteSaveAsCommand(Texture texture)
        {
            if (texture == null)
            {
                return;
            }

            BusyIndicatorService.Run(() =>
            {
                string fileName = FileDialogService.GetSaveTextureFileName(texture.Name);

                if (fileName == null)
                {
                    return;
                }

                try
                {
                    texture.Save(fileName);
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(texture.Name, ex));
                }
            });
        }
예제 #3
0
        private void ExecuteReplaceMapCommand(Texture texture)
        {
            if (texture == null)
            {
                return;
            }

            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenTextureFileName(texture.Name);

                if (fileName == null)
                {
                    return;
                }

                try
                {
                    var newTexture = Texture.FromFile(fileName);
                    newTexture.Name = texture.Name;

                    this.OptModel.File.Textures[newTexture.Name] = newTexture;

                    dispatcher(() => this.OptModel.File = this.OptModel.File);
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(texture.Name, ex));
                }
            });
        }
예제 #4
0
        private void ExecuteReplaceAlphaMapCommand(Texture texture)
        {
            if (texture == null)
            {
                return;
            }

            BusyIndicatorService.Run(dispatcher =>
            {
                string name = texture.Name + "_alpha";
                string fileName = FileDialogService.GetOpenTextureFileName(name);

                if (fileName == null)
                {
                    return;
                }

                try
                {
                    this.OptModel.File.Textures[texture.Name].SetAlphaMap(fileName);

                    dispatcher(() => this.OptModel.File = this.OptModel.File);
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(name, ex));
                }
            });
        }
예제 #5
0
        private static Texture GetFileBitmap(Bitmap image)
        {
            var rect = new Rectangle(0, 0, image.Width, image.Height);
            int length = image.Width * image.Height;

            byte[] bytes = new byte[length * 4];

            using (var bitmap = image.Clone(rect, PixelFormat.Format32bppArgb))
            {
                var data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

                try
                {
                    Marshal.Copy(data.Scan0, bytes, 0, length * 4);
                }
                finally
                {
                    bitmap.UnlockBits(data);
                }
            }

            byte[] alphaData = new byte[length];
            bool hasAlpha = false;

            for (int i = 0; i < length; i++)
            {
                byte a = bytes[i * 4 + 3];

                alphaData[i] = a;

                if (a != (byte)255)
                {
                    hasAlpha = true;
                }
            }

            var texture = new Texture();

            texture.Width = image.Width;
            texture.Height = image.Height;
            texture.ImageData = bytes;
            texture.AlphaData = hasAlpha ? alphaData : null;
            texture.Palette = new byte[8192];

            return texture;
        }
예제 #6
0
        public static bool AreEquals(Texture textureA, Texture textureB)
        {
            if (textureA == null || textureB == null)
            {
                return false;
            }

            if (textureA.Width == 0 || textureA.Height == 0 || textureA.ImageData == null)
            {
                return false;
            }

            if (textureB.Width == 0 || textureB.Height == 0 || textureB.ImageData == null)
            {
                return false;
            }

            if (textureA.Width != textureB.Width)
            {
                return false;
            }

            if (textureA.Height != textureB.Height)
            {
                return false;
            }

            if ((textureA.Palette != null) != (textureB.Palette != null))
            {
                return false;
            }

            if (textureA.Palette != null)
            {
                if (textureA.Palette.Length != textureB.Palette.Length)
                {
                    return false;
                }

                for (int i = 0; i < textureA.Palette.Length; i++)
                {
                    if (textureA.Palette[i] != textureB.Palette[i])
                    {
                        return false;
                    }
                }
            }

            if (textureA.ImageData.Length != textureB.ImageData.Length)
            {
                return false;
            }

            for (int i = 0; i < textureA.ImageData.Length; i++)
            {
                if (textureA.ImageData[i] != textureB.ImageData[i])
                {
                    return false;
                }
            }

            if ((textureA.AlphaData != null) != (textureB.AlphaData != null))
            {
                return false;
            }

            if (textureA.AlphaData != null)
            {
                if (textureA.AlphaData.Length != textureB.AlphaData.Length)
                {
                    return false;
                }

                for (int i = 0; i < textureA.AlphaData.Length; i++)
                {
                    if (textureA.AlphaData[i] != textureB.AlphaData[i])
                    {
                        return false;
                    }
                }
            }

            return true;
        }
예제 #7
0
        public static OptFile An8ToOpt(string an8Path, bool scale)
        {
            string an8Directory = Path.GetDirectoryName(an8Path);

            var an8 = An8File.FromFile(an8Path);
            var opt = new OptFile();

            foreach (var mesh in an8.Objects
                .SelectMany(t => t.Components)
                .SelectMany(t => Converter.EnumMeshes(t)))
            {
                var optMesh = new Mesh();
                opt.Meshes.Add(optMesh);

                if (scale)
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor));
                    }
                }
                else
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y));
                    }
                }

                foreach (var v in mesh.TexCoords)
                {
                    optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V));
                }

                foreach (var v in mesh.Normals)
                {
                    optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y));
                }

                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1));

                var optLod = new MeshLod();
                optMesh.Lods.Add(optLod);

                foreach (var face in mesh.Faces)
                {
                    if (face.PointIndexes.Length < 3)
                    {
                        continue;
                    }

                    bool isQuad = face.PointIndexes.Length > 3;

                    var optFaceGroup = new FaceGroup();
                    optLod.FaceGroups.Add(optFaceGroup);

                    var materialName = mesh.MaterialList.ElementAtOrDefault(face.MaterialIndex);

                    if (!string.IsNullOrEmpty(materialName))
                    {
                        optFaceGroup.Textures.Add(materialName);
                    }

                    Index verticesIndex = new Index(
                        face.PointIndexes[0],
                        face.PointIndexes[1],
                        face.PointIndexes[2],
                        isQuad ? face.PointIndexes[3] : -1);

                    if (verticesIndex.A >= optMesh.Vertices.Count)
                    {
                        verticesIndex.A = 0;
                    }

                    if (verticesIndex.B >= optMesh.Vertices.Count)
                    {
                        verticesIndex.B = 0;
                    }

                    if (verticesIndex.C >= optMesh.Vertices.Count)
                    {
                        verticesIndex.C = 0;
                    }

                    if (verticesIndex.D >= optMesh.Vertices.Count)
                    {
                        verticesIndex.D = 0;
                    }

                    Index textureCoordinatesIndex = new Index(
                        face.TexCoordIndexes[0],
                        face.TexCoordIndexes[1],
                        face.TexCoordIndexes[2],
                        isQuad ? face.TexCoordIndexes[3] : -1);

                    if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.A = 0;
                    }

                    if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.B = 0;
                    }

                    if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.C = 0;
                    }

                    if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.D = 0;
                    }

                    Index vertexNormalsIndex = new Index(
                        face.NormalIndexes[0],
                        face.NormalIndexes[1],
                        face.NormalIndexes[2],
                        isQuad ? face.NormalIndexes[3] : -1);

                    if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.A = 0;
                    }

                    if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.B = 0;
                    }

                    if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.C = 0;
                    }

                    if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.D = 0;
                    }

                    if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0))
                    {
                        textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4;
                        textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3;
                        textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2;
                        textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1;
                    }

                    Vector normal = Vector.Normal(
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.A),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.B),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.C));

                    if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0))
                    {
                        optMesh.VertexNormals.Add(normal);

                        vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1;
                    }

                    var optFace = new Face()
                    {
                        VerticesIndex = verticesIndex,
                        TextureCoordinatesIndex = textureCoordinatesIndex,
                        VertexNormalsIndex = vertexNormalsIndex,
                        Normal = normal
                    };

                    optFaceGroup.Faces.Add(optFace);
                }
            }

            opt.CompactBuffers();
            opt.ComputeHitzones();

            foreach (var material in an8.Materials
                .Concat(an8.Objects.SelectMany(t => t.Materials))
                .Where(t => t.FrontSurface != null)
                .Select(t => new
                {
                    Name = t.Name,
                    Diffuse = t.FrontSurface.Diffuse,
                    Alpha = t.FrontSurface.Alpha
                }))
            {
                Texture texture;

                var an8Texture = material.Diffuse.TextureName != null ?
                    an8.Textures.FirstOrDefault(t => string.Equals(t.Name, material.Diffuse.TextureName, StringComparison.Ordinal)) :
                    null;

                if (an8Texture == null)
                {
                    byte r = material.Diffuse.Red;
                    byte g = material.Diffuse.Green;
                    byte b = material.Diffuse.Blue;

                    int width = 8;
                    int height = 8;
                    int length = width * height;
                    byte[] data = new byte[length * 4];

                    for (int i = 0; i < length; i++)
                    {
                        data[i * 4 + 0] = b;
                        data[i * 4 + 1] = g;
                        data[i * 4 + 2] = r;
                        data[i * 4 + 3] = 255;
                    }

                    texture = new Texture();
                    texture.Name = material.Name;
                    texture.Width = width;
                    texture.Height = height;
                    texture.ImageData = data;
                }
                else
                {
                    string colorFileName = Path.Combine(an8Directory, Path.GetFileName(an8Texture.Files[0]));

                    texture = Texture.FromFile(colorFileName);
                    texture.Name = material.Name;
                }

                if (material.Alpha > 0 && material.Alpha < 255)
                {
                    byte alpha = (byte)material.Alpha;

                    int length = texture.Width * texture.Height;

                    byte[] alphaData = new byte[length];
                    var data = texture.ImageData;

                    for (int i = 0; i < length; i++)
                    {
                        alphaData[i] = alpha;
                        data[i * 4 + 3] = alpha;
                    }

                    texture.AlphaData = alphaData;
                }

                opt.Textures.Add(texture.Name, texture);
            }

            opt.GenerateTexturesMipmaps();

            return opt;
        }
예제 #8
0
        public static OptFile ObjToOpt(string objPath, bool scale)
        {
            string objDirectory = Path.GetDirectoryName(objPath);

            var obj = ObjFile.FromFile(objPath);
            var opt = new OptFile();

            foreach (var mesh in obj.Meshes)
            {
                var optMesh = new Mesh();
                opt.Meshes.Add(optMesh);

                if (scale)
                {
                    foreach (var v in obj.Vertices)
                    {
                        optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor));
                    }
                }
                else
                {
                    foreach (var v in obj.Vertices)
                    {
                        optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y));
                    }
                }

                foreach (var v in obj.VertexTexCoords)
                {
                    optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V));
                }

                foreach (var v in obj.VertexNormals)
                {
                    optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y));
                }

                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1));

                var optLod = new MeshLod();
                optMesh.Lods.Add(optLod);

                foreach (var faceGroup in mesh.FaceGroups)
                {
                    var optFaceGroup = new FaceGroup();
                    optLod.FaceGroups.Add(optFaceGroup);

                    if (!string.IsNullOrEmpty(faceGroup.MaterialName))
                    {
                        optFaceGroup.Textures.Add(faceGroup.MaterialName);
                    }

                    foreach (var face in faceGroup.Faces)
                    {
                        Index verticesIndex = new Index(
                                face.VerticesIndex.A,
                                face.VerticesIndex.B,
                                face.VerticesIndex.C,
                                face.VerticesIndex.D);

                        if (verticesIndex.A >= optMesh.Vertices.Count)
                        {
                            verticesIndex.A = 0;
                        }

                        if (verticesIndex.B >= optMesh.Vertices.Count)
                        {
                            verticesIndex.B = 0;
                        }

                        if (verticesIndex.C >= optMesh.Vertices.Count)
                        {
                            verticesIndex.C = 0;
                        }

                        if (verticesIndex.D >= optMesh.Vertices.Count)
                        {
                            verticesIndex.D = 0;
                        }

                        Index textureCoordinatesIndex = new Index(
                                face.VertexTexCoordsIndex.A,
                                face.VertexTexCoordsIndex.B,
                                face.VertexTexCoordsIndex.C,
                                face.VertexTexCoordsIndex.D);

                        if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.A = 0;
                        }

                        if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.B = 0;
                        }

                        if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.C = 0;
                        }

                        if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.D = 0;
                        }

                        Index vertexNormalsIndex = new Index(
                                face.VertexNormalsIndex.A,
                                face.VertexNormalsIndex.B,
                                face.VertexNormalsIndex.C,
                                face.VertexNormalsIndex.D);

                        if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.A = 0;
                        }

                        if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.B = 0;
                        }

                        if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.C = 0;
                        }

                        if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.D = 0;
                        }

                        if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0))
                        {
                            textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4;
                            textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3;
                            textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2;
                            textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1;
                        }

                        Vector normal = Vector.Normal(
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.A),
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.B),
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.C));

                        if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0))
                        {
                            optMesh.VertexNormals.Add(normal);

                            vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1;
                        }

                        var optFace = new Face()
                        {
                            VerticesIndex = verticesIndex,
                            TextureCoordinatesIndex = textureCoordinatesIndex,
                            VertexNormalsIndex = vertexNormalsIndex,
                            Normal = normal
                        };

                        optFaceGroup.Faces.Add(optFace);
                    }
                }
            }

            opt.CompactBuffers();
            opt.ComputeHitzones();

            foreach (var material in obj.Materials.Values)
            {
                Texture texture;

                if (material.DiffuseMapFileName == null)
                {
                    var color = material.DiffuseColor;
                    byte r = (byte)(color.X * 255.0f);
                    byte g = (byte)(color.Y * 255.0f);
                    byte b = (byte)(color.Z * 255.0f);

                    int width = 8;
                    int height = 8;
                    int length = width * height;
                    byte[] data = new byte[length * 4];

                    for (int i = 0; i < length; i++)
                    {
                        data[i * 4 + 0] = b;
                        data[i * 4 + 1] = g;
                        data[i * 4 + 2] = r;
                        data[i * 4 + 3] = 255;
                    }

                    texture = new Texture();
                    texture.Name = material.Name;
                    texture.Width = width;
                    texture.Height = height;
                    texture.ImageData = data;
                }
                else
                {
                    string colorFileName = Path.Combine(objDirectory, material.DiffuseMapFileName);

                    texture = Texture.FromFile(colorFileName);
                    texture.Name = material.Name;
                }

                if (material.AlphaMapFileName != null)
                {
                    string alphaFileName = Path.Combine(objDirectory, material.AlphaMapFileName);

                    texture.SetAlphaMap(alphaFileName);
                }
                else if (material.DissolveFactor > 0.0f && material.DissolveFactor < 1.0f)
                {
                    byte alpha = (byte)(material.DissolveFactor * 255.0f);

                    int length = texture.Width * texture.Height;

                    byte[] alphaData = new byte[length];
                    var data = texture.ImageData;

                    for (int i = 0; i < length; i++)
                    {
                        alphaData[i] = alpha;
                        data[i * 4 + 3] = alpha;
                    }

                    texture.AlphaData = alphaData;
                }

                opt.Textures.Add(texture.Name, texture);
            }

            opt.GenerateTexturesMipmaps();

            return opt;
        }
예제 #9
0
        public static BitmapSource BuildOptTextureAlpha(Texture texture)
        {
            if (texture == null || !texture.HasAlpha)
            {
                return null;
            }

            int size = texture.Width * texture.Height;

            byte[] imageData = new byte[size];
            Array.Copy(texture.AlphaData, imageData, size);

            return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Gray8, null, imageData, texture.Width);
        }
예제 #10
0
        public static BitmapSource BuildOptTexture(Texture texture, int paletteIndex)
        {
            if (texture == null || paletteIndex < 0 || paletteIndex > 15)
            {
                return null;
            }

            int size = texture.Width * texture.Height;
            int bpp = texture.BitsPerPixel;

            if (bpp == 8)
            {
                var palette = new BitmapPalette(Enumerable.Range(0, 256)
                    .Select(i =>
                    {
                        ushort c = BitConverter.ToUInt16(texture.Palette, paletteIndex * 512 + i * 2);

                        byte r = (byte)((c & 0xF800) >> 11);
                        byte g = (byte)((c & 0x7E0) >> 5);
                        byte b = (byte)(c & 0x1F);

                        r = (byte)((r * (0xffU * 2) + 0x1fU) / (0x1fU * 2));
                        g = (byte)((g * (0xffU * 2) + 0x3fU) / (0x3fU * 2));
                        b = (byte)((b * (0xffU * 2) + 0x1fU) / (0x1fU * 2));

                        return Color.FromRgb(r, g, b);
                    })
                    .ToList());

                //if (texture.AlphaData == null)
                //{
                //    byte[] imageData = new byte[size];
                //    Array.Copy(texture.ImageData, imageData, size);

                //    return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Indexed8, palette, imageData, texture.Width);
                //}
                //else
                {
                    byte[] imageData = new byte[size * 4];

                    for (int i = 0; i < size; i++)
                    {
                        int colorIndex = texture.ImageData[i];

                        imageData[i * 4 + 0] = palette.Colors[colorIndex].B;
                        imageData[i * 4 + 1] = palette.Colors[colorIndex].G;
                        imageData[i * 4 + 2] = palette.Colors[colorIndex].R;
                        //imageData[i * 4 + 3] = texture.AlphaData[i];
                        imageData[i * 4 + 3] = texture.AlphaData != null ? texture.AlphaData[i] : (byte)255;
                    }

                    return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4);
                }
            }
            else if (bpp == 32)
            {
                byte[] imageData = new byte[size * 4];
                Array.Copy(texture.ImageData, imageData, size * 4);

                return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4);
            }
            else
            {
                return null;
            }
        }
예제 #11
0
 public static BitmapSource BuildOptTexture(Texture texture)
 {
     return TextureHelpers.BuildOptTexture(texture, TextureHelpers.DefaultPalette);
 }
예제 #12
0
        private void CreateTexture(TextureNode textureNode)
        {
            if (textureNode.Name == null)
            {
                textureNode.Name = string.Format(CultureInfo.InvariantCulture, "Tex{0}", textureNode.UniqueId);
            }

            Texture texture = new Texture();
            texture.Name = textureNode.Name;

            if (textureNode.Width == 0 || textureNode.Height == 0)
            {
                Texture id = this.Textures.Values
                    .FirstOrDefault(t => t.Id == textureNode.UniqueId);

                if (id == null && this.Textures.Count != 0)
                {
                    id = this.Textures.ElementAt(this.Textures.Count - 1).Value;
                }

                if (id == null)
                {
                    throw new InvalidDataException("invalid 0x0 texture");
                }

                texture.Id = id.Id;
                texture.Width = id.Width;
                texture.Height = id.Height;
                texture.Palette = id.Palette;
                texture.ImageData = id.ImageData;
                texture.AlphaData = id.AlphaData;
            }
            else
            {
                texture.Id = textureNode.UniqueId;
                texture.Width = textureNode.Width;
                texture.Height = textureNode.Height;
                texture.Palette = textureNode.Palettes;
                texture.ImageData = textureNode.Bytes;

                TextureAlphaNode alphaNode = (TextureAlphaNode)textureNode.Nodes
                    .FirstOrDefault(t => t.NodeType == NodeType.TextureAlpha);

                if (alphaNode != null)
                {
                    texture.AlphaData = alphaNode.Bytes;
                }
            }

            this.Textures.Add(texture.Name, texture);
        }
예제 #13
0
        public static OptFile RhinoToOpt(string rhinoPath, bool scale)
        {
            string rhinoDirectory = Path.GetDirectoryName(rhinoPath);

            var opt = new OptFile();

            using (var file = Rhino.FileIO.File3dm.Read(rhinoPath))
            {
                float scaleFactor = scale ? (1.0f / OptFile.ScaleFactor) : 1.0f;

                if (file.Settings.ModelUnitSystem != Rhino.UnitSystem.Meters)
                {
                    scaleFactor *= (float)Rhino.RhinoMath.UnitScale(file.Settings.ModelUnitSystem, Rhino.UnitSystem.Meters);
                    scale = true;
                }

                var groups = file.Objects
                    .Where(t =>
                    {
                        using (var geometry = t.Geometry)
                        {
                            return geometry.ObjectType == Rhino.DocObjects.ObjectType.Mesh;
                        }
                    })
                    .GroupBy(t =>
                    {
                        using (var attributes = t.Attributes)
                        {
                            return attributes.LayerIndex;
                        }
                    })
                    .ToList();

                foreach (var group in groups)
                {
                    var mesh = new Mesh();
                    opt.Meshes.Add(mesh);

                    var lod = new MeshLod();
                    mesh.Lods.Add(lod);

                    foreach (var obj in group)
                    {
                        var faceGroup = new FaceGroup();
                        lod.FaceGroups.Add(faceGroup);

                        int baseIndex = mesh.Vertices.Count;

                        using (var geometry = (Rhino.Geometry.Mesh)obj.Geometry)
                        {
                            if (scale)
                            {
                                foreach (var vertex in geometry.Vertices)
                                {
                                    mesh.Vertices.Add(new Vector(vertex.X * scaleFactor, vertex.Y * scaleFactor, vertex.Z * scaleFactor));
                                }
                            }
                            else
                            {
                                foreach (var vertex in geometry.Vertices)
                                {
                                    mesh.Vertices.Add(new Vector(vertex.X, vertex.Y, vertex.Z));
                                }
                            }

                            foreach (var texCoords in geometry.TextureCoordinates)
                            {
                                mesh.TextureCoordinates.Add(new TextureCoordinates(texCoords.X, -texCoords.Y));
                            }

                            foreach (var normal in geometry.Normals)
                            {
                                mesh.VertexNormals.Add(new Vector(normal.X, normal.Y, normal.Z));
                            }

                            foreach (var geoFace in geometry.Faces)
                            {
                                var face = new Face();
                                faceGroup.Faces.Add(face);

                                Index index = geoFace.IsTriangle ?
                                    new Index(baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A) :
                                    new Index(baseIndex + geoFace.D, baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A);

                                face.VerticesIndex = index;
                                face.VertexNormalsIndex = index;
                                face.TextureCoordinatesIndex = index;

                                face.Normal = Vector.Normal(mesh.Vertices[index.A], mesh.Vertices[index.B], mesh.Vertices[index.C]);
                            }
                        }

                        using (var attributes = obj.Attributes)
                        {
                            if (attributes.MaterialIndex != -1)
                            {
                                using (var material = file.Materials[attributes.MaterialIndex])
                                {
                                    faceGroup.Textures.Add(material.Name);
                                }
                            }
                        }
                    }
                }

                opt.CompactBuffers();
                opt.ComputeHitzones();

                for (int materialIndex = 0; materialIndex < file.Materials.Count; materialIndex++)
                {
                    using (var material = file.Materials[materialIndex])
                    {
                        if (opt.Textures.ContainsKey(material.Name))
                        {
                            continue;
                        }

                        string colorMap = null;
                        string alphaMap = null;

                        using (var tex = material.GetBitmapTexture())
                        {
                            if (tex != null && !string.IsNullOrEmpty(tex.FileName))
                            {
                                colorMap = Path.GetFileName(tex.FileName);
                            }
                        }

                        using (var tex = material.GetTransparencyTexture())
                        {
                            if (tex != null && !string.IsNullOrEmpty(tex.FileName))
                            {
                                alphaMap = Path.GetFileName(tex.FileName);
                            }
                        }

                        Texture texture;

                        if (colorMap == null)
                        {
                            var color = material.DiffuseColor;
                            byte r = color.R;
                            byte g = color.G;
                            byte b = color.B;

                            int width = 8;
                            int height = 8;
                            int length = width * height;
                            byte[] data = new byte[length * 4];

                            for (int i = 0; i < length; i++)
                            {
                                data[i * 4 + 0] = b;
                                data[i * 4 + 1] = g;
                                data[i * 4 + 2] = r;
                                data[i * 4 + 3] = 255;
                            }

                            texture = new Texture();
                            texture.Name = material.Name;
                            texture.Width = width;
                            texture.Height = height;
                            texture.ImageData = data;
                        }
                        else
                        {
                            string colorFileName = Path.Combine(rhinoDirectory, colorMap);

                            texture = Texture.FromFile(colorFileName);
                            texture.Name = material.Name;
                        }

                        if (alphaMap != null)
                        {
                            string alphaFileName = Path.Combine(rhinoDirectory, alphaMap);

                            texture.SetAlphaMap(alphaFileName);
                        }
                        else if (material.Transparency > 0.0 && material.Transparency < 1.0)
                        {
                            byte alpha = (byte)(material.Transparency * 255.0f);

                            int length = texture.Width * texture.Height;

                            byte[] alphaData = new byte[length];
                            var data = texture.ImageData;

                            for (int i = 0; i < length; i++)
                            {
                                alphaData[i] = alpha;
                                data[i * 4 + 3] = alpha;
                            }

                            texture.AlphaData = alphaData;
                        }

                        opt.Textures.Add(texture.Name, texture);
                    }
                }

                opt.GenerateTexturesMipmaps();
            }

            return opt;
        }