コード例 #1
0
ファイル: PS_Fragment.cs プロジェクト: ST3RmY/Metanoia
        public GenericTexture BakeTexturePalette(GenericTexture t, int pid, List <byte[]> Palette)
        {
            if (pid == -1)
            {
                return(t);
            }

            GenericTexture tex = new GenericTexture();

            tex.Width  = t.Width;
            tex.Height = t.Height;

            tex.Id             = t.Id;
            tex.InternalFormat = PixelInternalFormat.Rgb5A1;
            tex.PixelFormat    = PixelFormat.Rgba;

            byte[] palette = Palette[pid];
            byte[] Data    = new byte[tex.Width * tex.Height * 2];

            for (int i = 0; i < t.Mipmaps[0].Length; i++)
            {
                if (palette.Length > 32)
                {
                    //8bpp
                    Data[i * 2 + 0] = palette[t.Mipmaps[0][i] * 2 + 1];
                    Data[i * 2 + 1] = palette[t.Mipmaps[0][i] * 2];
                }
                else
                {
                    //4bpp
                    int id = t.Mipmaps[0][i];
                    Data[i * 4 + 2] = palette[(id & 0xF) * 2 + 1];
                    Data[i * 4 + 3] = palette[(id & 0xF) * 2];

                    Data[i * 4 + 0] = palette[((id >> 4) & 0xF) * 2 + 1];
                    Data[i * 4 + 1] = palette[((id >> 4) & 0xF) * 2];
                }
            }

            tex.Mipmaps.Add(Data);

            return(tex);
        }
コード例 #2
0
ファイル: RenderTexture.cs プロジェクト: ST3RmY/Metanoia
        public void LoadGenericTexture(GenericTexture Texture)
        {
            if (Texture.Mipmaps.Count == 0)
            {
                return;
            }

            GL.BindTexture(TextureTarget.Texture2D, GLID);

            //todo: compressed
            PixelType PixelType = PixelType.UnsignedByte;

            if (Texture.InternalFormat == PixelInternalFormat.Rgb5A1)
            {
                PixelType = PixelType.UnsignedShort5551;
            }

            if (Texture.InternalFormat == PixelInternalFormat.CompressedRgbS3tcDxt1Ext ||
                Texture.InternalFormat == PixelInternalFormat.CompressedRgbaS3tcDxt5Ext)
            {
                GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, (InternalFormat)Texture.InternalFormat, (int)Texture.Width, (int)Texture.Height, 0, Texture.Mipmaps[0].Length, Texture.Mipmaps[0]);
                Console.WriteLine(GL.GetError() + " " + Texture.Mipmaps[0].Length.ToString("X"));
            }
            else
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, Texture.InternalFormat, (int)Texture.Width, (int)Texture.Height, 0, Texture.PixelFormat, PixelType, Texture.Mipmaps[0]);
            }

            Width  = Texture.Width;
            Height = Texture.Height;

            Console.WriteLine(GLID + " " + Texture.Width + " " + Texture.Height + " " + Texture.InternalFormat + " " + Texture.PixelFormat);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);

            GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

            Loaded = true;
        }
コード例 #3
0
        public static GenericTexture ToGenericTexture(byte[] xifile)
        {
            GenericTexture tex = new GenericTexture();
            Level5_XI      xi  = new Level5_XI();

            xi.Open(xifile);
            if (xi.SwitchFile && xi.ImageFormat == 0x1D)
            {
                tex.Mipmaps.Add(xi.BuildImageDataFromBlock(8)[0]);
                tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbS3tcDxt1Ext;
                tex.Width          = (uint)xi.Height;
                tex.Height         = (uint)xi.Width;
            }
            else
            if (xi.SwitchFile && xi.ImageFormat == 0x1F)
            {
                tex.Mipmaps.Add(xi.BuildImageDataFromBlock(16)[0]);
                tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                tex.Width          = (uint)xi.Height;
                tex.Height         = (uint)xi.Width;
            }
            else
            if (xi.SwitchFile && xi.ImageFormat == 0x1)
            {
                tex.Mipmaps.Add(xi.BuildImageData()[0]);
                tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb8;
                tex.PixelFormat    = OpenTK.Graphics.OpenGL.PixelFormat.Rgb;
                tex.Width          = (uint)xi.Height;
                tex.Height         = (uint)xi.Width;
            }
            else
            {
                var texture = xi.ToBitmap();
                tex.FromBitmap(texture);
                texture.Dispose();
            }
            return(tex);
        }
コード例 #4
0
        public void Open(FileItem File)
        {
            var igb = new IGBFile(File.GetFileBinary());

            var igbSkel = new IGSkeleton(igb);

            Matrix4[] transforms = new Matrix4[igbSkel.Bones.Count];
            Matrix4[] inverts = new Matrix4[igbSkel.Bones.Count];
            int boneIndex = 0;
            foreach (var v in igbSkel.Bones)
            {
                if (v == null)
                    continue;
                GenericBone b = new GenericBone();
                b.Name = v.Name;
                b.ParentIndex = v.ParentIndex;
                transforms[boneIndex] = new Matrix4(
                    v.WorldInverseMatrix.M11, v.WorldInverseMatrix.M12, v.WorldInverseMatrix.M13, v.WorldInverseMatrix.M14,
                    v.WorldInverseMatrix.M21, v.WorldInverseMatrix.M22, v.WorldInverseMatrix.M23, v.WorldInverseMatrix.M24,
                    v.WorldInverseMatrix.M31, v.WorldInverseMatrix.M32, v.WorldInverseMatrix.M33, v.WorldInverseMatrix.M34,
                    v.WorldInverseMatrix.M41, v.WorldInverseMatrix.M42, v.WorldInverseMatrix.M43, v.WorldInverseMatrix.M44);
                inverts[boneIndex] = transforms[boneIndex].Inverted();
                b.Transform = inverts[boneIndex];

                boneIndex++;
                Skeleton.Bones.Add(b);
            }
            
            foreach (var b in Skeleton.Bones)
            {
                if (b.ParentIndex != -1)
                {
                    b.Transform = inverts[b.ParentIndex] * transforms[Skeleton.Bones.IndexOf(b)];
                    b.Transform = b.Transform.Inverted();
                    var position = igbSkel.Bones[Skeleton.Bones.IndexOf(b)].Position;
                    b.Position = new Vector3(position.X, position.Y, position.Z);
                }
            }

            var vertexBuffers = IGVertexAccessor.ToDivaModels(igb);

            Model.Skeleton = Skeleton;

            Console.WriteLine(vertexBuffers.Count);
            foreach (var model in vertexBuffers)
            {
                GenericMesh m = new GenericMesh();
                m.Name = model.Name;
                if (m.Name.Equals(""))
                    m.Name = "Mesh_" + vertexBuffers.IndexOf(model);
                Console.WriteLine(m.Name + " " + !(model.Texture==null));

                if(model.Texture != null)
                {
                    GenericTexture t = new GenericTexture();
                    t.Name = System.IO.Path.GetFileNameWithoutExtension(model.Texture.Name);
                    t.Width = (uint)model.Texture.Width;
                    t.Height = (uint)model.Texture.Height;
                    t.Mipmaps.Add(model.Texture.RGBA);

                    if(!Model.MaterialBank.ContainsKey(t.Name))
                        Model.TextureBank.Add(t.Name, t);

                    GenericMaterial mat = new GenericMaterial();
                    mat.TextureDiffuse = t.Name;

                    if (!Model.MaterialBank.ContainsKey(t.Name))
                        Model.MaterialBank.Add(t.Name, mat);

                    m.MaterialName = t.Name;
                }
                
                foreach (var mesh in model.Mesh)
                {
                    var vertices = ToGenericVertices(mesh.Vertices);
                    foreach (var dl in mesh.DisplayList)
                    {
                        if (dl.PrimitiveType == PrimType.Triangles)
                        {
                            foreach(var f in dl.Indices)
                                m.Vertices.Add(vertices[f]);
                        }
                        if (dl.PrimitiveType == PrimType.TriangleStrip)
                        {
                            var tempList = new List<GenericVertex>();
                            foreach (var f in dl.Indices)
                                tempList.Add(vertices[f]);
                            Tools.TriangleConverter.StripToList(tempList, out tempList);
                            m.Vertices.AddRange(tempList);
                        }
                    }
                }
                

                if(model.SingleBindBone != null && model.SingleBindBone != "")
                {
                    var singleBone = Skeleton.Bones.Find(e => e.Name.Equals(model.SingleBindBone));
                    var singleBindTransform = Skeleton.GetWorldTransform(singleBone);
                    var singleBindIndex = Skeleton.Bones.IndexOf(singleBone);
                    for (int i = 0; i < m.VertexCount;i++)
                    {
                        var vert = m.Vertices[i];
                        vert.Pos = Vector3.TransformPosition(vert.Pos, singleBindTransform);
                        vert.Nrm = Vector3.TransformNormal(vert.Nrm, singleBindTransform);
                        vert.Bones = new Vector4(singleBindIndex, 0, 0, 0);
                        vert.Weights = new Vector4(1, 0, 0, 0);
                        m.Vertices[i] = vert;
                    }
                }

                m.Optimize();

                Model.Meshes.Add(m);
            }
        }
コード例 #5
0
ファイル: HSF.cs プロジェクト: ST3RmY/Metanoia
        private void ReadTextures(DataReader reader, uint offset, int count, uint paletteOffset, int paletteCount, uint stringTableOffset)
        {
            reader.Position = offset;
            var texInfo     = reader.ReadStructArray <TextureInfo>(count);
            var startOffset = reader.Position;

            reader.Position = paletteOffset;
            var palInfo          = reader.ReadStructArray <PaletteInfo>(paletteCount);
            var palSectionOffset = reader.Position;

            for (int i = 0; i < texInfo.Length; i++)
            {
                var textureName = reader.ReadString(stringTableOffset + texInfo[i].NameOffset, -1);
                Console.WriteLine($"{textureName} {texInfo[i].Type1} {texInfo[i].Type2} {texInfo[i].PaletteIndex} {texInfo[i].Width} {texInfo[i].Height} {(startOffset + texInfo[i].DataOffset).ToString("X")}");

                var format = texInfo[i].Type1;

                byte[] palData   = new byte[texInfo[i].Depth * 2];
                var    palFormat = 0;
                var    palCount  = 0;

                switch (texInfo[i].Type1)
                {
                case 0x00:
                    format = 0;
                    break;

                case 0x01:
                    format = 1;
                    break;

                case 0x03:
                    format = 3;
                    break;

                case 0x04:
                    format = 4;
                    break;

                case 0x05:
                    format = 5;
                    break;

                case 0x06:
                    format = 6;
                    break;

                case 0x07:
                    format = 14;
                    break;

                case 0x09:
                    palFormat = 1;
                    format    = 9;
                    if (texInfo[i].Type2 == 4)
                    {
                        format = 8;
                    }
                    break;

                case 0x0A:
                    palFormat = 2;
                    format    = 9;
                    if (texInfo[i].Type2 == 4)
                    {
                        format = 8;
                    }
                    break;

                case 0x0B:
                    palFormat = 1;
                    format    = 9;
                    if (texInfo[i].Type2 == 4)
                    {
                        format = 8;
                    }
                    break;

                default:
                    throw new NotSupportedException("Unsupported Texture Type " + texInfo[i].Type1 + " " + texInfo[i].Type2);
                }

                //var pal = palInfo.ToList().Find(e => e.NameOffset == texInfo[i].NameOffset);
                if (texInfo[i].PaletteIndex > -1)
                {
                    var pal = palInfo[texInfo[i].PaletteIndex];
                    palCount = pal.Count;
                    palData  = reader.GetSection(palSectionOffset + pal.DataOffset, 2 * palCount);
                    Console.WriteLine((palSectionOffset + pal.DataOffset).ToString("X") + " " + (2 * palCount).ToString("X"));
                }

                var dataLength =
                    Tools.TPL.textureByteSize((Tools.TPL_TextureFormat)format, texInfo[i].Width, texInfo[i].Height);
                ;
                Console.WriteLine(textureName + " " + (Tools.TPL_TextureFormat)format + " " + dataLength.ToString("X"));
                reader.Position = startOffset + texInfo[i].DataOffset;

                var bitmap = Tools.TPL.ConvertFromTextureMelee(reader.ReadBytes(dataLength), texInfo[i].Width, texInfo[i].Height, format, palData, palCount, palFormat);//.Save(textureName + ".png");

                GenericTexture t = new GenericTexture();
                t.Name = textureName;
                t.FromBitmap(bitmap);
                bitmap.Dispose();
                Textures.Add(t);
            }
        }
コード例 #6
0
ファイル: PS_Fragment.cs プロジェクト: ST3RmY/Metanoia
        public void Open(FileItem File)
        {
            var Data = File.GetFileBinary();

            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();
            Model.Skeleton.RotationOrder = RotationOrder.ZYX;

            // decompress
            using (DataReader reader = new DataReader(new MemoryStream(Data)))
            {
                reader.BigEndian = true;

                if (reader.BaseStream.Length < 8 || !reader.ReadString(8).Equals("PERS-SZP"))
                {
                    // not compressed
                }
                else
                {
                    reader.BigEndian = true;
                    uint compressedoffset = reader.ReadUInt32();

                    reader.Seek(compressedoffset);
                    Data = Tools.Decompress.YAY0(reader.ReadBytes((int)(reader.BaseStream.Length - compressedoffset)));
                }
            }

            // decode file contents
            using (DataReader reader = new DataReader(new MemoryStream(Data)))
            {
                reader.BigEndian = true;
                reader.Seek(0x8);
                if (!reader.ReadString(8).Equals("FRAGMENT"))
                {
                    return;
                }
                reader.Seek(0x10);
                uint DataOffset            = reader.ReadUInt32();
                uint RelocationTableOffset = reader.ReadUInt32();
                reader.Skip(4); // filesize
                reader.Skip(4); // tableOffset again

                // Relocation Table
                reader.Seek(RelocationTableOffset);
                int   entryCount = reader.ReadInt32();
                int[] offsets    = new int[entryCount];
                for (int i = 0; i < entryCount; i++)
                {
                    int mask = 0xFFFF;
                    offsets[i] = reader.ReadInt32();
                    if (RelocationTableOffset > 0xFFFF)
                    {
                        mask = 0x1FFFF;                                 // hack
                    }
                    uint temp = reader.Position;
                    reader.Seek((uint)(offsets[i] & 0x1FFFF));
                    reader.WriteInt32At(reader.ReadInt32() & mask, offsets[i] & 0x1FFFF);
                    reader.Seek((uint)(offsets[i] & 0x1FFFF));
                    reader.Seek(temp);
                }

                // main data
                reader.Seek(DataOffset);
                reader.Skip(0x10);
                uint mainOffset = reader.ReadUInt32();

                // main stuff
                reader.Seek(mainOffset);
                reader.Skip(8); // i dunno
                uint offsetToTextureOffset = reader.ReadUInt32();

                reader.Seek(offsetToTextureOffset);
                uint textureOffset = reader.ReadUInt32();

                // may be objects instead of just textures
                reader.Seek(textureOffset);
                int  TextureCount  = reader.ReadInt32() & 0xFFFF; // should have 0x17 in front
                int  PaletteCount  = reader.ReadInt16();
                int  VertexCount   = reader.ReadInt16();
                uint TextureOffset = reader.ReadUInt32();
                uint PaletteOffset = reader.ReadUInt32();
                uint VertexOffset  = reader.ReadUInt32();
                reader.Skip(0x1C); //I dunno
                uint objectOffset = reader.ReadUInt32();


                // Textures-------------------------------------------------------
                List <GenericTexture> Textures = new List <GenericTexture>();
                List <byte[]>         Palettes = new List <byte[]>();

                //Read Palettes
                reader.Seek(PaletteOffset);
                for (int i = 0; i < PaletteCount; i++)
                {
                    int  colorcount      = reader.ReadInt32();
                    uint OffsetData      = reader.ReadUInt32();
                    int  OffsetSomething = reader.ReadInt32();
                    Palettes.Add(reader.GetSection(OffsetData, colorcount * 2));
                }

                // Read Textures?
                reader.Seek(TextureOffset);
                //Console.WriteLine(reader.pos().ToString("x"));
                for (int i = 0; i < TextureCount; i++)
                {
                    int  format        = reader.ReadByte();
                    int  bitsize       = reader.ReadByte();
                    uint width         = reader.ReadUInt16();
                    uint height        = reader.ReadUInt16();
                    uint size          = reader.ReadUInt16(); // sometimes 8 maybe an id? pointer?
                    uint texDataOffset = reader.ReadUInt32() & 0x1FFFF;

                    Console.WriteLine("Texture " + format + " " + bitsize + " " + size + " " + width + " " + height);

                    GenericTexture tex = new GenericTexture();
                    Textures.Add(tex);
                    tex.Name = "Texture_" + i;
                    byte[] data;
                    tex.Width  = width;
                    tex.Height = height;

                    tex.PixelFormat = PixelFormat.Rgba;
                    if (format == 4)
                    {
                        // Raw
                        if (bitsize == 1) //RGBA
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Luminance8;
                            tex.PixelFormat    = PixelFormat.Luminance;
                        }
                    }
                    else
                    if (format == 2)
                    {
                        // Paletted

                        if (bitsize == 0) //4bpp
                        {
                            data = reader.GetSection(texDataOffset, (int)size / 2);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Alpha4;
                        }
                        else if (bitsize == 1) //8bpp
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Alpha8;
                        }
                    }
                    else
                    {
                        if (bitsize == 2)
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);
                            // swap endian
                            for (int j = 0; j < data.Length / 2; j++)
                            {
                                byte temp = data[j * 2];
                                data[j * 2]       = data[(j * 2) + 1];
                                data[(j * 2) + 1] = temp;
                            }
                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Rgb5A1;
                        }
                        else if (bitsize == 3)
                        {
                            tex.InternalFormat = PixelInternalFormat.Rgba8;
                            data = reader.GetSection(texDataOffset, (int)size * 4);
                            tex.Mipmaps.Add(data);
                        }
                    }
                }

                // Objects--------------------------------------------------------
                // now parse until end
                bool done = false;
                Stack <GenericBone> boneStack  = new Stack <GenericBone>();
                GenericBone         parentBone = null;

                reader.Seek(objectOffset);
                reader.Skip(4); // idk
                int maybeCount = reader.ReadInt32();

                string          currentMaterialName = "";
                GenericMaterial currentMaterial     = new GenericMaterial();
                GenericBone     CurrentBone         = null;

                while (!done)
                {
                    int doff, temp;
                    //Console.WriteLine(reader.Position().ToString("x") + " " + reader.ReadByte().ToString("x"));
                    reader.ReadByte();
                    reader.Seek(reader.Position - 1);
                    switch (reader.ReadByte())
                    {
                    case 0x03:     // Perhaps some object offset? Offset goes to beginning of file. Material maybe?
                        reader.Skip(0x08 - 1);
                        break;

                    case 0x05:
                        reader.Skip(0x04 - 1);
                        boneStack.Push(CurrentBone);
                        parentBone = boneStack.Peek();
                        break;

                    case 0x06:
                        reader.Skip(0x04 - 1);
                        if (boneStack.Count > 0)
                        {
                            boneStack.Pop();
                            if (boneStack.Count > 0)
                            {
                                parentBone = boneStack.Peek();
                            }
                        }
                        break;

                    case 0x08:
                        reader.Skip(4 - 1);
                        int s1 = reader.ReadByte() & 0x7F;
                        reader.Skip(1);
                        int s2 = reader.ReadInt16();
                        reader.Skip(4);
                        // pops matrix
                        // maybe pop until you get to this bone?
                        //Also maybe some texture thing?
                        Console.WriteLine("What dis?" + " " + s1 + " " + s2);
                        //throw new Exception("Weird Special Thing");

                        /*for (int i = popto - s1; i < popto + s2; i++)
                         * {
                         *  Bone bo = skel.GetBoneByID(i);
                         *  boneStack.Push(bo);
                         * }*/
                        break;

                    case 0x18:     // idk has 4 values
                        reader.Skip(0x08 - 1);
                        break;

                    case 0x1D:
                        int id     = reader.ReadByte();
                        int what   = reader.ReadByte();
                        int parent = (sbyte)reader.ReadByte();

                        // read bone properties
                        Vector3 trans = new Vector3((short)reader.ReadInt16(), (short)reader.ReadInt16(), (short)reader.ReadInt16());
                        Vector3 rot   = new Vector3((short)reader.ReadInt16() / 180, ((short)reader.ReadInt16()) / 180, (short)reader.ReadInt16() / 180);

                        // to radians
                        rot.X = (rot.X * (float)Math.PI) / 180f;
                        rot.Y = (rot.Y * (float)Math.PI) / 180f;
                        rot.Z = (rot.Z * (float)Math.PI) / 180f;

                        //rot = new Vector3(rot.Z, rot.X, rot.Y);

                        Vector3 scale = new Vector3();
                        scale.X = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;
                        scale.Y = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;
                        scale.Z = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;

                        int parent2 = boneStack.Count;

                        GenericBone b = new GenericBone();
                        b.Name = "Bone_" + id;
                        if (parentBone != null)
                        {
                            b.ParentIndex = Model.Skeleton.IndexOf(parentBone);
                        }
                        else
                        {
                            b.ParentIndex = -1;
                        }
                        b.ID       = id;
                        b.Scale    = new Vector3(1, 1, 1);  // scale
                        b.Position = trans;
                        b.Rotation = rot;

                        CurrentBone = b;
                        Model.Skeleton.Bones.Add(b);

                        //Console.WriteLine(reader.Position().ToString("x") + " " + b.Name + " " + b.p1 + " " + what + " " + parent + " " + boneStack.Count + " " + trans.ToString() + " " + rot.ToString() + " " + scale.ToString());
                        //Console.WriteLine(b.transform.ToString());
                        break;

                    case 0x1E:
                        //reader.Skip(3);
                        reader.Skip(1);
                        int w = reader.ReadInt16();     // bone index
                        doff = reader.ReadInt32();
                        temp = (int)reader.Position;

                        reader.Seek((uint)doff);
                        {
                            GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(Model.Skeleton.GetBoneByID(w)), Model.Skeleton.GetWorldTransform(Model.Skeleton.GetBoneByID(w))));
                            mesh.MaterialName = currentMaterialName;
                            Model.Meshes.Add(mesh);
                        }
                        reader.Seek((uint)temp);

                        break;

                    case 0x22:
                        int materialIndex = reader.ReadByte();
                        int ww            = (short)reader.ReadInt16();

                        doff = reader.ReadInt32();
                        temp = (int)reader.Position;
                        if (doff == 0)
                        {
                            continue;
                        }

                        reader.Seek((uint)doff);
                        {
                            GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(parentBone), Model.Skeleton.GetWorldTransform(parentBone)));
                            mesh.MaterialName = currentMaterialName;
                            Model.Meshes.Add(mesh);
                        }
                        reader.Seek((uint)temp);
                        //((DisplayList)DisplayLists.Nodes[DisplayLists.Nodes.Count - 1]).Mat = unk;
                        //Console.WriteLine("Material Maybe 0x" + reader.pos().ToString("x") + " " + unk + " " + .Count);
                        break;

                    case 0x23:
                        reader.Skip(1);
                        int tidunk = (short)reader.ReadInt16();
                        int texOff = reader.ReadInt32();    //& 0x1FFFF Material Offset?
                        int tid    = (short)reader.ReadInt16();
                        int pid    = (short)reader.ReadInt16();
                        reader.Skip(4);    // 0xFF padding
                        //Console.WriteLine("TextureCount " + tid + " " + pid + " " + tidunk + " " + texOfreader.ToString("x"));
                        if (tid != -1)
                        {
                            currentMaterial     = new GenericMaterial();
                            currentMaterialName = "material_" + Model.MaterialBank.Count;
                            var diffuse = BakeTexturePalette(Textures[tid], pid, Palettes);
                            diffuse.Name = "texture_" + Model.TextureBank.Count;
                            currentMaterial.TextureDiffuse = diffuse.Name;
                            Model.TextureBank.Add(diffuse.Name, diffuse);
                            Model.MaterialBank.Add(currentMaterialName, currentMaterial);
                        }
                        else
                        {
                            var currentTexture = currentMaterial.TextureDiffuse;
                            currentMaterial                = new GenericMaterial();
                            currentMaterialName            = "material_" + Model.MaterialBank.Count;
                            currentMaterial.TextureDiffuse = currentTexture;
                            Model.MaterialBank.Add(currentMaterialName, currentMaterial);
                        }

                        // Read Texture Info At Offset
                        int tt = (int)reader.Position;
                        reader.Seek((uint)texOff);
                        ReadTextureCodes(reader, currentMaterial);
                        reader.Seek((uint)tt);
                        break;                        // Texture Binding

                    case 0x24: reader.Skip(3); break; // has to do with matrix popping

                    case 0x25:
                        reader.Skip(0x04 - 1);
                        //Console.WriteLine("Unknown 0x" + reader.pos().ToString("x"));
                        break;

                    default:
                        done = true;
                        break;
                    }
                    ;
                }
            }


            // Post Process

            // optimized texture sharing
            Dictionary <string, string>         newTexName  = new Dictionary <string, string>();
            Dictionary <string, GenericTexture> newTexBank  = new Dictionary <string, GenericTexture>();
            Dictionary <byte[], string>         TextureBank = new Dictionary <byte[], string>();

            foreach (var tex in Model.TextureBank)
            {
                if (!TextureBank.ContainsKey(tex.Value.Mipmaps[0]))
                {
                    string newName = "texture_" + newTexName.Count;
                    newTexName.Add(tex.Key, newName);
                    newTexBank.Add(newName, tex.Value);
                    TextureBank.Add(tex.Value.Mipmaps[0], newName);
                }
                else
                {
                    newTexName.Add(tex.Key, TextureBank[tex.Value.Mipmaps[0]]);
                }
            }

            Model.TextureBank = newTexBank;

            foreach (var mesh in Model.Meshes)
            {
                var material = Model.GetMaterial(mesh);
                if (material != null && material.TextureDiffuse != null)
                {
                    material.TextureDiffuse = newTexName[material.TextureDiffuse];
                }
            }

            Console.WriteLine(TextureBank.Count + " total textures");

            // Transform Verts

            /*int meshindex = 0;
             * foreach(GenericMesh mesh in Model.Meshes)
             * {
             *  mesh.Name = "Mesh_" + meshindex;
             *  GenericVertex[] CorrectedVertices = mesh.Vertices.ToArray();
             *  for(int i =0; i < CorrectedVertices.Length; i++)
             *  {
             *      CorrectedVertices[i].Pos = Vector3.TransformPosition(CorrectedVertices[i].Pos, Model.Skeleton.GetWorldTransform((int)CorrectedVertices[i].Bones.X));
             *  }
             *  mesh.Vertices.Clear();
             *  mesh.Vertices.AddRange(CorrectedVertices);
             * }*/
        }
コード例 #7
0
ファイル: JStar.cs プロジェクト: ST3RmY/Metanoia
        public GenericModel ToGenericModel()
        {
            var mdl = new GenericModel()
            {
                Skeleton = Skeleton
            };;

            byte[] Data      = File.ReadAllBytes(@"chr0020_model.npki");
            byte[] ImageData = File.ReadAllBytes(@"chr0020_model.npkv");

            foreach (var t in TXRs)
            {
                GenericTexture tex = new GenericTexture();
                tex.Width  = (uint)t.Width;
                tex.Height = (uint)t.Height;

                var buf = new byte[t.Width * t.Height / 2];
                Array.Copy(ImageData, t.BufferOffsets[0], buf, 0, buf.Length);
                buf = VitaSwizzle.UnswizzlePS4(buf, t.Width, t.Height);
                tex.Mipmaps.Add(buf);

                tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbS3tcDxt1Ext;

                if (!mdl.TextureBank.ContainsKey(t.Name))
                {
                    mdl.TextureBank.Add(t.Name, tex);
                }

                Console.WriteLine(tex.Width + " " + tex.Height + " " + t.Unknown.ToString("X") + " " + t.BufferOffsets[0].ToString("X") + " " + t.BufferSizes[0].ToString("X"));
            }

            foreach (var v in VTXs)
            {
                if (v.BufferSizes.Length < 2)
                {
                    continue;
                }
                GenericMesh m = new GenericMesh();
                mdl.Meshes.Add(m);
                m.Name = v.Name;

                using (DataReader r = new DataReader(Data))
                {
                    for (uint i = 0; i < v.BufferSizes[1]; i += 2)
                    {
                        r.Seek((uint)v.BufferOffsets[1] + i);
                        //r.PrintPosition();
                        var index = r.ReadInt16();

                        GenericVertex vert = new GenericVertex();

                        foreach (var attr in v.Attribtues)
                        {
                            r.Seek((uint)(v.BufferOffsets[0] + v.BufferInfos[attr.RESBufferIndex].Offset + index * v.BufferInfos[attr.RESBufferIndex].Stride + attr.BufferOffset));

                            switch (attr.AttributeName)
                            {
                            case 1:
                                vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;

                            case 2:
                                vert.Nrm = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;

                            case 5:
                                vert.UV0 = new OpenTK.Vector2(r.ReadSingle(), r.ReadSingle());
                                break;

                            case 8:
                                var b1 = v.Bones[r.ReadInt32()];
                                var b2 = v.Bones[r.ReadInt32()];
                                var b3 = v.Bones[r.ReadInt32()];
                                var b4 = v.Bones[r.ReadInt32()];
                                vert.Bones = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(b1)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b2)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b3)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b4)));
                                break;

                            case 7:
                                vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;
                            }
                        }

                        if (v.Bones.Count == 1)
                        {
                            vert.Bones   = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(v.Bones[0])), 0, 0, 0);
                            vert.Weights = new OpenTK.Vector4(1, 0, 0, 0);
                        }

                        m.Vertices.Add(vert);
                        m.Triangles.Add(i / 2);

                        //Console.WriteLine(index + " " + v.BufferOffsets[0].ToString("X") + " " + v.BufferInfos[0].Offset + " " + v.BufferInfos[0].Stride);
                    }
                    //m.Optimize();
                }
            }

            return(mdl);
        }
コード例 #8
0
        private void ParseTextures(string path)
        {
            using (DataReader r = new DataReader(path))
            {
                r.BigEndian = false;

                r.Seek(0x0C);
                var offset = r.ReadUInt32();
                var count  = r.ReadInt32();

                r.Seek(offset);

                for (int i = 0; i < count; i++)
                {
                    var off  = offset + r.ReadUInt32();
                    var temp = r.Position;
                    r.Seek(off);

                    int mipMap = r.ReadByte();
                    int T      = r.ReadByte();
                    int W      = r.ReadByte();
                    r.Skip(1);

                    var flags = r.ReadInt32();

                    if ((flags >> 24) == 0x10)
                    {
                        r.Skip(0xC);
                    }

                    int H = (int)Math.Pow(2, (W >> 4));
                    W = (int)Math.Pow(2, (W & 0xF));

                    Console.WriteLine(W + " " + H + " " + T + " " + r.Position.ToString("X"));

                    GenericTexture t = new GenericTexture();

                    var size = (int)r.Length - (int)r.Position;
                    if (T == 0x59)
                    {
                        size = W * H / 2;

                        t.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbS3tcDxt1Ext;
                    }
                    else
                    if (T == 0x5B)
                    {
                        size = W * H;

                        t.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                    }
                    else
                    {
                        continue;
                    }

                    t.Width  = (uint)W;
                    t.Height = (uint)H;
                    t.Mipmaps.Add(r.GetSection(r.Position, size));
                    Textures.Add(t);

                    r.Seek(temp);
                }
            }
        }
コード例 #9
0
ファイル: JetFusion.cs プロジェクト: ST3RmY/Metanoia
        public void Open(FileItem File)
        {
            var skelPath    = File.FilePath.Replace(".mdg", ".anm");
            var skelAngPath = File.FilePath.Replace(".mdg", ".ang");
            var modelPath   = File.FilePath.Replace(".mdg", ".mdl");
            var texPath     = File.FilePath.Replace(".mdg", ".tex");

            if (!System.IO.File.Exists(skelPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelPath));
                return;
            }
            if (!System.IO.File.Exists(skelAngPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelAngPath));
                return;
            }
            if (!System.IO.File.Exists(modelPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Model File " + Path.GetFileName(modelPath));
                return;
            }

            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();

            if (System.IO.File.Exists(texPath))
            {
                using (DataReader r = new DataReader(new FileStream(texPath, FileMode.Open)))
                {
                    r.BigEndian = true;

                    var unk        = r.ReadInt32();
                    var width      = r.ReadInt32();
                    var height     = r.ReadInt32();
                    var dataLength = r.ReadInt32();
                    var padding    = r.ReadInt32();
                    var format     = r.ReadByte();
                    var data       = r.GetSection(0x20, (int)(r.BaseStream.Length - 0x20));

                    var bmp = HSDLib.Helpers.TPL.ConvertFromTextureMelee(data, width, height, (int)TPL_TextureFormat.CMP, null, 0, 0);

                    GenericTexture t = new GenericTexture();
                    t.FromBitmap(bmp);

                    bmp.Dispose();

                    Model.TextureBank.Add("texture", t);
                    Model.MaterialBank.Add("material", new GenericMaterial()
                    {
                        TextureDiffuse = "texture"
                    });
                }
            }

            using (DataReader r = new DataReader(new FileStream(skelPath, FileMode.Open)))
            {
                r.BigEndian = false;

                r.ReadInt32(); // magic
                r.ReadInt32(); // header
                var boneCount  = r.ReadInt32();
                var boneOffset = r.ReadUInt32();

                using (DataReader angr = new DataReader(new FileStream(skelAngPath, FileMode.Open)))
                {
                    angr.BigEndian = false;
                    for (int i = 0; i < boneCount; i++)
                    {
                        r.Seek(boneOffset + (uint)(i * 0x20));
                        var bone = new GenericBone();
                        bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                        r.ReadSingle();
                        //r.Skip(0x10); // inverted world position
                        bone.Name        = r.ReadString(r.ReadUInt32(), -1);
                        bone.ParentIndex = r.ReadInt32();
                        var flags     = r.ReadInt32();
                        var angOffset = r.ReadUInt32();

                        /*angr.Seek(angOffset);
                         * angr.Skip(4);
                         * var posOff = angr.ReadUInt32();
                         * var rotOff = angr.ReadUInt32();
                         * var scaOff = angr.ReadUInt32();
                         * angr.Seek(posOff);
                         * bone.Position = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());
                         * angr.Seek(rotOff);
                         * bone.Rotation = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());
                         * angr.Seek(scaOff);
                         * bone.Scale = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());*/

                        Model.Skeleton.Bones.Add(bone);
                    }
                }
            }

            Model.Skeleton.TransformWorldToRelative();

            using (DataReader r = new DataReader(new FileStream(modelPath, FileMode.Open)))
            {
                r.BigEndian = true;

                r.ReadInt32(); // magic
                int boneCount = r.ReadInt16();
                var meshCount = r.ReadInt16();
                boneCount = r.ReadInt32();
                var meshOffset = r.ReadUInt32();
                r.ReadUInt32();
                var boneOffset = r.ReadUInt32();

                for (int i = 0; i < meshCount; i++)
                {
                    r.Seek(meshOffset + (uint)(i * 80));
                    r.Skip(0x30); // bounding stuff
                    var mesh = new GenericMesh();
                    mesh.MaterialName = "material";
                    mesh.Name         = r.ReadString(r.ReadUInt32(), -1);
                    r.Skip(4 * 4);
                    var datInfoOffset = r.ReadUInt32();
                    Model.Meshes.Add(mesh);

                    r.Seek(datInfoOffset);
                    var flag         = r.ReadInt32();
                    var bufferOffset = r.ReadUInt32();
                    var someCount    = r.ReadInt32();
                    var primCount    = r.ReadInt32();

                    using (DataReader buffer = new DataReader(new FileStream(File.FilePath, FileMode.Open)))
                    {
                        buffer.BigEndian = true;
                        if (new string(buffer.ReadChars(4)) == "MDG5")
                        {
                            buffer.Seek(0x10);
                        }
                        else
                        {
                            buffer.Seek(0);
                        }
                        buffer.Skip(bufferOffset);
                        for (int p = 0; p < primCount; p++)
                        {
                            var primitiveType = buffer.ReadInt16();
                            var pcount        = buffer.ReadInt16();

                            if (primitiveType != 0x98)
                            {
                                throw new NotSupportedException("Unknown prim type " + primitiveType.ToString("X"));
                            }

                            var strip = new List <GenericVertex>();
                            for (int v = 0; v < pcount; v++)
                            {
                                var vert = new GenericVertex();
                                vert.Pos = new OpenTK.Vector3(buffer.ReadSingle(), buffer.ReadSingle(), buffer.ReadSingle());
                                vert.Nrm = new OpenTK.Vector3(buffer.ReadSByte(), buffer.ReadSByte(), buffer.ReadSByte());
                                vert.Nrm.Normalize();

                                // Color?
                                int col = buffer.ReadInt16();
                                var R   = (col >> 12) & 0xF;
                                var G   = (col >> 8) & 0xF;
                                var B   = (col >> 4) & 0xF;
                                var A   = (col) & 0xF;
                                vert.Clr = new OpenTK.Vector4(
                                    (R | R << 4) / (float)0xFF,
                                    (G | G << 4) / (float)0xFF,
                                    (B | B << 4) / (float)0xFF,
                                    (A | A << 4) / (float)0xFF);

                                vert.UV0 = new OpenTK.Vector2(buffer.ReadInt16() / (float)0xFFF, buffer.ReadInt16() / (float)0xFFF);

                                var   weight1 = buffer.ReadByte() / (float)0xFF;
                                float weight2 = 0;
                                if (weight1 != 1)
                                {
                                    weight2 = 1 - weight1;
                                }
                                var bone1 = buffer.ReadByte();
                                var bone2 = buffer.ReadByte();
                                vert.Bones   = new OpenTK.Vector4(bone1, bone2, 0, 0);
                                vert.Weights = new OpenTK.Vector4(weight1, weight2, 0, 0);

                                strip.Add(vert);
                            }

                            TriangleConverter.StripToList(strip, out strip);

                            mesh.Vertices.AddRange(strip);
                        }
                    }

                    mesh.Optimize();
                }
            }
        }
コード例 #10
0
ファイル: HSD.cs プロジェクト: ST3RmY/Metanoia
        private void ParseDOBJs(IHSDNode node, HSD_JOBJ parent, List <HSD_JOBJ> BoneList)
        {
            if (node is HSD_JOBJ jobj)
            {
                if (jobj.DOBJ != null)
                {
                    foreach (var child in jobj.DOBJ.List)
                    {
                        ParseDOBJs(child, jobj, BoneList);
                    }
                }
                foreach (var child in jobj.Children)
                {
                    ParseDOBJs(child, child, BoneList);
                }
            }
            if (node is HSD_DOBJ dobj)
            {
                Console.WriteLine("DOBJ found");
                GenericMesh mesh = new GenericMesh();
                mesh.Name = "Mesh_" + outModel.Meshes.Count;

                GenericMaterial mat = new GenericMaterial();
                mesh.MaterialName = "material_" + outModel.MaterialBank.Count;
                outModel.MaterialBank.Add(mesh.MaterialName, mat);

                var Xscale = 1;
                var Yscale = 1;

                if (dobj.MOBJ != null)
                {
                    if (dobj.MOBJ.Textures != null)
                    {
                        var tobj = dobj.MOBJ.Textures;

                        mat.SWrap = GXTranslator.toWrapMode(tobj.WrapS);
                        mat.TWrap = GXTranslator.toWrapMode(tobj.WrapT);

                        Xscale = tobj.WScale;
                        Yscale = tobj.HScale;

                        if (!tobjToIndex.ContainsKey(tobj.ImageData.Data))
                        {
                            Bitmap B = null;
                            if (tobj.ImageData != null)
                            {
                                if (tobj.Tlut != null)
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, tobj.Tlut.Data, tobj.Tlut.ColorCount, (int)tobj.Tlut.Format);
                                }
                                else
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, null, 0, 0);
                                }
                            }
                            GenericTexture t = new GenericTexture();
                            t.FromBitmap(B);
                            B.Dispose();

                            tobjToIndex.Add(tobj.ImageData.Data, outModel.TextureBank.Count);
                            outModel.TextureBank.Add("texture_" + outModel.TextureBank.Count, t);
                        }

                        mat.TextureDiffuse = outModel.TextureBank.Keys.ToArray()[tobjToIndex[tobj.ImageData.Data]];
                    }
                }

                outModel.Meshes.Add(mesh);
                if (dobj.POBJ != null)
                {
                    foreach (HSD_POBJ pobj in dobj.POBJ.List)
                    {
                        // Decode the Display List Data
                        GXDisplayList DisplayList  = new GXDisplayList(pobj.DisplayListBuffer, pobj.VertexAttributes);
                        var           Vertices     = ToGenericVertex(VertexAccessor.GetDecodedVertices(pobj), BoneList, pobj.BindGroups != null ? new List <HSD_JOBJWeight>(pobj.BindGroups.Elements) : null, parent);
                        int           bufferOffset = 0;
                        foreach (GXPrimitiveGroup g in DisplayList.Primitives)
                        {
                            var primitiveType = GXTranslator.toPrimitiveType(g.PrimitiveType);

                            var strip = new List <GenericVertex>();
                            for (int i = bufferOffset; i < bufferOffset + g.Count; i++)
                            {
                                strip.Add(Vertices[i]);
                            }
                            bufferOffset += g.Count;

                            switch (primitiveType)
                            {
                            case OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip:
                                Tools.TriangleConverter.StripToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Quads:
                                Tools.TriangleConverter.QuadToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Triangles:
                                break;

                            default:
                                Debug.WriteLine("Error converting primitive type " + primitiveType);
                                break;
                            }

                            mesh.Vertices.AddRange(strip);
                        }
                    }
                }

                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    var vert = mesh.Vertices[i];
                    vert.UV0         = new Vector2(vert.UV0.X * Xscale, vert.UV0.Y * Yscale);
                    mesh.Vertices[i] = vert;
                }
                mesh.Optimize();
                Tools.TriangleConverter.ReverseFaces(mesh.Triangles, out mesh.Triangles);
            }
        }