示例#1
0
        private void GenerateTexGenBPCommands(Material mat, List <BinaryTextureImage> textures)
        {
            for (int i = 0; i < 8; i++)
            {
                if (mat.TexCoord1Gens[i] == null)
                {
                    continue;
                }

                BPCommand suSizeMask = new BPCommand()
                {
                    Register = BPRegister.BP_MASK
                };
                suSizeMask.SetBits(0x03FFFF, 0, 24);

                BPCommand sSize = new BPCommand()
                {
                    Register = BPRegister.SU_SSIZE0 + (i * 2)
                };
                sSize.SetFlag(false, 16);
                BPCommand tSize = new BPCommand()
                {
                    Register = BPRegister.SU_TSIZE0 + (i * 2)
                };
                tSize.SetFlag(false, 16);

                BinaryTextureImage curTex = textures[mat.TextureIndices[i]];
                sSize.SetBits(curTex.Width - 1, 0, 16);
                tSize.SetBits(curTex.Height - 1, 0, 16);

                BPCommands.Add(suSizeMask);
                BPCommands.Add(sSize);
                BPCommands.Add(tSize);
            }
        }
示例#2
0
文件: TEX1.cs 项目: magcius/JStudio
        public Texture(string name, BinaryTextureImage compressedData)
        {
            Name           = name;
            CompressedData = compressedData;

            m_glTextureIndex = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, m_glTextureIndex);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)GXToOpenGL.GetWrapMode(compressedData.WrapS));
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)GXToOpenGL.GetWrapMode(compressedData.WrapT));
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)GXToOpenGL.GetMinFilter(compressedData.MinFilter));
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)GXToOpenGL.GetMagFilter(compressedData.MagFilter));

            // Border Color
            WLinearColor borderColor = compressedData.BorderColor;

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, new[] { borderColor.R, borderColor.G, borderColor.B, borderColor.A });

            // ToDo: Min/Mag LOD & Biases

            // Upload Image Data
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, compressedData.Width, compressedData.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, compressedData.GetData());

            // Generate Mip Maps
            if (compressedData.MipMapCount > 0)
            {
                GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
            }
        }
示例#3
0
        public TEX1(EndianBinaryReader reader, int offset)
        {
            Textures = new List <BinaryTextureImage>();

            reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);
            reader.SkipInt32();
            int   tex1Size = reader.ReadInt32();
            short texCount = reader.ReadInt16();

            reader.SkipInt16();

            int textureHeaderOffset    = reader.ReadInt32();
            int textureNameTableOffset = reader.ReadInt32();

            List <string> names = NameTableIO.Load(reader, offset + textureNameTableOffset);

            reader.BaseStream.Seek(textureHeaderOffset + offset, System.IO.SeekOrigin.Begin);

            for (int i = 0; i < texCount; i++)
            {
                reader.BaseStream.Seek((offset + 0x20 + (0x20 * i)), System.IO.SeekOrigin.Begin);

                BinaryTextureImage img = new BinaryTextureImage(names[i]);
                img.Load(reader, (offset + 0x20 + (0x20 * i)));
                Textures.Add(img);
            }
        }
示例#4
0
        private void LoadTexturesFromJson(string headers_path, string directory_path)
        {
            JsonSerializer serial = new JsonSerializer();

            serial.Formatting = Formatting.Indented;
            serial.Converters.Add(new StringEnumConverter());

            using (StreamReader strm_reader = new StreamReader(headers_path))
            {
                strm_reader.BaseStream.Seek(0, SeekOrigin.Begin);
                JsonTextReader reader = new JsonTextReader(strm_reader);
                Textures = serial.Deserialize <List <BinaryTextureImage> >(reader);
            }

            foreach (BinaryTextureImage tex in Textures)
            {
                // We'll search for duplicate texture names.
                BinaryTextureImage duplicate_search = Textures.Find(x => x.Name == tex.Name);

                // Otherwise we have to load the image from disk
                string name_without_ext = Path.Combine(directory_path, tex.Name);
                string full_img_path    = FindImagePath(name_without_ext);

                if (full_img_path == "")
                {
                    Console.WriteLine($"Could not find texture \"{ name_without_ext }\". It will not be imported.");
                    continue;
                }

                tex.LoadImageFromDisk(full_img_path);
            }
        }
示例#5
0
文件: TEX1.cs 项目: CryZe/WindEditor2
        private static List <Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart)
        {
            ushort           textureCount        = reader.ReadUInt16();
            ushort           padding             = reader.ReadUInt16(); // Usually 0xFFFF?
            uint             textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart.
            uint             stringTableOffset   = reader.ReadUInt32(); // One filename per texture. relative to chunkStart.
            List <Texture2D> textureList         = new List <Texture2D>();

            // Get all Texture Names
            reader.BaseStream.Position = chunkStart + stringTableOffset;
            StringTable stringTable = StringTable.FromStream(reader);

            for (int t = 0; t < textureCount; t++)
            {
                // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file.
                reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20);
                BinaryTextureImage texture = new BinaryTextureImage();
                texture.Load(reader, chunkStart + 0x20, t);

                Texture2D texture2D = new Texture2D(texture.Width, texture.Height);
                texture2D.Name      = stringTable[t];
                texture2D.PixelData = texture.GetData();
                textureList.Add(texture2D);


                string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t));
            }

            return(textureList);
        }
示例#6
0
        public TexBlock(EndianBinaryReader reader)
        {
            Images   = new List <BinaryTextureImage>();
            Textures = new List <Texture>();

            // Get the offset of the TexBlock, save the reader's current offset, then go to the TexBlock
            int  offset    = reader.ReadInt32();
            long curOffset = reader.BaseStream.Position;

            reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);

            // Get the offset of the first texture's image data
            int firstTexOffset = offset + reader.ReadInt32At(offset + 8);

            // We'll read texture data as long as the next image's width isn't 0 and
            // the stream's position isn't at the place where the first texture's image data starts.
            while (reader.PeekReadInt16() != 0 && reader.BaseStream.Position != firstTexOffset)
            {
                BinaryTextureImage tex = new BinaryTextureImage();
                tex.LoadBinTex(reader, offset);
                Images.Add(tex);
            }

            //DumpTextures(@"D:\SZS Tools\TextureTest");

            reader.BaseStream.Seek(curOffset, System.IO.SeekOrigin.Begin);
        }
示例#7
0
        /// <summary>
        /// Reads in the clamp settings and mipmap count for each texture.
        /// Textures are often duplicated to have one image with multiple pairs of clamp settings.
        /// </summary>
        /// <param name="reader"></param>
        public void GetTextureSettings(EndianBinaryReader reader)
        {
            // Get the offset of the TexBlock, get the offset of the next section, save the reader's current offset,
            // then go to the TextureSettings section
            int  offset            = reader.ReadInt32();
            int  nextSectionOffset = reader.PeekReadInt32();
            long curOffset         = reader.BaseStream.Position;

            reader.BaseStream.Seek(offset, System.IO.SeekOrigin.Begin);

            // New list to store the images with proper clamp settings
            List <BinaryTextureImage> newImageList = new List <BinaryTextureImage>();

            while ((reader.PeekReadInt32() & 0xFFFF) == 0xFFFF && reader.BaseStream.Position != nextSectionOffset)
            {
                // Create a new texture from the texture at the index provided
                BinaryTextureImage modifiedTex = new BinaryTextureImage(Images[reader.ReadInt16()]);
                reader.SkipInt16(); // Padding, 0xFFFF
                modifiedTex.SetTexSettingsFromBin(reader);
                newImageList.Add(modifiedTex);
                Textures.Add(new Texture(modifiedTex));
            }

            // Replace original list of textures
            Images = newImageList;
            DumpTextures(@"D:\SZS Tools\TextureTest");

            reader.BaseStream.Seek(curOffset, System.IO.SeekOrigin.Begin);
        }
示例#8
0
文件: TEX1.cs 项目: CryZe/WindEditor2
        private static List<Texture2D> LoadTEX1FromFile(EndianBinaryReader reader, long chunkStart)
        {
            ushort textureCount = reader.ReadUInt16();
            ushort padding = reader.ReadUInt16(); // Usually 0xFFFF?
            uint textureHeaderOffset = reader.ReadUInt32(); // textureCount # bti image headers are stored here, relative to chunkStart.
            uint stringTableOffset = reader.ReadUInt32(); // One filename per texture. relative to chunkStart.
            List<Texture2D> textureList = new List<Texture2D>();

            // Get all Texture Names
            reader.BaseStream.Position = chunkStart + stringTableOffset;
            StringTable stringTable = StringTable.FromStream(reader);

            for (int t = 0; t < textureCount; t++)
            {
                // 0x20 is the length of the BinaryTextureImage header which all come in a row, but then the stream gets jumped around while loading the BTI file.
                reader.BaseStream.Position = chunkStart + textureHeaderOffset + (t * 0x20);
                BinaryTextureImage texture = new BinaryTextureImage();
                texture.Load(reader, chunkStart + 0x20, t);

                Texture2D texture2D = new Texture2D(texture.Width, texture.Height);
                texture2D.Name = stringTable[t];
                texture2D.PixelData = texture.GetData();
                textureList.Add(texture2D);

                string executionPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                texture.SaveImageToDisk(executionPath + "/TextureDump/" + string.Format("{0}_({1}-{2}).png", stringTable[t], texture.Format, t));
            }

            return textureList;
        }
示例#9
0
        public void SetTexture(Grendgine_Collada_Texture sourceTex, string texName, Bitmap bmp)
        {
            BinaryTextureImage tex = null;

            // Check to see if we need an alpha channel in our texture
            bool hasAlpha = HasAlpha(bmp);

            // If so, we'll use RGB565
            if (hasAlpha)
            {
                tex = new BinaryTextureImage(texName, bmp, BinaryTextureImage.TextureFormats.RGBA32);

                // This sets the alpha compare settings so that alpha is set correctly.
                // It won't allow translucency, just a sharp transparent/opaque dichotemy.
                AlphCompare.Comp0      = GXCompareType.GEqual;
                AlphCompare.Comp1      = GXCompareType.LEqual;
                AlphCompare.Operation  = GXAlphaOp.And;
                AlphCompare.Reference0 = 0x80;
                AlphCompare.Reference1 = 0xFF;

                // We'll default to showing the texture on both sides for now. Maybe it'll be changable in the future
                CullMode = GXCullMode.None;

                // Make sure z compare happens *after* texture look up so we can take the alpha compare results into account
                ZCompLoc = false;
            }
            // Otherwise, we'll use CMPR to save space
            else
            {
                tex = new BinaryTextureImage(texName, bmp, BinaryTextureImage.TextureFormats.CMPR);
            }

            tex.SetTextureSettings(sourceTex);
            CullMode = GXCullMode.None;

            // Search for an open texture slot and if there is one, put the texture there,
            // Include tex cooord gens,
            // Include a tex matrix,
            // And configure tev orders
            for (int i = 0; i < 8; i++)
            {
                if (Textures[i] == null)
                {
                    Textures[i]      = tex;
                    TexCoord1Gens[i] = new TexCoordGen(GXTexGenType.Matrix2x4, GXTexGenSrc.Tex0 + i, GXTexMatrix.TexMtx0);
                    TexMatrix1[i]    = new TexMatrix();

                    TevOrders[i].TexCoordId = GXTexCoordSlot.TexCoord0 + i;
                    TevOrders[i].TexMap     = (byte)i;
                    TevOrders[i].ChannelId  = GXColorChannelId.Color0A0;
                    break;
                }
            }

            TevStages[0].ColorIn[0] = GXCombineColorInput.TexColor;
            TevStages[0].ColorIn[1] = GXCombineColorInput.TexColor;
            TevStages[0].AlphaIn[0] = GXCombineAlphaInput.TexAlpha;
        }
示例#10
0
        private int GetGLTexIdFromCache(int j3dTextureId)
        {
            if (_textureCache.ContainsKey(j3dTextureId))
            {
                return(_textureCache[j3dTextureId]);
            }

            //Console.WriteLine("Generating GL texture for id: " + j3dTextureId);

            //Look up the material first.
            //_file.Materials.GetMaterialRemapTable((ushort)j3dTextureId);
            J3DFormat.MaterialInitData matData = _file.Materials.GetMaterialInitData(_file.Materials.GetMaterialRemapTable((ushort)j3dTextureId));

            //If the texture cache doesn't contain the ID, we're going to load it here.

            ushort textureIndex = matData.GetTextureIndex(0);

            if (textureIndex == 0xFF || textureIndex == 0xFFFF)
            {
                _textureCache[j3dTextureId] = 0;
                return(0);
            }
            BinaryTextureImage image = _file.Textures.GetTexture(_file.Materials.GetMaterialIndex(textureIndex));

            //image.WriteImageToFile("image_" + matChunk.GetMaterialIndex(matData.GetTextureIndex(0)) + image.Format + ".png");

            byte[] imageData   = image.GetData();
            ushort imageWidth  = image.Width;
            ushort imageHeight = image.Height;

            //Generate a black and white textureboard if the texture format is not supported.
            if (imageData.Length == 0)
            {
                imageData = new byte[]
                {
                    0, 0, 0, 255, 255, 255, 255, 255,
                    255, 255, 255, 255, 0, 0, 0, 255
                };
                imageWidth  = 2;
                imageHeight = 2;
            }


            int glTextureId;

            GL.GenTextures(1, out glTextureId);
            GL.BindTexture(TextureTarget.Texture2D, glTextureId);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.Repeat);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, imageWidth, imageHeight, 0, PixelFormat.Bgra, PixelType.UnsignedInt8888Reversed, imageData);


            _textureCache[j3dTextureId] = glTextureId;
            return(glTextureId);
        }
示例#11
0
文件: TEX1.cs 项目: kai13xd/SuperBMD
        private void LoadTexturesFromScene(Assimp.Scene scene, string model_directory, Arguments cmdargs)
        {
            foreach (Assimp.Mesh mesh in scene.Meshes)
            {
                Console.Write(mesh.Name);
                Assimp.Material mat = scene.Materials[mesh.MaterialIndex];

                if (mat.HasTextureDiffuse)
                {
                    string texname       = System.IO.Path.GetFileNameWithoutExtension(mat.TextureDiffuse.FilePath);
                    bool   isEmbedded    = false;
                    int    embeddedIndex = -1;

                    if (mat.TextureDiffuse.FilePath.StartsWith("*"))
                    {
                        string index = mat.TextureDiffuse.FilePath.Substring(1, mat.TextureDiffuse.FilePath.Length);;
                        isEmbedded = int.TryParse(index, out embeddedIndex);
                        texname    = String.Format("embedded_tex{0}", embeddedIndex);
                    }

                    bool already_exists = false;

                    foreach (BinaryTextureImage image in Textures)
                    {
                        if (image.Name == texname)
                        {
                            already_exists = true;
                            break;
                        }
                    }

                    if (already_exists)
                    {
                        continue;
                    }

                    BinaryTextureImage img = new BinaryTextureImage();

                    if (isEmbedded)
                    {
                        Assimp.EmbeddedTexture embeddedTexture = scene.Textures[embeddedIndex];
                        img.Load(mat.TextureDiffuse, embeddedTexture);
                    }
                    else
                    {
                        img.Load(mat.TextureDiffuse, model_directory, cmdargs.readMipmaps);
                    }
                    Textures.Add(img);
                }
                else
                {
                    Console.WriteLine(" -> Has No Textures");
                }
            }
        }
示例#12
0
 public Material(EndianBinaryReader stream, uint texOffset)
 {
     //Console.WriteLine("Reading Material at 0x{0:X}", stream.BaseStream.Position);
     textureIndex = stream.ReadInt16();
     stream.SkipInt16();
     wrapU = stream.ReadByte();
     wrapV = stream.ReadByte();
     stream.SkipInt16();
     stream.Skip(12);
     texture = new BinaryTextureImage(stream, texOffset + (0xC * textureIndex), texOffset);
 }
示例#13
0
        /// <summary>
        /// This is used to emulate a feature used in The Legend of Zelda: The Wind Waker. In WW all characters appear to share
        /// their Toon texture lookup image. The J3D files include a texture in their files which is a black/white checkerboard
        /// that is a placeholder for the one the game overrides. Unfortunately, if we use the black/white checkerboard then lighting
        /// gets broken, so this function is provided to optionally override a texture name with a specific texture, such as the
        /// texture name "ZBtoonEX" used by WW.
        /// </summary>
        /// <param name="textureName">Name of the texture to override. All textures with this name will be overriden.</param>
        /// <param name="filePath">Path to the texture to use.</param>
        public void SetTextureOverride(string textureName, string filePath)
        {
            BinaryTextureImage btiData = new BinaryTextureImage();

            btiData.LoadImageFromDisk(filePath);
            if (m_textureOverrides.ContainsKey(textureName))
            {
                m_textureOverrides[textureName].Dispose();
            }

            m_textureOverrides[textureName] = new Texture(textureName, btiData);
        }
示例#14
0
文件: TEX1.cs 项目: kai13xd/SuperBMD
        public void AddTextureFromPath(string path, bool readMipmaps)
        {
            string             modelDirectory = System.IO.Path.GetDirectoryName(path);
            BinaryTextureImage img            = new BinaryTextureImage();

            // Only the path and the wrap mode are relevant, the rest doesn't matter for img.Load
            TextureSlot tex = new TextureSlot(path, 0, 0, 0, 0, (float)0.0, 0, TextureWrapMode.Clamp, TextureWrapMode.Clamp, 0);

            img.Load(tex, modelDirectory, readMipmaps);

            Textures.Add(img);
        }
示例#15
0
        private void LoadTexturesFromScene(Assimp.Scene scene, string model_directory)
        {
            foreach (Assimp.Mesh mesh in scene.Meshes)
            {
                Assimp.Material mat = scene.Materials[mesh.MaterialIndex];

                if (mat.HasTextureDiffuse)
                {
                    BinaryTextureImage img = new BinaryTextureImage();
                    img.Load(mat.TextureDiffuse, model_directory);
                    Textures.Add(img);
                }
            }
        }
示例#16
0
        public TEX1(Assimp.Scene scene, string modelDirectory)
        {
            Textures = new List <BinaryTextureImage>();

            foreach (Assimp.Material mat in scene.Materials)
            {
                if (mat.HasTextureDiffuse)
                {
                    BinaryTextureImage img = new BinaryTextureImage();
                    img.Load(mat.TextureDiffuse, modelDirectory);
                    Textures.Add(img);
                }
            }
        }
示例#17
0
文件: TEX1.cs 项目: magcius/JStudio
        protected virtual void Dispose(bool manualDispose)
        {
            if (!m_hasBeenDisposed)
            {
                if (manualDispose)
                {
                    // TODO: dispose managed state (managed objects).
                }

                GL.DeleteTexture(m_glTextureIndex);

                // Set large fields to null.
                CompressedData    = null;
                m_hasBeenDisposed = true;
            }
        }
示例#18
0
        private ObservableCollection <BinaryTextureImage> LoadImages(string[] paths)
        {
            if (ImageList == null)
            {
                ImageList = new ObservableCollection <BinaryTextureImage>();
            }

            ObservableCollection <BinaryTextureImage> tempList = ImageList;

            foreach (string path in paths)
            {
                BinaryTextureImage openedImage = null;

                // Open a BTI
                if (path.EndsWith(".bti"))
                {
                    using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        EndianBinaryReader reader = new EndianBinaryReader(stream, Endian.Big);

                        openedImage = new BinaryTextureImage();

                        openedImage.Load(reader, path, 0);
                    }
                }
                // Open a PNG
                else if (path.EndsWith(".png") || path.EndsWith(".PNG"))
                {
                    Bitmap input = new Bitmap(path);

                    openedImage = new BinaryTextureImage(path, input, BinaryTextureImage.TextureFormats.PNG);
                }
                // Open a TGA
                else if (path.EndsWith(".tga"))
                {
                    Bitmap input = TgaReader.Load(path);

                    openedImage = new BinaryTextureImage(path, input, BinaryTextureImage.TextureFormats.TGA);
                }

                tempList.Add(openedImage);
            }

            return(tempList);
        }
示例#19
0
文件: TEX1.cs 项目: magcius/JStudio
        public void LoadTEX1FromStream(EndianBinaryReader reader, long tagStart, bool dumpTextures)
        {
            ushort numTextures = reader.ReadUInt16();

            Trace.Assert(reader.ReadUInt16() == 0xFFFF); // Padding

            int textureHeaderDataOffset = reader.ReadInt32();
            int stringTableOffset       = reader.ReadInt32();

            // Texture Names
            reader.BaseStream.Position = tagStart + stringTableOffset;
            StringTable nameTable = StringTable.FromStream(reader);

            Textures = new BindingList <Texture>();
            for (int t = 0; t < numTextures; t++)
            {
                // Reset the stream position to the start of this header as loading the actual data of the texture
                // moves the stream head around.
                reader.BaseStream.Position = tagStart + textureHeaderDataOffset + (t * 0x20);

                BinaryTextureImage compressedTex = new BinaryTextureImage();
                string             tempFileName  = string.Format("TextureDump/{1}_{0}.png", nameTable[t], t);
                if (!m_allowTextureCache || !File.Exists(tempFileName))
                {
                    compressedTex.Load(reader, tagStart + 0x20 /* Size of TEX1 header?*/, t);
                }
                else
                {
                    compressedTex.LoadImageFromDisk(tempFileName);
                }

                Texture texture = new Texture(nameTable[t], compressedTex);
                Textures.Add(texture);

                if (dumpTextures)
                {
                    compressedTex.SaveImageToDisk(string.Format("TextureDump/{2}__{0}_{1}_{3}.png", texture.Name, compressedTex.Format, t, compressedTex.PaletteFormat));
                }
            }
        }
示例#20
0
        /// <summary>
        /// Pass this a Room&lt;x&gt; folder or a Stage folder directory! This will look for specific subfolders
        /// (bdl, btk, dzb, dzr, dzs, dat, etc.) and load each file within them as appropriate.
        /// </summary>
        /// <param name="directory">Absolute file path to a folder containing a bdl/btk/etc. files(s)</param>
        public void LoadFromDirectory(string directory)
        {
            if (!Directory.Exists(directory))
            {
                new Exception("Invalid directory specified for WorldspaceProject.");
            }

            //Get all of the sub folders (bdl, btk, etc.)
            string[] subFolders = Directory.GetDirectories(directory);

            foreach (string folder in subFolders)
            {
                //Then grab all of the files that are inside this folder and we'll load each one.
                string[] subFiles = Directory.GetFiles(folder);

                foreach (string filePath in subFiles)
                {
                    BinaryReader    br = new BinaryReader(File.OpenRead(filePath));
                    BaseArchiveFile file;

                    byte[] fileData = br.ReadBytes((int)br.BaseStream.Length);
                    switch ((new DirectoryInfo(folder).Name).ToLower())
                    {
                    /* Map Collision Format */
                    case "dzb":
                        file = new StaticCollisionModel();
                        break;

                    /* Room and Stage Entity Data */
                    case "dzr":
                    case "dzs":
                        //Apparently Nintendo likes to mis-categorize files sometimes and put the wrong
                        //file format inside the wrong folder! We'll name-check dzr and dzs before loading
                        //them as they have fixed names (Room.*)
                        if (filePath.EndsWith(".dzr") || filePath.EndsWith(".dzs"))
                        {
                            file = new WindWakerEntityData();
                        }
                        else
                        {
                            file = new GenericArchiveData();
                        }
                        break;

                    /* 3D Model Formats */
                    case "bmd":
                    case "bdl":
                        file = new JStudioModel();
                        break;

                    case "tex":
                        file = new BinaryTextureImage();
                        break;

                    case "bck":
                    case "brk":
                    case "btk":
                    default:
                        Console.WriteLine("Unknown file extension {0} found ({1}). Creating GenericData holder for it!", Path.GetExtension(filePath), Path.GetFileName(filePath));
                        file = new GenericArchiveData();
                        break;
                    }

                    file.FileName      = Path.GetFileName(filePath);
                    file.FolderName    = new DirectoryInfo(folder).Name;
                    file.ParentArchive = this;
                    file.Load(fileData);

                    //Now that we've created the appropriate file (and hopefully mapped them all out!) we'll just stick
                    //it in our list of loaded files. They can later be gotten with the templated getter!
                    _archiveFiles.Add(file);
                    br.Close();
                }
            }
        }
示例#21
0
        public MdlModel(string path)
        {
            m_Counts          = new ushort[20];
            m_Offsets         = new long[18];
            shapes            = new List <GXBatch>();
            globalMatrixTable = new List <Matrix4>();
            textures          = new List <BinaryTextureImage>();

            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                EndianBinaryReader stream = new EndianBinaryReader(fs, Endian.Big);
                stream.ReadInt32();                 //ignore the magic
                for (int i = 0; i < 20; i++)
                {
                    m_Counts[i] = stream.ReadUInt16();
                }
                stream.BaseStream.Seek(0x30, 0);
                for (int i = 0; i < 18; i++)
                {
                    m_Offsets[i] = stream.ReadUInt32();
                }

                verticies    = fromVec3(LoadSection <vec3>(stream, 6, 6));
                normals      = fromVec3(LoadSection <vec3>(stream, 7, 7));
                uvs          = fromVec2(LoadSection <vec2>(stream, 9, 9));
                drawelements = LoadSection <DrawElement>(stream, 17, 17);
                shapepackets = LoadSection <ShapePacket>(stream, 1, 3);
                materials    = LoadSection <Material>(stream, 14, 18);
                texobjs      = LoadSection <TexObj>(stream, 15, 16);

                stream.BaseStream.Seek(m_Offsets[2], 0);
                for (int i = 0; i < m_Counts[5]; i++)
                {
                    Matrix4 mat = new Matrix4(
                        new Vector4(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
                        new Vector4(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
                        new Vector4(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()),
                        new Vector4(0, 0, 0, 1)
                        );
                    globalMatrixTable.Add(mat.Inverted());
                }
                for (int i = 0; i < m_Counts[4]; i++)
                {
                    globalMatrixTable.Add(Matrix4.Identity);
                }

                stream.BaseStream.Seek(m_Offsets[16], 0);
                for (int i = 0; i < m_Counts[19]; i++)
                {
                    GXBatch bat = new GXBatch();
                    bat.LoadMdlBatch(stream, shapepackets, globalMatrixTable, verticies);
                    shapes.Add(bat);
                }

                /*
                 * foreach (var packet in shapepackets)
                 * {
                 *      //create local matrix table for shape packet
                 *      Matrix4[] localMats = new Matrix4[packet.numMatIndicies];
                 *      for (int i = 0; i < packet.numMatIndicies; i++)
                 *      {
                 *              if (packet.matIndicies[i] != 0xFFFF)
                 *              {
                 *                      localMats[i] = globalMatrixTable[packet.matIndicies[i]];
                 *              } else {break;}
                 *      }
                 *      //apply to shapes
                 *      foreach (GXBatch shape in shapes)
                 *      {
                 *              if (shape.ActiveAttributes.Contains(GXAttribute.PositionMatrixIndex))
                 *              {
                 *                      foreach (var vert in shape.RawVertices)
                 *                      {
                 *                              var matIndex = vert.Indices[shape.ActiveAttributes.IndexOf(GXAttribute.PositionMatrixIndex)];
                 *                              Console.WriteLine($"Mat Index: {matIndex}\nLocal Matrix List Size: {localMats.Length}");
                 *                              if(shape.ActiveAttributes.Contains(GXAttribute.PositionMatrixIndex)){
                 *                                      Matrix4 mat = localMats[matIndex];
                 *                                      Vector4 pos = new Vector4(verticies[vert.Indices[shape.ActiveAttributes.IndexOf(GXAttribute.Position)]]);
                 *                                      Vector4.Transform(pos, mat);
                 *                                      verticies[vert.Indices[shape.ActiveAttributes.IndexOf(GXAttribute.Position)]] = new Vector3(pos);
                 *                              }
                 *                      }
                 *              }
                 *      }
                 * }*/

                stream.BaseStream.Seek(m_Offsets[12], SeekOrigin.Begin);
                for (int i = 0; i < m_Counts[14]; i++)
                {
                    int  textureOffset = stream.ReadInt32();
                    long nextOffsetPos = stream.BaseStream.Position;

                    stream.BaseStream.Seek(textureOffset, SeekOrigin.Begin);
                    BinaryTextureImage img = new BinaryTextureImage();
                    img.Load(stream, textureOffset, 1);
                    textures.Add(img);

                    stream.BaseStream.Seek(nextOffsetPos, SeekOrigin.Begin);
                }

                WriteObj("mdlTest.obj");
            }
        }
示例#22
0
        public void WriteObj(string f)
        {
            //string dirPath = Path.GetDirectoryName(f);
            string fileName = $"{ AppContext.BaseDirectory }\\{ Path.GetFileNameWithoutExtension(f) }";

            StringWriter objWriter = new StringWriter();
            StringWriter mtlWriter = new StringWriter();

            objWriter.WriteLine("# dumped with booldozer");
            objWriter.WriteLine($"mtllib { fileName }.mtl");

            foreach (var vert in verticies)
            {
                objWriter.WriteLine($"v {vert.X} {vert.Y} {vert.Z}");
            }

            if (normals.Count != 0)
            {
                foreach (var vert in normals)
                {
                    objWriter.WriteLine($"vn { vert.X } { vert.Y } { vert.Z }");
                }
            }

            if (uvs.Count != 0)
            {
                foreach (var vert in uvs)
                {
                    objWriter.WriteLine($"vt { vert.X } { 1 - vert.Y }");
                }
            }

            objWriter.WriteLine();

            int index = 0;

            foreach (DrawElement drw in drawelements)
            {
                Material mat = materials[drw.matIndex];
                GXBatch  shp = shapes[drw.shapeIndex];

                mtlWriter.WriteLine($"newmtl { index }");
                mtlWriter.WriteLine($"Kd { ((mat.color & 0xFF000000) >> 24) / 255 } { ((mat.color & 0x00FF0000) >> 16) / 255 } { ((mat.color & 0x0000FF00) >> 8) / 255 }");
                mtlWriter.WriteLine($"d { (mat.color & 0x000000FF) / 255 }");

                if (mat.num_tev_stages > 0)
                {
                    TexObj texObj = texobjs[mat.stages[0].texobj_index];
                    mtlWriter.WriteLine($"map_Kd { index }.png");
                    BinaryTextureImage tex = textures[texObj.textureIndex];
                    tex.SaveImageToDisk($"{ AppContext.BaseDirectory }\\{ index }.png", tex.GetData(), tex.Width, tex.Height);
                }

                objWriter.WriteLine($"o { index }");
                objWriter.WriteLine($"usemtl { index }");

                for (int i = 0; i < shp.RawVertices.Count; i += 3)
                {
                    string[] verts = new string[3] {
                        "", "", ""
                    };

                    for (int j = 0; j < 3; j++)
                    {
                        string pos  = "";
                        string uv   = "";
                        string norm = "";

                        if (shp.ActiveAttributes.Contains(GXAttribute.Position))
                        {
                            pos = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Position)] + 1) }/";
                        }
                        if (shp.ActiveAttributes.Contains(GXAttribute.Tex0))
                        {
                            uv = $"{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Tex0)] + 1) }";
                        }
                        if (shp.ActiveAttributes.Contains(GXAttribute.Normal))
                        {
                            norm = $"/{ Convert.ToString(shp.RawVertices[i + j].Indices[shp.ActiveAttributes.IndexOf(GXAttribute.Normal)] + 1) }/";
                        }

                        verts[j] = $"{ pos }{ uv }{ norm }";
                    }

                    objWriter.WriteLine($"f { verts[0] } { verts[1] } { verts[2] }");
                }

                index++;
            }

            using (FileStream s = new FileStream($"{ fileName }.obj", FileMode.Create, FileAccess.Write))
            {
                EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big);
                w.Write(objWriter.ToString().ToCharArray());
            }

            using (FileStream s = new FileStream($"{ fileName }.mtl", FileMode.Create, FileAccess.Write))
            {
                EndianBinaryWriter w = new EndianBinaryWriter(s, Endian.Big);
                w.Write(mtlWriter.ToString().ToCharArray());
            }
        }
示例#23
0
        private void GenerateTextureCommands(Material mat, List <BinaryTextureImage> textures)
        {
            BPRegister[] texInfoRegs = new BPRegister[] { BPRegister.TX_SETIMAGE0_I0, BPRegister.TX_SETIMAGE0_I1, BPRegister.TX_SETIMAGE0_I2,
                                                          BPRegister.TX_SETIMAGE0_I3, BPRegister.TX_SETIMAGE0_I4, BPRegister.TX_SETIMAGE0_I5,
                                                          BPRegister.TX_SETIMAGE0_I6, BPRegister.TX_SETIMAGE0_I7 };

            BPRegister[] texIndexRegs = new BPRegister[] { BPRegister.TX_SETIMAGE3_I0, BPRegister.TX_SETIMAGE3_I1, BPRegister.TX_SETIMAGE3_I2,
                                                           BPRegister.TX_SETIMAGE3_I3, BPRegister.TX_SETIMAGE3_I4, BPRegister.TX_SETIMAGE3_I5,
                                                           BPRegister.TX_SETIMAGE3_I6, BPRegister.TX_SETIMAGE3_I7 };

            BPRegister[] texMode0Regs = new BPRegister[] { BPRegister.TX_SET_MODE0_I0, BPRegister.TX_SET_MODE0_I1, BPRegister.TX_SET_MODE0_I2,
                                                           BPRegister.TX_SET_MODE0_I3, BPRegister.TX_SET_MODE0_I4, BPRegister.TX_SET_MODE0_I5,
                                                           BPRegister.TX_SET_MODE0_I6, BPRegister.TX_SET_MODE0_I7 };

            BPRegister[] texMode1Regs = new BPRegister[] { BPRegister.TX_SET_MODE1_I0, BPRegister.TX_SET_MODE1_I1, BPRegister.TX_SET_MODE1_I2,
                                                           BPRegister.TX_SET_MODE1_I3, BPRegister.TX_SET_MODE1_I4, BPRegister.TX_SET_MODE1_I5,
                                                           BPRegister.TX_SET_MODE1_I6, BPRegister.TX_SET_MODE1_I7 };

            for (int i = 0; i < 8; i++)
            {
                if (mat.TextureIndices[i] == -1)
                {
                    continue;
                }

                BinaryTextureImage curTex = textures[mat.TextureIndices[i]];

                // Records width, height, and format
                BPCommand texInfo = new BPCommand()
                {
                    Register = texInfoRegs[i]
                };
                texInfo.SetBits(curTex.Width - 1, 0, 10);
                texInfo.SetBits(curTex.Height - 1, 10, 10);
                texInfo.SetBits((int)curTex.Format, 20, 4);

                // Records the index of the texture
                BPCommand texIndex = new BPCommand()
                {
                    Register = texIndexRegs[i]
                };
                texIndex.SetBits(mat.TextureIndices[i], 0, 24);

                BPCommand mode0 = new BPCommand()
                {
                    Register = texMode0Regs[i]
                };
                mode0.SetBits((int)curTex.WrapS, 0, 2);
                mode0.SetBits((int)curTex.WrapT, 2, 2);
                mode0.SetBits((int)curTex.MagFilter, 4, 1);

                switch (curTex.MinFilter)
                {
                case BinaryTextureImage.FilterMode.Nearest:
                    mode0.SetBits(0, 5, 3);
                    break;

                case BinaryTextureImage.FilterMode.Linear:
                    mode0.SetBits(4, 5, 3);
                    break;

                case BinaryTextureImage.FilterMode.NearestMipmapNearest:
                    mode0.SetBits(1, 5, 3);
                    break;

                case BinaryTextureImage.FilterMode.NearestMipmapLinear:
                    mode0.SetBits(2, 5, 3);
                    break;

                case BinaryTextureImage.FilterMode.LinearMipmapNearest:
                    mode0.SetBits(5, 5, 3);
                    break;

                case BinaryTextureImage.FilterMode.LinearMipmapLinear:
                    mode0.SetBits(6, 5, 3);
                    break;
                }

                // Unimplemented:
                mode0.SetFlag(true, 8);   // Edge LOD (diag_lod)
                mode0.SetBits(0, 9, 8);   // LoDBias (lod_bias)
                mode0.SetBits(0, 19, 2);  // Max aniso (max_aniso)
                mode0.SetFlag(false, 21); // Bias Clamp (lod_clamp)
                // MinLOD
                // MaxLOD

                BPCommand mode1 = new BPCommand()
                {
                    Register = texMode1Regs[i]
                };

                BPCommands.Add(texIndex);
                BPCommands.Add(texInfo);
                BPCommands.Add(mode0);
                BPCommands.Add(mode1);
            }
        }