Beispiel #1
0
        public void Open(FileItem File)
        {
            var chunks = GetChunks(File.GetFileBinary());

            var outputpath = Path.GetDirectoryName(File.FilePath);
            int i          = 0;

            foreach (var c in chunks)
            {
                System.IO.File.WriteAllBytes(outputpath + "\\" + i + "_" + c.Flags.ToString("X8"), c.Data);
                //HSF h = new HSF();
                // h.Open(new FileItem(outputpath + "\\" + i + "_" + c.Flags.ToString("X8")));
                //mod = h;
                i++;
            }
        }
Beispiel #2
0
        public void Open(FileItem File)
        {
            var Data = File.GetFileBinary();

            byte[] DecompressedData = null;

            /*using (DataReader reader = new DataReader(new MemoryStream(Data)))
             * {
             *  reader.BigEndian = true;
             *  reader.Seek(0x14); // skip header stuff
             *  ushort CompressedChunkCount = reader.ReadUInt16();
             *
             *  ushort[] CompressedSize = new ushort[CompressedChunkCount];
             *  for(int i = 0; i < CompressedChunkCount; i++)
             *  {
             *      CompressedSize[i] = reader.ReadUInt16();
             *      reader.ReadUInt16();
             *  }
             *
             *  MemoryStream data = new MemoryStream();
             *  using (BinaryWriter o = new BinaryWriter(data))
             *  {
             *      foreach (ushort compsize in CompressedSize)
             *      {
             *          o.Write(Metanoia.Tools.Decompress.ZLIB(reader.ReadBytes(compsize)));
             *      }
             *      DecompressedData = data.GetBuffer();
             *      data.Close();
             *      System.IO.File.WriteAllBytes("LBP\\Decomp.bin", DecompressedData);
             *  }
             *
             *  reader.PrintPosition();
             * }*/

            using (DataReader reader = new DataReader(new MemoryStream(File.GetFileBinary())))
            {
                reader.BigEndian = true;

                // bit pack hell
                reader.Seek(0x10);
                int bufferSizeCount = reader.ReadInt32();
                int uvchannelCount  = reader.ReadInt32();
                int morphCount      = reader.ReadInt32();

                Console.WriteLine(bufferSizeCount);

                reader.Seek(0x220);
                Console.WriteLine(reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadInt32());
                Console.WriteLine(reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadInt32());

                int[] bufferOffsets = new int[bufferSizeCount];
                for (int i = 0; i < bufferSizeCount; i++)
                {
                    bufferOffsets[i] = reader.ReadInt32();
                }

                var vertexBufferSize = reader.ReadUInt32();
                var start            = reader.Position;
                PositionBuffer = new Vector4[bufferOffsets[0] / 0x10];
                for (int i = 0; i < PositionBuffer.Length; i++)
                {
                    PositionBuffer[i] = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                }
                reader.Seek(start + vertexBufferSize);

                var uvbufferSize = reader.ReadUInt32();
                UV0Buffer = new Vector2[uvbufferSize / 0x18];
                UV1Buffer = new Vector2[uvbufferSize / 0x18];
                UV2Buffer = new Vector2[uvbufferSize / 0x18];
                for (int i = 0; i < uvbufferSize / 0x18; i++)
                {
                    if (uvchannelCount > 0)
                    {
                        UV0Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }
                    if (uvchannelCount > 1)
                    {
                        UV1Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }
                    if (uvchannelCount > 2)
                    {
                        UV2Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }
                }

                Console.WriteLine(PositionBuffer.Length + " " + UV0Buffer.Length);

                var trianglebufferSize = reader.ReadInt32();
                IndexBuffer = new short[trianglebufferSize / 2];
                for (int i = 0; i < IndexBuffer.Length; i++)
                {
                    IndexBuffer[i] = reader.ReadInt16();
                }

                uint boneCount = reader.ReadUInt32();
                reader.Skip(0x22 * boneCount);

                uint      boneCount2  = reader.ReadUInt32();
                var       boneStart   = reader.Position;
                Matrix4[] wtransforms = new Matrix4[boneCount2];
                Matrix4[] itransforms = new Matrix4[boneCount2];
                for (int i = 0; i < boneCount2; i++)
                {
                    reader.Seek((uint)(boneStart + (i * 0x114))); // 0xD4 for older versions
                    var bone = new GenericBone();
                    bone.Name = reader.ReadString((uint)(boneStart + (i * 0x114)), -1);
                    reader.Skip(0x28);
                    bone.ParentIndex = reader.ReadInt32();
                    reader.Skip(0x8);
                    wtransforms[i] = new Matrix4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    itransforms[i] = new Matrix4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(),
                                                 reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    if (bone.ParentIndex != -1 && bone.ParentIndex != 0)
                    {
                        var par          = skeleton.GetWorldTransform(bone.ParentIndex).Inverted();
                        var reltransform = wtransforms[i] * par;
                        bone.Transform          = reltransform;
                        bone.QuaternionRotation = wtransforms[i].ExtractRotation() * par.ExtractRotation();
                    }
                    else
                    if (i != 0)
                    {
                        bone.Transform = wtransforms[i];
                    }
                    else
                    {
                        bone.Transform = Matrix4.Identity;
                    }

                    skeleton.Bones.Add(bone);
                }

                reader.Seek(boneStart + (boneCount2 * 0x114));

                var boneIndexTableCount = reader.ReadUInt32();
                reader.Skip(boneIndexTableCount * 2);

                var bonecountTableCount = reader.ReadUInt32();
                reader.Skip(bonecountTableCount);

                var boneIndexTableCount2 = reader.ReadUInt32();
                reader.Skip(boneIndexTableCount2 * 2);

                reader.Skip(5);
                reader.Skip(reader.ReadUInt32() * 0x10); // vector 4s?

                reader.Skip(reader.ReadUInt32() * 0x40); // some matrices?

                reader.Skip(reader.ReadUInt32() * 0x4);  // float table? maybe weights?

                int clusterStringCount = reader.ReadInt32();
                var clusterstringstart = reader.Position;
                for (int i = 0; i < clusterStringCount; i++)
                {
                }
                reader.Seek(clusterstringstart + 0x20 * (uint)clusterStringCount);

                reader.Skip(reader.ReadUInt32() * 0x8); // ?? may have something to do with weighting

                reader.Skip(reader.ReadUInt32() * 0x4); // ?? may have something to do with weighting

                reader.Skip(reader.ReadUInt32() * 0x4); // ?? another float table??

                reader.PrintPosition();
            }
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        public void Open(FileItem File)
        {
            using (DataReader reader = new DataReader(new MemoryStream(File.GetFileBinary())))
            {
                reader.BigEndian = true;

                var header = ParseVAPS(reader);

                uint polyOff = 0;

                for (int h = 0; h < header.Offsets.Length; h++)
                {
                    reader.Seek(header[h]);
                    var contentHeader = ParseVAPS(reader);

                    switch (contentHeader.ContentType)
                    {
                    case 0x0C:     // Bones
                        var boneCount = reader.ReadInt16();
                        reader.Position += 0xA;

                        for (int i = 0; i < boneCount; i++)
                        {
                            GenericBone b = new GenericBone();
                            b.Name = "Bone_" + i;
                            Skeleton.Bones.Add(b);
                            b.QuaternionRotation = new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            b.Position           = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            b.Scale          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            b.ParentIndex    = reader.ReadSByte();
                            reader.Position += 3;
                        }
                        break;

                    case 0x03:     // textures
                        Console.WriteLine(contentHeader.Indices.Length + " " + contentHeader.Offsets.Length);
                        break;

                    case 0x04:     // mesh objects
                        polyOff = header[h];
                        break;

                    case 0x09:     // uv buffer

                        break;

                    case 0x0E:     // materials?

                        break;

                    case 0x0D:     // sounds?

                        break;

                    case 0x16:     // vertices
                        ReadVertices(reader);
                        break;

                    default:
                        System.Diagnostics.Debug.WriteLine("Unknown content type " + contentHeader.ContentType.ToString("X") + " " + reader.Position.ToString("X"));
                        break;
                    }
                }
                //Polygons
                reader.Seek(polyOff);
                ParseVAPS(reader);
                ReadPolygons(reader);
            }
        }
Beispiel #5
0
 public void Open(FileItem File)
 {
     ParseOBE(File.GetFileBinary());
 }
Beispiel #6
0
        public void Open(FileItem File)
        {
            dynamic stuff = JObject.Parse(System.Text.Encoding.UTF8.GetString(File.GetFileBinary()));

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

            var skeletons = stuff.skeletons;

            foreach (var skel in skeletons)
            {
                if (((string)skel.name).Contains("carryable"))
                {
                    foreach (var bone in skel.bones)
                    {
                        var gBone = new GenericBone();
                        Model.Skeleton.Bones.Add(gBone);
                        gBone.Name               = "Bone_" + bone.index;
                        gBone.ParentIndex        = bone.parent;
                        gBone.Position           = new OpenTK.Vector3((float)bone.local.position[0], (float)bone.local.position[1], (float)bone.local.position[2]);
                        gBone.QuaternionRotation = new OpenTK.Quaternion((float)bone.local.rotation[0], (float)bone.local.rotation[1], (float)bone.local.rotation[2], (float)bone.local.rotation[3]).Inverted();
                        gBone.Scale              = new OpenTK.Vector3((float)bone.local.scale[0], (float)bone.local.scale[1], (float)bone.local.scale[2]);
                    }
                    break;
                }
            }

            var models = stuff.models;

            foreach (var modl in models)
            {
                foreach (var batch in modl.batches)
                {
                    GenericMesh mesh = new GenericMesh();
                    Model.Meshes.Add(mesh);
                    mesh.Name = batch.id;

                    foreach (int index in batch.indices)
                    {
                        var vertex = new GenericVertex();
                        if (((JArray)batch.positions).Count > 0)
                        {
                            vertex.Pos = new OpenTK.Vector3((float)batch.positions[index * 3 + 0], (float)batch.positions[index * 3 + 1], (float)batch.positions[index * 3 + 2]);
                        }

                        if (((JArray)batch.normals).Count > 0)
                        {
                            vertex.Nrm = new OpenTK.Vector3((float)batch.normals[index * 3 + 0], (float)batch.normals[index * 3 + 1], (float)batch.normals[index * 3 + 2]);
                        }

                        if (((JArray)batch.uvs).Count > 0)
                        {
                            vertex.UV0 = new OpenTK.Vector2((float)batch.uvs[index * 2 + 0], (float)batch.uvs[index * 2 + 1]);
                        }
                        if (((JArray)batch.uvs2).Count > 0)
                        {
                            vertex.UV1 = new OpenTK.Vector2((float)batch.uvs2[index * 2 + 0], (float)batch.uvs2[index * 2 + 1]);
                        }
                        if (((JArray)batch.uvs3).Count > 0)
                        {
                            vertex.UV2 = new OpenTK.Vector2((float)batch.uvs3[index * 2 + 0], (float)batch.uvs3[index * 2 + 1]);
                        }
                        if (((JArray)batch.colors).Count > 0)
                        {
                            vertex.Clr = new OpenTK.Vector4((float)batch.colors[index * 4 + 0] * 255, (float)batch.colors[index * 4 + 1] * 255, (float)batch.colors[index * 4 + 2] * 255, (float)batch.colors[index * 4 + 3] * 255);
                        }

                        if (((JArray)batch.bindings).Count > 0)
                        {
                            vertex.Bones = new OpenTK.Vector4((int)batch.bindings[index * 4 + 0], (int)batch.bindings[index * 4 + 1], (int)batch.bindings[index * 4 + 2], (int)batch.bindings[index * 4 + 3]);
                        }

                        if (((JArray)batch.weights).Count > 0)
                        {
                            vertex.Weights = new OpenTK.Vector4(((int)batch.weights[index * 4 + 0]) / 255f, ((int)batch.weights[index * 4 + 1]) / 255f, ((int)batch.weights[index * 4 + 2]) / 255f, ((int)batch.weights[index * 4 + 3]) / 255f);
                        }
                        mesh.Vertices.Add(vertex);
                    }

                    mesh.Optimize();
                }
            }
        }
Beispiel #7
0
        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);
             * }*/
        }
Beispiel #8
0
        public void Open(FileItem File)
        {
            using (DataReader r = new DataReader(new MemoryStream(File.GetFileBinary())))
            {
                if (!new string(r.ReadChars(4)).Equals("XPCK"))
                {
                    throw new Exception("File header error");
                }

                uint fileCount = (uint)(r.ReadUInt16() & 0xFFF);

                var fileInfoOffset  = r.ReadUInt16() * 4;
                var fileTableOffset = r.ReadUInt16() * 4;
                var dataOffset      = r.ReadUInt16() * 4;

                r.ReadUInt16();
                var filenameTableSize = r.ReadUInt16() * 4;

                var hashToData = new Dictionary <uint, byte[]>();
                r.Seek((uint)fileInfoOffset);
                for (int i = 0; i < fileCount; i++)
                {
                    var nameCRC = r.ReadUInt32();
                    r.ReadInt16();
                    var offset    = (uint)r.ReadUInt16();
                    var size      = (uint)r.ReadUInt16();
                    var offsetExt = (uint)r.ReadByte();
                    var sizeExt   = (uint)r.ReadByte();

                    offset |= offsetExt << 16;
                    size   |= sizeExt << 16;
                    offset  = (uint)(offset * 4 + dataOffset);

                    var data = r.GetSection(offset, (int)size);
                    //Decompress.CheckLevel5Zlib(data, out data);

                    hashToData.Add(nameCRC, data);
                }

                byte[] nameTable = r.GetSection((uint)fileTableOffset, filenameTableSize);
                if (!Decompress.CheckLevel5Zlib(nameTable, out nameTable))
                {
                    nameTable = Decompress.lzss_Decompress(nameTable);
                }
                using (DataReader nt = new DataReader(new MemoryStream(nameTable)))
                {
                    for (int i = 0; i < fileCount; i++)
                    {
                        var name = nt.ReadString();

                        if (hashToData.ContainsKey(CRC32.Crc32C(name)))
                        {
                            Files.Add(name, hashToData[CRC32.Crc32C(name)]);
                        }
                        else
                        {
                            Console.WriteLine("Couldn't find " + name + " " + CRC32.Crc32C(name).ToString("X"));
                        }
                    }
                }
            }
        }