예제 #1
0
        public override byte[] Rebuild()
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Big;

            f.writeString("MTA4");
            f.writeInt((int)unknown);
            f.writeInt((int)numFrames);
            f.writeInt(0);
            f.writeInt((int)numFrames - 1);
            f.writeInt((int)frameRate);
            f.writeInt(matEntries.Count);
            if (matEntries.Count > 0)
            {
                f.writeInt(0x38);
            }
            else
            {
                f.writeInt(0);
            }
            f.writeInt(visEntries.Count);
            if (visEntries.Count > 0)
            {
                f.writeInt(0x38 + 4 * matEntries.Count);
            }
            else
            {
                f.writeInt(0);
            }
            for (int i = 0; i < 0x10; i++)
            {
                f.writeByte(0);
            }

            List <byte[]> matEntriesBuilt = new List <byte[]>();
            List <byte[]> visEntriesBuilt = new List <byte[]>();

            int position = 0x38 + matEntries.Count + visEntries.Count;

            while (position % 0x10 != 0)
            {
                position++;
            }

            foreach (MatEntry m in matEntries)
            {
                byte[] b = m.Rebuild(position);
                matEntriesBuilt.Add(b);
                f.writeInt(position);
                position += b.Length;
                while (position % 0x10 != 0)
                {
                    position++;
                }
            }

            foreach (VisEntry v in visEntries)
            {
                byte[] b = v.Rebuild(position);
                matEntriesBuilt.Add(b);
                f.writeInt(position);
                position += b.Length;
                while (position % 0x10 != 0)
                {
                    position++;
                }
            }

            while (f.pos() % 0x10 != 0)
            {
                f.writeByte(0);
            }

            foreach (byte[] b in matEntriesBuilt)
            {
                f.writeBytes(b);
                while (f.pos() % 0x10 != 0)
                {
                    f.writeByte(0);
                }
            }

            foreach (byte[] b in visEntriesBuilt)
            {
                f.writeBytes(b);
                while (f.pos() % 0x10 != 0)
                {
                    f.writeByte(0);
                }
            }

            return(f.getBytes());
        }
예제 #2
0
        public static byte[] createOMO(SkelAnimation a, VBN vbn)
        {
            List <int> nodeid = a.getNodes(true, vbn);

            int startNode = 0;
            int sizeNode  = nodeid.Count;

            FileOutput o = new FileOutput();

            o.Endian = Endianness.Big;

            FileOutput t1 = new FileOutput();

            t1.Endian = Endianness.Big;

            FileOutput t2 = new FileOutput();

            t2.Endian = Endianness.Big;

            o.writeString("OMO ");
            o.writeShort(1);        //idk
            o.writeShort(3);        //idk

            o.writeInt(0x091E100C); //flags??


            o.writeShort(0);              //padding
            o.writeShort(sizeNode);       // numOfNodes

            o.writeShort(a.frames.Count); // frame size
            o.writeShort(0);              // frame start ??

            o.writeInt(0);
            o.writeInt(0);
            o.writeInt(0);

            o.writeIntAt(o.size(), 0x14);


            // ASSESSMENT
            KeyNode[] minmax   = new KeyNode[sizeNode];
            bool[]    hasScale = new bool[sizeNode];
            bool[]    hasTrans = new bool[sizeNode];
            bool[]    hasRot   = new bool[sizeNode];

            bool[] conScale = new bool[sizeNode];
            bool[] conTrans = new bool[sizeNode];
            bool[] conRot   = new bool[sizeNode];

            a.setFrame(0);

            for (int i = 0; i < a.size(); i++)
            {
                a.nextFrame(vbn);

                for (int j = 0; j < nodeid.Count; j++)
                {
                    Bone node = getNodeId(vbn, nodeid[j]);

                    if (minmax[j] == null)
                    {
                        hasRot[j]   = false;
                        hasScale[j] = false;
                        hasTrans[j] = false;

                        KeyNode n = a.getFirstNode(nodeid[j]);
                        if (n != null)
                        {
                            if (n.r_type != -1)
                            {
                                hasRot[j] = true;
                            }
                            if (n.t_type != -1)
                            {
                                hasTrans[j] = true;
                            }
                            if (n.s_type != -1)
                            {
                                hasScale[j] = true;
                            }
                        }

                        minmax[j]    = new KeyNode();
                        minmax[j].t  = new Vector3(999f, 999f, 999f);
                        minmax[j].r  = new Quaternion(999f, 999f, 999f, 999f);
                        minmax[j].s  = new Vector3(999f, 999f, 999f);
                        minmax[j].t2 = new Vector3(-999f, -999f, -999f);
                        minmax[j].r2 = new Quaternion(-999f, -999f, -999f, -999f);
                        minmax[j].s2 = new Vector3(-999f, -999f, -999f);
                    }

                    if (node.pos.X < minmax[j].t.X)
                    {
                        minmax[j].t.X = node.pos.X;
                    }
                    if (node.pos.X > minmax[j].t2.X)
                    {
                        minmax[j].t2.X = node.pos.X;
                    }

                    if (node.pos.Y < minmax[j].t.Y)
                    {
                        minmax[j].t.Y = node.pos.Y;
                    }
                    if (node.pos.Y > minmax[j].t2.Y)
                    {
                        minmax[j].t2.Y = node.pos.Y;
                    }

                    if (node.pos.Z < minmax[j].t.Z)
                    {
                        minmax[j].t.Z = node.pos.Z;
                    }
                    if (node.pos.Z > minmax[j].t2.Z)
                    {
                        minmax[j].t2.Z = node.pos.Z;
                    }

                    //				float[] fix = Node.fix360(node.nrx, node.nry, node.nrz);
                    //float[] f = Bone.CalculateRotation(node.nrx, node.nry, node.nrz);
                    Quaternion r = node.rot;

                    if (r.X < minmax[j].r.X)
                    {
                        minmax[j].r.X = r.X;
                    }
                    if (r.X > minmax[j].r2.X)
                    {
                        minmax[j].r2.X = r.X;
                    }

                    if (r.Y < minmax[j].r.Y)
                    {
                        minmax[j].r.Y = r.Y;
                    }
                    if (r.Y > minmax[j].r2.Y)
                    {
                        minmax[j].r2.Y = r.Y;
                    }

                    if (r.Z < minmax[j].r.Z)
                    {
                        minmax[j].r.Z = r.Z;
                    }
                    if (r.Z > minmax[j].r2.Z)
                    {
                        minmax[j].r2.Z = r.Z;
                    }


                    if (node.sca.X < minmax[j].s.X)
                    {
                        minmax[j].s.X = node.sca.X;
                    }
                    if (node.sca.X > minmax[j].s2.X)
                    {
                        minmax[j].s2.X = node.sca.X;
                    }

                    if (node.sca.Y < minmax[j].s.Y)
                    {
                        minmax[j].s.Y = node.sca.Y;
                    }
                    if (node.sca.Y > minmax[j].s2.Y)
                    {
                        minmax[j].s2.Y = node.sca.Y;
                    }

                    if (node.sca.Z < minmax[j].s.Z)
                    {
                        minmax[j].s.Z = node.sca.Z;
                    }
                    if (node.sca.Z > minmax[j].s2.Z)
                    {
                        minmax[j].s2.Z = node.sca.Z;
                    }
                }
            }

            // NODE INFO

            int t2Size = 0;

            for (int i = 0; i < sizeNode; i++)
            {
                int flag = 0;

                conRot[i]   = false;
                conScale[i] = false;
                conTrans[i] = false;

                // check for constant
                if (minmax[i].t.Equals(minmax[i].t2))
                {
                    conTrans[i] = true;
                }
                if (minmax[i].r.Equals(minmax[i].r2))
                {
                    conRot[i] = true;
                }
                if (minmax[i].s.Equals(minmax[i].s2))
                {
                    conScale[i] = true;
                }

                if (hasTrans[i])
                {
                    flag |= 0x01000000;
                }
                if (hasRot[i])
                {
                    flag |= 0x02000000;
                }
                if (hasScale[i])
                {
                    flag |= 0x04000000;
                }

                if (conTrans[i] && hasTrans[i])
                {
                    flag |= 0x00200000;
                }
                else
                {
                    flag |= 0x00080000;
                }

                if (conRot[i] && hasRot[i])
                {
                    flag |= 0x00007000;
                }
                else
                {
                    flag |= 0x00005000;
                }

                if (conScale[i] && hasScale[i])
                {
                    flag |= 0x00000200;
                }
                else
                {
                    flag |= 0x00000080;
                }

                flag |= 0x00000001;

                int hash = (int)getNodeId(vbn, nodeid[i]).boneId;
                //if(hash == -1)
                //hash = (int)FileData.crc32(getNodeId(nodeid.get(i)).name);
                o.writeInt(flag);      // flags...
                o.writeInt(hash);      //hash
                o.writeInt(t1.size()); // Offset in 1 table
                o.writeInt(t2Size);    // Offset in 2 table

                // calculate size needed
                if (hasTrans[i])
                {
                    t1.writeFloat(minmax[i].t.X);
                    t1.writeFloat(minmax[i].t.Y);
                    t1.writeFloat(minmax[i].t.Z);

                    if (!conTrans[i])
                    {
                        minmax[i].t2.X -= minmax[i].t.X;
                        minmax[i].t2.Y -= minmax[i].t.Y;
                        minmax[i].t2.Z -= minmax[i].t.Z;

                        t1.writeFloat(minmax[i].t2.X);
                        t1.writeFloat(minmax[i].t2.Y);
                        t1.writeFloat(minmax[i].t2.Z);

                        t2Size += 6;
                    }
                }

                if (hasRot[i])
                {
                    t1.writeFloat(minmax[i].r.X);
                    t1.writeFloat(minmax[i].r.Y);
                    t1.writeFloat(minmax[i].r.Z);

                    if (!conRot[i])
                    {
                        minmax[i].r2.X -= minmax[i].r.X;
                        minmax[i].r2.Y -= minmax[i].r.Y;
                        minmax[i].r2.Z -= minmax[i].r.Z;

                        t1.writeFloat(minmax[i].r2.X);
                        t1.writeFloat(minmax[i].r2.Y);
                        t1.writeFloat(minmax[i].r2.Z);

                        t2Size += 6;
                    }
                }

                if (hasScale[i])
                {
                    t1.writeFloat(minmax[i].s.X);
                    t1.writeFloat(minmax[i].s.Y);
                    t1.writeFloat(minmax[i].s.Z);

                    if (!conScale[i])
                    {
                        minmax[i].s2.X -= minmax[i].s.X;
                        minmax[i].s2.Y -= minmax[i].s.Y;
                        minmax[i].s2.Z -= minmax[i].s.Z;

                        t1.writeFloat(minmax[i].s2.X);
                        t1.writeFloat(minmax[i].s2.Y);
                        t1.writeFloat(minmax[i].s2.Z);

                        t2Size += 6;
                    }
                }
            }

            o.writeIntAt(o.size(), 0x18);

            o.writeOutput(t1);

            o.writeIntAt(o.size(), 0x1C);

            // INTERPOLATION

            a.setFrame(0);

            for (int i = 0; i < a.size(); i++)
            {
                a.nextFrame(vbn);
                for (int j = 0; j < nodeid.Count; j++)
                {
                    Bone node = getNodeId(vbn, nodeid[j]);

                    if (hasTrans[j] && !conTrans[j])
                    {
                        t2.writeShort((int)(((node.pos.X - minmax[j].t.X) / minmax[j].t2.X) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Y - minmax[j].t.Y) / minmax[j].t2.Y) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Z - minmax[j].t.Z) / minmax[j].t2.Z) * 0xFFFF));
                    }

                    if (hasRot[j] && !conRot[j])
                    {
                        //					float[] fix = Node.fix360(node.nrx, node.nry, node.nrz);
                        //float[] f = CalculateRotation(node.nrx, node.nry, node.nrz);
                        Quaternion r = node.rot;

                        t2.writeShort((int)(((r.X - minmax[j].r.X) / minmax[j].r2.X) * 0xFFFF));
                        t2.writeShort((int)(((r.Y - minmax[j].r.Y) / minmax[j].r2.Y) * 0xFFFF));
                        t2.writeShort((int)(((r.Z - minmax[j].r.Z) / minmax[j].r2.Z) * 0xFFFF));
                    }

                    if (hasScale[j] && !conScale[j])
                    {
                        t2.writeShort((int)(((node.sca.X - minmax[j].s.X) / minmax[j].s2.X) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Y - minmax[j].s.Y) / minmax[j].s2.Y) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Z - minmax[j].s.Z) / minmax[j].s2.Z) * 0xFFFF));
                    }
                }

                if (i == 0)
                {
                    o.writeShortAt(t2.size(), 0x12);
                }
            }

            o.writeOutput(t2);
            return(o.getBytes());
        }
예제 #3
0
        public byte[] Rebuild(int pos)
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Big;

            f.writeInt(pos + f.pos() + 0x20);
            f.writeInt(matHash);
            f.writeInt(properties.Count);
            int nameOffset = pos + f.pos() + 0x15 + name.Length;

            while (nameOffset % 4 != 0)
            {
                nameOffset++;
            }
            f.writeInt(nameOffset);
            f.writeFlag(hasPat);
            f.writeBytes(new byte[3]);
            //Write all the mat data into a buffer (g) then write pat offset
            int        pos2 = pos + f.pos() + 4;
            FileOutput g    = new FileOutput();

            g.Endian = Endianness.Big;

            if (matHash2 != 0)
            {
                g.writeInt(pos2 + g.pos() + 0x8);
                g.writeInt(matHash);
            }
            else
            {
                g.writeBytes(new byte[8]);
            }

            g.writeString(name);
            g.writeByte(0);
            while ((pos2 + g.pos()) % 0x10 != 0)
            {
                g.writeByte(0);
            }

            int position = pos2 + g.pos() + properties.Count * 4;

            while (position % 16 != 0)
            {
                position++;
            }

            List <byte[]> builtProperties = new List <byte[]>();

            foreach (MatData prop in properties)
            {
                g.writeInt(position);
                byte[] b = prop.Rebuild(position);
                builtProperties.Add(b);
                position += b.Length;
                while (position % 16 != 0)
                {
                    position++;
                }
            }

            while ((pos2 + g.pos()) % 16 != 0)
            {
                g.writeByte(0);
            }

            foreach (byte[] b in builtProperties)
            {
                g.writeBytes(b);
                while ((pos2 + g.pos()) % 16 != 0)
                {
                    g.writeByte(0);
                }
            }

            f.writeInt(pos2 + g.pos());
            f.writeBytes(g.getBytes());
            if (hasPat)
            {
                f.writeBytes(pat0.Rebuild(f.pos()));
            }

            return(f.getBytes());
        }
예제 #4
0
파일: LM.cs 프로젝트: nnn1590/Smash-Forge
        public byte[] Rebuild(bool dump = false)
        {
            FileOutput o = new FileOutput();

            TextWriter   oldOut = Console.Out;
            MemoryStream ostrm  = new MemoryStream(0xA00000);
            StreamWriter writer = new StreamWriter(ostrm);

            Console.SetOut(writer);

            // TODO: write correct filesize in header.
            // It isn't checked by the game, but what the hell, right?
            header.Write(o);

            writeSymbols(o);
            writeColors(o);
            writeTransforms(o);
            writePositions(o);
            writeBounds(o);

            Actionscript.Write(o);
            if (Actionscript2 != null)
            {
                Actionscript2.Write(o);
            }

            writeAtlases(o);

            unkF008.Write(o);
            unkF009.Write(o);
            unkF00A.Write(o);
            unk000A.Write(o);
            unkF00B.Write(o);
            properties.Write(o);

            Defines.numShapes  = (uint)Shapes.Count;
            Defines.numSprites = (uint)Sprites.Count;
            Defines.numTexts   = (uint)Texts.Count;
            Defines.Write(o);

            writeShapes(o);
            writeSprites(o);
            writeTexts(o);

            o.writeInt((int)TagType.End);
            o.writeInt(0);

            int padSize = (4 - (o.size() % 4)) % 4;

            for (int i = 0; i < padSize; i++)
            {
                o.writeByte(0);
            }

            if (dump)
            {
                writer.Flush();
                using (var filestream = new FileStream("dump.txt", FileMode.Create))
                    ostrm.WriteTo(filestream);
            }

            Console.SetOut(oldOut);

            return(o.getBytes());
        }
예제 #5
0
파일: NUT.cs 프로젝트: aelanx/Smash-Forge
        public override byte[] Rebuild()
        {
            FileOutput o    = new FileOutput();
            FileOutput data = new FileOutput();

            o.writeInt(0x4E545033); // "NTP3"
            o.writeShort(Version);
            o.writeShort(Nodes.Count);
            o.writeInt(0);
            o.writeInt(0);

            //calculate total header size
            int headerLength = 0;

            foreach (NutTexture texture in Nodes)
            {
                int headerSize = 0x50;

                if (texture.mipmaps.Count > 1)
                {
                    headerSize += texture.mipmaps.Count * 4;
                    while (headerSize % 16 != 0)
                    {
                        headerSize += 4;
                    }
                }
                headerLength += headerSize;
            }

            // write headers+data
            foreach (NutTexture texture in Nodes)
            {
                int size = 0;

                foreach (var mip in texture.mipmaps)
                {
                    size += mip.Length;
                    while (size % 16 != 0)
                    {
                        size += 1;
                    }
                }

                int headerSize = 0x50;

                // calculate header size
                if (texture.mipmaps.Count > 1)
                {
                    headerSize += texture.mipmaps.Count * 4;
                    //align to 16
                    while (headerSize % 16 != 0)
                    {
                        headerSize += 1;
                    }
                }

                o.writeInt(size + headerSize);
                o.writeInt(0x00);         //padding
                o.writeInt(size);
                o.writeShort(headerSize); //+ (texture.mipmaps.Count - 4 > 0 ? texture.mipmaps.Count - 4 : 0) * 4
                o.writeShort(0);
                o.writeShort(texture.mipmaps.Count);
                o.writeShort(texture.getNutFormat());
                o.writeShort(texture.Width);
                o.writeShort(texture.Height);
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(headerLength + data.size());
                headerLength -= headerSize;
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(0);

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    foreach (byte[] mip in texture.mipmaps)
                    {
                        for (int t = 0; t < mip.Length; t += 4)
                        {
                            byte t1 = mip[t + 3];
                            mip[t + 3] = mip[t + 2];
                            mip[t + 2] = mip[t + 1];
                            mip[t + 1] = mip[t];
                            mip[t]     = t1;
                        }
                    }
                }

                foreach (var mip in texture.mipmaps)
                {
                    int ds = data.size();
                    data.writeBytes(mip);
                    data.align(0x10);
                    if (texture.mipmaps.Count > 1)
                    {
                        o.writeInt(data.size() - ds);
                    }
                }
                o.align(16);

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    foreach (byte[] mip in texture.mipmaps)
                    {
                        for (int t = 0; t < mip.Length; t += 4)
                        {
                            byte t1 = mip[t];
                            mip[t]     = mip[t + 1];
                            mip[t + 1] = mip[t + 2];
                            mip[t + 2] = mip[t + 3];
                            mip[t + 3] = t1;
                        }
                    }
                }

                o.writeInt(0x65587400); // "eXt\0"
                o.writeInt(0x20);
                o.writeInt(0x10);
                o.writeInt(0x00);
                o.writeInt(0x47494458); // "GIDX"
                o.writeInt(0x10);

                o.writeInt(texture.HASHID);
                o.writeInt(0);
            }
            o.writeOutput(data);

            return(o.getBytes());
        }
예제 #6
0
        public override byte[] Rebuild()
        {
            FileOutput o    = new FileOutput();
            FileOutput data = new FileOutput();

            o.writeUInt(0x4E545033); // "NTP3"
            o.writeUShort(Version);
            o.writeUShort((ushort)Nodes.Count);
            o.writeInt(0);
            o.writeInt(0);

            //calculate total header size
            uint headerLength = 0;

            foreach (NutTexture texture in Nodes)
            {
                byte surfaceCount = (byte)texture.surfaces.Count;
                bool isCubemap    = surfaceCount == 6;
                if (surfaceCount < 1 || surfaceCount > 6)
                {
                    throw new NotImplementedException($"Unsupported surface amount {surfaceCount} for texture with hash 0x{texture.HashId:X}. 1 to 6 faces are required.");
                }
                else if (surfaceCount > 1 && surfaceCount < 6)
                {
                    throw new NotImplementedException($"Unsupported cubemap face amount for texture with hash 0x{texture.HashId:X}. Six faces are required.");
                }
                byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count;

                ushort headerSize = 0x50;
                if (isCubemap)
                {
                    headerSize += 0x10;
                }
                if (mipmapCount > 1)
                {
                    headerSize += (ushort)(mipmapCount * 4);
                    while (headerSize % 0x10 != 0)
                    {
                        headerSize += 1;
                    }
                }

                headerLength += headerSize;
            }

            // write headers+data
            foreach (NutTexture texture in Nodes)
            {
                byte surfaceCount = (byte)texture.surfaces.Count;
                bool isCubemap    = surfaceCount == 6;
                byte mipmapCount  = (byte)texture.surfaces[0].mipmaps.Count;

                uint dataSize = 0;

                foreach (var mip in texture.GetAllMipmaps())
                {
                    dataSize += (uint)mip.Length;
                    while (dataSize % 0x10 != 0)
                    {
                        dataSize += 1;
                    }
                }

                ushort headerSize = 0x50;
                if (isCubemap)
                {
                    headerSize += 0x10;
                }
                if (mipmapCount > 1)
                {
                    headerSize += (ushort)(mipmapCount * 4);
                    while (headerSize % 0x10 != 0)
                    {
                        headerSize += 1;
                    }
                }

                o.writeUInt(dataSize + headerSize);
                o.writeUInt(0);
                o.writeUInt(dataSize);
                o.writeUShort(headerSize);
                o.writeUShort(0);

                o.writeByte(0);
                o.writeByte(mipmapCount);
                o.writeByte(0);
                o.writeByte(texture.getNutFormat());
                o.writeShort(texture.Width);
                o.writeShort(texture.Height);
                o.writeInt(0);
                o.writeUInt(texture.DdsCaps2);

                o.writeUInt((uint)(headerLength + data.size()));
                headerLength -= headerSize;
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(0);

                if (isCubemap)
                {
                    o.writeInt(texture.surfaces[0].mipmaps[0].Length);
                    o.writeInt(texture.surfaces[0].mipmaps[0].Length);
                    o.writeInt(0);
                    o.writeInt(0);
                }

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    texture.SwapChannelOrderDown();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        int ds = data.size();
                        data.writeBytes(texture.surfaces[surfaceLevel].mipmaps[mipLevel]);
                        data.align(0x10);
                        if (mipmapCount > 1 && surfaceLevel == 0)
                        {
                            o.writeInt(data.size() - ds);
                        }
                    }
                }
                o.align(0x10);

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    texture.SwapChannelOrderUp();
                }

                o.writeUInt(0x65587400); // "eXt\0"
                o.writeInt(0x20);
                o.writeInt(0x10);
                o.writeInt(0x00);

                o.writeUInt(0x47494458); // "GIDX"
                o.writeInt(0x10);
                o.writeInt(texture.HashId);
                o.writeInt(0);
            }
            o.writeOutput(data);

            return(o.getBytes());
        }
예제 #7
0
        public override byte[] Rebuild()
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Little;
            FileOutput fv = new FileOutput();

            fv.Endian = Endianness.Little;

            f.writeShort(format);
            f.writeShort(unkown);
            f.writeInt(flags);
            f.writeInt(mode);
            bool hasNameTable = (flags & 2) > 0;

            f.writeInt(mesh.Count);

            int vertSize = 0;

            // Vertex Bank
            for (int i = 0; i < 1; i++)
            {
                if (mode == 0 || i == 0)
                {
                    Descriptor des = descript[i];

                    if (format != 4)
                    {
                        foreach (Vertex v in vertices)
                        {
                            for (int k = 0; k < des.type.Length; k++)
                            {
                                fv.align(2, 0x00);
                                switch (des.type[k])
                                {
                                case 0:     //Position
                                    writeType(fv, v.pos.X, des.format[k], des.scale[k]);
                                    writeType(fv, v.pos.Y, des.format[k], des.scale[k]);
                                    writeType(fv, v.pos.Z, des.format[k], des.scale[k]);
                                    break;

                                case 1:     //Normal
                                    writeType(fv, v.nrm.X, des.format[k], des.scale[k]);
                                    writeType(fv, v.nrm.Y, des.format[k], des.scale[k]);
                                    writeType(fv, v.nrm.Z, des.format[k], des.scale[k]);
                                    break;

                                case 2:     //Color
                                    writeType(fv, v.col.X, des.format[k], des.scale[k]);
                                    writeType(fv, v.col.Y, des.format[k], des.scale[k]);
                                    writeType(fv, v.col.Z, des.format[k], des.scale[k]);
                                    writeType(fv, v.col.W, des.format[k], des.scale[k]);
                                    break;

                                case 3:     //Tex0
                                    writeType(fv, v.tx[0].X, des.format[k], des.scale[k]);
                                    writeType(fv, v.tx[0].Y, des.format[k], des.scale[k]);
                                    break;

                                case 4:     //Tex1
                                    writeType(fv, v.tx[1].X, des.format[k], des.scale[k]);
                                    writeType(fv, v.tx[1].Y, des.format[k], des.scale[k]);
                                    break;

                                case 5:     //Bone Index
                                    fv.writeByte(v.node[0]);
                                    fv.writeByte(v.node[1]);
                                    break;

                                case 6:     //Bone Weight
                                    writeType(fv, v.weight[0], des.format[k], des.scale[k]);
                                    writeType(fv, v.weight[1], des.format[k], des.scale[k]);
                                    break;
                                    //default:
                                    //    Console.WriteLine("WTF is this");
                                }
                            }
                        }
                        vertSize = fv.size();
                        fv.align(32, 0xFF);
                    }
                }


                for (int j = 0; j < mesh.Count; j++)
                {
                    foreach (List <int> l in mesh[j].faces)
                    {
                        foreach (int index in l)
                        {
                            fv.writeShort(index);
                        }
                        fv.align(32, 0xFF);
                    }
                }
            }


            for (int i = 0; i < mesh.Count; i++)
            {
                if (i == 0 && mode == 1)
                {
                    descript[0].WriteDescription(f);
                    f.writeInt(vertSize);
                }

                f.writeInt(mesh[i].nodeList.Count);
                //Console.WriteLine(mesh[i].faces.Count + " " + mesh[i].nodeList.Count);
                for (int j = 0; j < mesh[i].nodeList.Count; j++)
                {
                    f.writeInt(mesh[i].nodeList[j].Count);

                    for (int k = 0; k < mesh[i].nodeList[j].Count; k++)
                    {
                        f.writeInt(mesh[i].nodeList[j][k]);
                    }

                    f.writeInt(mesh[i].faces[j].Count);

                    // TODO: This stuff
                    if (hasNameTable)
                    {
                        //int nameId = d.readInt();
                    }

                    /*if (mode == 0)
                     * {
                     *  if (format == 4)
                     *  {
                     *      int[] buffer = new int[primitiveCount];
                     *      for (int k = 0; k < primitiveCount; k++)
                     *      {
                     *          buffer[k] = d.readShort();
                     *      }
                     *      d.align(4);
                     *      List<int> buf = new List<int>();
                     *      buf.AddRange(buffer);
                     *      m.faces.Add(buf);
                     *  }
                     *  else
                     *  {
                     *      Descriptor des = new Descriptor();
                     *      des.ReadDescription(d);
                     *      descript.Add(des);
                     *  }
                     *
                     * }*/
                }
            }

            // TODO: STRING TABLE

            /*if (hasNameTable)
             * {
             *  for (int i = 0; i < mesh.Count; i++)
             *  {
             *      int index = d.readByte();
             *      nameTable.Add(d.readString());
             *  }
             * }*/


            if (format != 4)
            {
                f.align(32, 0xFF);
            }

            f.writeOutput(fv);

            return(f.getBytes());
        }
예제 #8
0
        public override byte[] Rebuild()
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Big;

            f.writeHex("4C494748"); //LIGH
            f.writeInt(version);
            f.writeInt(frameCount);
            if (version == 5)
            {
                f.writeInt(frameDuration);
            }

            //Offsets
            int padding = 0;

            while ((((frameCount * 3) + padding) % 4) != 0) //All offsets must be multiples of 4 or the game won't use the file properly
            {
                padding++;
            }

            int[] offsets = new int[6];
            int   currOff = 0x24;

            if (version == 4)
            {
                currOff = 0x24;
            }
            else if (version == 5)
            {
                currOff = 0x28;
            }

            for (int i = 0; i < 5; i++)
            {
                offsets[i + 1] = (rgbProperties[i].enabled) ? currOff : 0x0;
                if (rgbProperties[i].enabled)
                {
                    currOff += (frameCount * 3) + padding;
                }
            }
            offsets[0] = currOff;

            for (int i = 0; i < 6; i++)
            {
                f.writeInt(offsets[i]);
            }

            //RGB properties
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < frameCount; j++)
                {
                    for (int k = 0; k < 3; k++)
                    {
                        f.writeByte(rgbProperties[i].frames[j][k]);
                    }
                }

                for (int j = 0; j < padding; j++)
                {
                    f.writeByte(0);
                }
            }

            //Light data
            for (int i = 0; i < frameCount; i++)
            {
                for (int j = 0; j < 17; j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        f.writeInt((int)lightFrames[i].lightSets[j].lights[k].enabled);
                        for (int l = 0; l < 3; l++)
                        {
                            f.writeFloat(lightFrames[i].lightSets[j].lights[k].angle[l]);
                        }
                        f.writeFloat(lightFrames[i].lightSets[j].lights[k].colorHue);
                        f.writeFloat(lightFrames[i].lightSets[j].lights[k].colorSat);
                        f.writeFloat(lightFrames[i].lightSets[j].lights[k].colorVal);
                    }
                    f.writeByte(lightFrames[i].lightSets[j].fog.unknown);
                    for (int k = 0; k < 3; k++)
                    {
                        f.writeByte(lightFrames[i].lightSets[j].fog.color[k]);
                    }
                }
                f.writeByte(lightFrames[i].effect.unknown);
                for (int j = 0; j < 3; j++)
                {
                    f.writeByte(lightFrames[i].effect.color[j]);
                }
                for (int j = 0; j < 3; j++)
                {
                    f.writeFloat(lightFrames[i].effect.position[j]);
                }
            }

            return(f.getBytes());
        }
예제 #9
0
        public override byte[] Rebuild()
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Big;

            f.writeHex("000000010A014C564431");

            f.writeByte(1);
            f.writeInt(collisions.Count);
            foreach (Collision c in collisions)
            {
                c.save(f);
            }

            f.writeByte(1);
            f.writeInt(spawns.Count);
            foreach (Spawn s in spawns)
            {
                s.save(f);
            }

            f.writeByte(1);
            f.writeInt(respawns.Count);
            foreach (Spawn s in respawns)
            {
                s.save(f);
            }

            f.writeByte(1);
            f.writeInt(cameraBounds.Count);
            foreach (Bounds b in cameraBounds)
            {
                b.save(f);
            }

            f.writeByte(1);
            f.writeInt(blastzones.Count);
            foreach (Bounds b in blastzones)
            {
                b.save(f);
            }

            f.writeByte(1);
            f.writeInt(enemySpawns.Count);
            foreach (EnemyGenerator e in enemySpawns)
            {
                e.save(f);
            }

            for (int i = 0; i < 5; i++)
            {
                f.writeByte(1);
                f.writeInt(0);
            }

            f.writeByte(1);
            f.writeInt(damageShapes.Count);
            foreach (DamageShape shape in damageShapes)
            {
                shape.save(f);
            }

            f.writeByte(1);
            f.writeInt(itemSpawns.Count);
            foreach (ItemSpawner item in itemSpawns)
            {
                item.save(f);
            }

            f.writeByte(1);
            f.writeInt(generalShapes.Count);
            foreach (GeneralShape shape in generalShapes)
            {
                shape.save(f);
            }

            f.writeByte(1);
            f.writeInt(generalPoints.Count);
            foreach (GeneralPoint p in generalPoints)
            {
                p.save(f);
            }

            for (int i = 0; i < 4; i++)
            {
                f.writeByte(1);
                f.writeInt(0);
            }

            return(f.getBytes());
        }
예제 #10
0
        public override byte[] Rebuild()
        {
            FileOutput o    = new FileOutput();
            FileOutput data = new FileOutput();

            //We always want BE for the first six bytes
            o.Endian    = Endianness.Big;
            data.Endian = Endianness.Big;

            if (Endian == Endianness.Big)
            {
                o.writeUInt(0x4E545033); //NTP3
            }
            else if (Endian == Endianness.Little)
            {
                o.writeUInt(0x4E545744); //NTWD
            }

            //Most NTWU NUTs are 0x020E, which isn't valid for NTP3/NTWD
            if (Version > 0x0200)
            {
                Version = 0x0200;
            }
            o.writeUShort(Version);

            //After that, endian is used appropriately
            o.Endian    = Endian;
            data.Endian = Endian;

            o.writeUShort((ushort)Nodes.Count);
            o.writeInt(0);
            o.writeInt(0);

            //calculate total header size
            uint headerLength = 0;

            foreach (NutTexture texture in Nodes)
            {
                byte surfaceCount = (byte)texture.surfaces.Count;
                bool isCubemap    = surfaceCount == 6;
                if (surfaceCount < 1 || surfaceCount > 6)
                {
                    throw new NotImplementedException($"Unsupported surface amount {surfaceCount} for texture with hash 0x{texture.HashId:X}. 1 to 6 faces are required.");
                }
                else if (surfaceCount > 1 && surfaceCount < 6)
                {
                    throw new NotImplementedException($"Unsupported cubemap face amount for texture with hash 0x{texture.HashId:X}. Six faces are required.");
                }
                byte mipmapCount = (byte)texture.surfaces[0].mipmaps.Count;

                ushort headerSize = 0x50;
                if (isCubemap)
                {
                    headerSize += 0x10;
                }
                if (mipmapCount > 1)
                {
                    headerSize += (ushort)(mipmapCount * 4);
                    while (headerSize % 0x10 != 0)
                    {
                        headerSize += 1;
                    }
                }

                headerLength += headerSize;
            }

            // write headers+data
            foreach (NutTexture texture in Nodes)
            {
                byte surfaceCount = (byte)texture.surfaces.Count;
                bool isCubemap    = surfaceCount == 6;
                byte mipmapCount  = (byte)texture.surfaces[0].mipmaps.Count;

                uint dataSize = 0;

                foreach (var mip in texture.GetAllMipmaps())
                {
                    dataSize += (uint)mip.Length;
                    while (dataSize % 0x10 != 0)
                    {
                        dataSize += 1;
                    }
                }

                ushort headerSize = 0x50;
                if (isCubemap)
                {
                    headerSize += 0x10;
                }
                if (mipmapCount > 1)
                {
                    headerSize += (ushort)(mipmapCount * 4);
                    while (headerSize % 0x10 != 0)
                    {
                        headerSize += 1;
                    }
                }

                o.writeUInt(dataSize + headerSize);
                o.writeUInt(0);
                o.writeUInt(dataSize);
                o.writeUShort(headerSize);
                o.writeUShort(0);

                o.writeByte(0);
                o.writeByte(mipmapCount);
                o.writeByte(0);
                o.writeByte(texture.getNutFormat());
                o.writeShort(texture.Width);
                o.writeShort(texture.Height);
                o.writeInt(0);
                o.writeUInt(texture.DdsCaps2);

                if (Version < 0x0200)
                {
                    o.writeUInt(0);
                }
                else if (Version >= 0x0200)
                {
                    o.writeUInt((uint)(headerLength + data.size()));
                }
                headerLength -= headerSize;
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(0);

                if (isCubemap)
                {
                    o.writeInt(texture.surfaces[0].mipmaps[0].Length);
                    o.writeInt(texture.surfaces[0].mipmaps[0].Length);
                    o.writeInt(0);
                    o.writeInt(0);
                }

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    texture.SwapChannelOrderDown();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        int ds = data.size();
                        data.writeBytes(texture.surfaces[surfaceLevel].mipmaps[mipLevel]);
                        data.align(0x10);
                        if (mipmapCount > 1 && surfaceLevel == 0)
                        {
                            o.writeInt(data.size() - ds);
                        }
                    }
                }
                o.align(0x10);

                if (texture.getNutFormat() == 14 || texture.getNutFormat() == 17)
                {
                    texture.SwapChannelOrderUp();
                }

                o.writeBytes(new byte[] { 0x65, 0x58, 0x74, 0x00 }); // "eXt\0"
                o.writeInt(0x20);
                o.writeInt(0x10);
                o.writeInt(0x00);

                o.writeBytes(new byte[] { 0x47, 0x49, 0x44, 0x58 }); // "GIDX"
                o.writeInt(0x10);
                o.writeInt(texture.HashId);
                o.writeInt(0);

                if (Version < 0x0200)
                {
                    o.writeOutput(data);
                    data = new FileOutput();
                }
            }

            if (Version >= 0x0200)
            {
                o.writeOutput(data);
            }

            return(o.getBytes());
        }
예제 #11
0
파일: LVD.cs 프로젝트: struz/Smash-Forge
        public override byte[] Rebuild()
        {
            FileOutput f = new FileOutput();

            f.Endian = Endianness.Big;

            f.writeHex("000000010A014C56443101");
            f.writeInt(collisions.Count);
            foreach (Collision c in collisions)
            {
                c.save(f);
            }
            f.writeByte(1);
            f.writeInt(spawns.Count);
            foreach (Point p in spawns)
            {
                f.writeHex("020401017735BB750000000201");
                f.writeString(p.name.PadRight(0x38, (char)0));
                f.writeByte(1);
                f.writeString(p.subname.PadRight(0x40, (char)0));
                f.writeByte(1);
                f.writeHex("00000000000000000000000000010000000001000000000000000000000000FFFFFFFF010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
                f.writeFloat(p.x);
                f.writeFloat(p.y);
            }
            f.writeByte(1);
            f.writeInt(respawns.Count);
            foreach (Point p in respawns)
            {
                f.writeHex("020401017735BB750000000201");
                f.writeString(p.name.PadRight(0x38, (char)0));
                f.writeByte(1);
                f.writeString(p.subname.PadRight(0x40, (char)0));
                f.writeByte(1);
                f.writeHex("00000000000000000000000000010000000001000000000000000000000000FFFFFFFF010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
                f.writeFloat(p.x);
                f.writeFloat(p.y);
            }
            f.writeByte(1);
            f.writeInt(cameraBounds.Count);
            foreach (Bounds b in cameraBounds)
            {
                f.writeHex("020401017735BB750000000201");
                f.writeString(b.name.PadRight(0x38, (char)0));
                f.writeByte(1);
                f.writeString(b.subname.PadRight(0x40, (char)0));
                f.writeByte(1);
                f.writeHex("00000000000000000000000000010000000001000000000000000000000000FFFFFFFF010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
                f.writeFloat(b.left);
                f.writeFloat(b.right);
                f.writeFloat(b.top);
                f.writeFloat(b.bottom);
            }
            f.writeByte(1);
            f.writeInt(blastzones.Count);
            foreach (Bounds b in blastzones)
            {
                f.writeHex("020401017735BB750000000201");
                f.writeString(b.name.PadRight(0x38, (char)0));
                f.writeByte(1);
                f.writeString(b.subname.PadRight(0x40, (char)0));
                f.writeByte(1);
                f.writeHex("00000000000000000000000000010000000001000000000000000000000000FFFFFFFF010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
                f.writeFloat(b.left);
                f.writeFloat(b.right);
                f.writeFloat(b.top);
                f.writeFloat(b.bottom);
            }

            for (int i = 0; i < 7; i++)
            {
                f.writeByte(1);
                f.writeInt(0);
            }

            f.writeByte(1);
            f.writeInt(items.Count);
            foreach (ItemSpawner item in items)
            {
                item.save(f);
            }

            f.writeByte(1);
            f.writeInt(generalShapes.Count);
            foreach (LVDGeneralShape shape in generalShapes)
            {
                shape.save(f);
            }


            f.writeByte(1);
            f.writeInt(generalPoints.Count);
            foreach (Point p in generalPoints)
            {
                f.writeHex("010401017735BB750000000201");
                f.writeChars(p.name.PadRight(0x38, (char)0).ToCharArray());
                f.writeByte(1);
                f.writeChars(p.subname.PadRight(0x40, (char)0).ToCharArray());
                f.writeByte(1);
                f.writeHex("00000000432100000000000000010000000001000000000000000000000000FFFFFFFF010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000100000004");
                f.writeFloat(p.x);
                f.writeFloat(p.y);
                f.writeBytes(new byte[0x14]);
            }

            for (int i = 0; i < 4; i++)
            {
                f.writeByte(1);
                f.writeInt(0);
            }

            return(f.getBytes());
        }
예제 #12
0
        public override byte[] Rebuild()
        {
            FileOutput o = new FileOutput();

            o.writeInt(0x4E545033); // "NTP3"
            o.writeShort(0x0200);
            o.writeShort(textures.Count);
            o.writeInt(0);
            o.writeInt(0);

            int offset = textures.Count * 0x60;

            foreach (var texture in textures)
            {
                int size       = 0;
                int headerSize = 0x60;

                foreach (var mip in texture.mipmaps)
                {
                    size += mip.Length;
                }

                // // headerSize 0x50 seems to crash with models
                //if (texture.mipmaps.Count == 1)
                //{
                //    headerSize = 0x50;
                //}

                o.writeInt(size + headerSize);
                o.writeInt(0x00);
                o.writeInt(size);
                o.writeShort(headerSize);
                o.writeShort(0);
                o.writeShort(texture.mipmaps.Count);
                o.writeShort(texture.getNutFormat());
                o.writeShort(texture.width);
                o.writeShort(texture.height);
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(offset);
                o.writeInt(0);
                o.writeInt(0);
                o.writeInt(0);

                if (headerSize > 0x50)
                {
                    foreach (var mip in texture.mipmaps)
                    {
                        o.writeInt(mip.Length);
                    }

                    // Sizes for missing mips.
                    for (int j = 0; j < 4 - texture.mipmaps.Count; j++)
                    {
                        o.writeInt(0);
                    }
                }

                o.writeInt(0x65587400); // "eXt\0"
                o.writeInt(0x20);
                o.writeInt(0x10);
                o.writeInt(0x00);
                o.writeInt(0x47494458); // "GIDX"
                o.writeInt(0x10);

                o.writeInt(texture.id);
                o.writeInt(0);

                offset += (size - headerSize);
            }

            foreach (var texture in textures)
            {
                foreach (var mip in texture.mipmaps)
                {
                    o.writeBytes(mip);
                }
            }

            return(o.getBytes());
        }
예제 #13
0
        public static byte[] encodeETCa4(Bitmap b)
        {
            int width  = b.Width;
            int height = b.Height;

            int[] pixels = new int[width * height];

            int i, j;

            FileOutput o = new FileOutput();

            o.Endian = System.IO.Endianness.Little;

            for (i = 0; i < height; i += 8)
            {
                for (j = 0; j < width; j += 8)
                {
                    int x, y;

                    Color[] temp = new Color[16];
                    int     pi   = 0;
                    for (x = i; x < i + 4; x++)
                    {
                        for (y = j; y < j + 4; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    for (int ax = 0; ax < 4; ax++)
                    {
                        for (int ay = 0; ay < 4; ay++)
                        {
                            int a = (temp[ax + ay * 4].A >> 4);
                            ay++;
                            a |= (temp[ax + ay * 4].A >> 4) << 4;
                            o.writeByte(a);
                        }
                    }

                    ulong g = GenETC1(temp);
                    o.writeInt((int)(g & 0xFFFFFFFF));
                    o.writeInt((int)((g >> 32) & 0xFFFFFFFF));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i; x < i + 4; x++)
                    {
                        for (y = j + 4; y < j + 8; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    for (int ax = 0; ax < 4; ax++)
                    {
                        for (int ay = 0; ay < 4; ay++)
                        {
                            int a = (temp[ax + ay * 4].A >> 4);
                            ay++;
                            a |= (temp[ax + ay * 4].A >> 4) << 4;
                            o.writeByte(a);
                        }
                    }

                    g = GenETC1(temp);
                    o.writeInt((int)(g & 0xFFFFFFFF));
                    o.writeInt((int)((g >> 32) & 0xFFFFFFFF));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i + 4; x < i + 8; x++)
                    {
                        for (y = j; y < j + 4; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    for (int ax = 0; ax < 4; ax++)
                    {
                        for (int ay = 0; ay < 4; ay++)
                        {
                            int a = (temp[ax + ay * 4].A >> 4);
                            ay++;
                            a |= (temp[ax + ay * 4].A >> 4) << 4;
                            o.writeByte(a);
                        }
                    }

                    g = GenETC1(temp);
                    o.writeInt((int)(g & 0xFFFFFFFF));
                    o.writeInt((int)((g >> 32) & 0xFFFFFFFF));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i + 4; x < i + 8; x++)
                    {
                        for (y = j + 4; y < j + 8; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    for (int ax = 0; ax < 4; ax++)
                    {
                        for (int ay = 0; ay < 4; ay++)
                        {
                            int a = (temp[ax + ay * 4].A >> 4);
                            ay++;
                            a |= (temp[ax + ay * 4].A >> 4) << 4;
                            o.writeByte(a);
                        }
                    }

                    g = GenETC1(temp);
                    o.writeInt((int)(g & 0xFFFFFFFF));
                    o.writeInt((int)((g >> 32) & 0xFFFFFFFF));
                }
            }

            return(o.getBytes());
        }
예제 #14
0
        public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn)
        {
            if (vbn == null || a == null)
            {
                return new byte[] { }
            }
            ;
            FileOutput o = new FileOutput();

            o.Endian = Endianness.Big;

            FileOutput t1 = new FileOutput();

            t1.Endian = Endianness.Big;

            FileOutput t2 = new FileOutput();

            t2.Endian = Endianness.Big;

            o.writeString("OMO ");
            o.writeShort(1);        //idk
            o.writeShort(3);        //idk

            o.writeInt(0x091E100C); //flags??


            o.writeShort(0);             //padding
            o.writeShort(a.Bones.Count); // numOfNodes

            o.writeShort(a.FrameCount);  // frame size
            o.writeShort(0);             // frame start ??

            o.writeInt(0);
            o.writeInt(0);
            o.writeInt(0);

            o.writeIntAt(o.size(), 0x14);

            // ASSESSMENT
            Vector3[] maxT     = new Vector3[a.Bones.Count], minT = new Vector3[a.Bones.Count];
            Vector4[] maxR     = new Vector4[a.Bones.Count], minR = new Vector4[a.Bones.Count];
            Vector3[] maxS     = new Vector3[a.Bones.Count], minS = new Vector3[a.Bones.Count];
            bool[]    hasScale = new bool[a.Bones.Count];
            bool[]    hasTrans = new bool[a.Bones.Count];
            bool[]    hasRot   = new bool[a.Bones.Count];

            bool[] conScale = new bool[a.Bones.Count];
            bool[] conTrans = new bool[a.Bones.Count];
            bool[] conRot   = new bool[a.Bones.Count];

            a.SetFrame(0);

            List <List <Bone> > Frames = new List <List <Bone> >();

            {
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Animation.KeyNode keynode = ((Animation.KeyNode)a.Bones[j]);
                    if (keynode.XPOS.HasAnimation() || keynode.YPOS.HasAnimation() || keynode.ZPOS.HasAnimation())
                    {
                        hasTrans[j] = true;
                    }
                    if (keynode.XROT.HasAnimation())
                    {
                        hasRot[j] = true;
                    }
                    if (keynode.XSCA.HasAnimation() || keynode.YSCA.HasAnimation() || keynode.ZSCA.HasAnimation())
                    {
                        hasScale[j] = true;
                    }

                    maxT[j] = new Vector3(-999f, -999f, -999f);
                    minT[j] = new Vector3(999f, 999f, 999f);
                    maxS[j] = new Vector3(-999f, -999f, -999f);
                    minS[j] = new Vector3(999f, 999f, 999f);
                    maxR[j] = new Vector4(-999f, -999f, -999f, -999f);
                    minR[j] = new Vector4(999f, 999f, 999f, 999f);

                    foreach (Animation.KeyFrame key in keynode.XPOS.Keys)
                    {
                        maxT[j].X = Math.Max(maxT[j].X, key.Value);
                        minT[j].X = Math.Min(minT[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YPOS.Keys)
                    {
                        maxT[j].Y = Math.Max(maxT[j].Y, key.Value);
                        minT[j].Y = Math.Min(minT[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZPOS.Keys)
                    {
                        maxT[j].Z = Math.Max(maxT[j].Z, key.Value);
                        minT[j].Z = Math.Min(minT[j].Z, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.XSCA.Keys)
                    {
                        maxS[j].X = Math.Max(maxS[j].X, key.Value);
                        minS[j].X = Math.Min(minS[j].X, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.YSCA.Keys)
                    {
                        maxS[j].Y = Math.Max(maxS[j].Y, key.Value);
                        minS[j].Y = Math.Min(minS[j].Y, key.Value);
                    }
                    foreach (Animation.KeyFrame key in keynode.ZSCA.Keys)
                    {
                        maxS[j].Z = Math.Max(maxS[j].Z, key.Value);
                        minS[j].Z = Math.Min(minS[j].Z, key.Value);
                    }

                    Bone b = vbn.getBone(keynode.Text);
                    //if (b == null)continue;
                    if (b != null)
                    {
                        if (maxT[j].X == -999)
                        {
                            maxT[j].X = b.position[0];
                        }
                        if (maxT[j].Y == -999)
                        {
                            maxT[j].Y = b.position[1];
                        }
                        if (maxT[j].Z == -999)
                        {
                            maxT[j].Z = b.position[2];
                        }
                        if (minT[j].X == -999)
                        {
                            minT[j].X = b.position[0];
                        }
                        if (minT[j].Y == -999)
                        {
                            minT[j].Y = b.position[1];
                        }
                        if (minT[j].Z == -999)
                        {
                            minT[j].Z = b.position[2];
                        }

                        if (maxS[j].X == -999)
                        {
                            maxS[j].X = b.scale[0];
                        }
                        if (maxS[j].Y == -999)
                        {
                            maxS[j].Y = b.scale[1];
                        }
                        if (maxS[j].Z == -999)
                        {
                            maxS[j].Z = b.scale[2];
                        }
                        if (minS[j].X == -999)
                        {
                            minS[j].X = b.scale[0];
                        }
                        if (minS[j].Y == -999)
                        {
                            minS[j].Y = b.scale[1];
                        }
                        if (minS[j].Z == -999)
                        {
                            minS[j].Z = b.scale[2];
                        }
                    }
                }
            }

            //TODO: Euler Rotation Values
            VBN tempvbn = new VBN();

            a.SetFrame(0);
            for (int i = 0; i < a.FrameCount; i++)
            {
                //Frames.Add(new List<Bone>());
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Animation.KeyNode keynode = a.Bones[j];
                    Bone b = vbn.getBone(keynode.Text);
                    //if(b == null) continue;
                    maxR[j].X = Math.Max(maxR[j].X, b.rot.X);
                    minR[j].X = Math.Min(minR[j].X, b.rot.X);
                    maxR[j].Y = Math.Max(maxR[j].Y, b.rot.Y);
                    minR[j].Y = Math.Min(minR[j].Y, b.rot.Y);
                    maxR[j].Z = Math.Max(maxR[j].Z, b.rot.Z);
                    minR[j].Z = Math.Min(minR[j].Z, b.rot.Z);

                    Bone f1 = new Bone(tempvbn);
                    f1.pos = b.pos;
                    f1.rot = b.rot;
                    f1.sca = b.sca;
                    //Frames[i].Add(f1);
                }
                a.NextFrame(vbn);
            }

            // NODE INFO

            int t2Size = 0;

            for (int i = 0; i < a.Bones.Count; i++)
            {
                int flag = 0;

                conRot[i]   = false;
                conScale[i] = false;
                conTrans[i] = false;

                // check for constant
                if (maxT[i].Equals(minT[i]))
                {
                    conTrans[i] = true;
                }
                if (maxR[i].Equals(minR[i]))
                {
                    conRot[i] = true;
                }
                if (maxS[i].Equals(minS[i]))
                {
                    conScale[i] = true;
                }

                if (hasTrans[i])
                {
                    flag |= 0x01000000;
                }
                if (hasRot[i])
                {
                    flag |= 0x02000000;
                }
                if (hasScale[i])
                {
                    flag |= 0x04000000;
                }

                if (conTrans[i] && hasTrans[i])
                {
                    flag |= 0x00200000;
                }
                else
                {
                    flag |= 0x00080000;
                }

                if (conRot[i] && hasRot[i])
                {
                    flag |= 0x00007000;
                }
                else
                {
                    flag |= 0x00005000;
                }

                if (conScale[i] && hasScale[i])
                {
                    flag |= 0x00000200;
                }
                else
                {
                    flag |= 0x00000080;
                }

                flag |= 0x00000001;

                //uint id = 999;

                Bone b    = vbn.getBone(a.Bones[i].Text);
                int  hash = -1;
                if (MainForm.Hashes.names.ContainsKey(a.Bones[i].Text))
                {
                    hash = (int)MainForm.Hashes.names[a.Bones[i].Text];
                }
                else
                {
                    if (b != null)
                    {
                        hash = (int)b.boneId;
                    }
                    else
                    {
                        continue;
                    }
                }
                //if(hash == -1)
                //hash = (int)FileData.crc32(getNodeId(nodeid.get(i)).name);
                o.writeInt(flag);      // flags...
                o.writeInt(hash);      //hash
                o.writeInt(t1.size()); // Offset in 1 table
                o.writeInt(t2Size);    // Offset in 2 table

                // calculate size needed
                if (hasTrans[i])
                {
                    t1.writeFloat(minT[i].X);
                    t1.writeFloat(minT[i].Y);
                    t1.writeFloat(minT[i].Z);

                    if (!conTrans[i])
                    {
                        maxT[i].X -= minT[i].X;
                        maxT[i].Y -= minT[i].Y;
                        maxT[i].Z -= minT[i].Z;

                        t1.writeFloat(maxT[i].X);
                        t1.writeFloat(maxT[i].Y);
                        t1.writeFloat(maxT[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasRot[i])
                {
                    t1.writeFloat(minR[i].X);
                    t1.writeFloat(minR[i].Y);
                    t1.writeFloat(minR[i].Z);

                    if (!conRot[i])
                    {
                        maxR[i].X -= minR[i].X;
                        maxR[i].Y -= minR[i].Y;
                        maxR[i].Z -= minR[i].Z;

                        t1.writeFloat(maxR[i].X);
                        t1.writeFloat(maxR[i].Y);
                        t1.writeFloat(maxR[i].Z);

                        t2Size += 6;
                    }
                }

                if (hasScale[i])
                {
                    t1.writeFloat(minS[i].X);
                    t1.writeFloat(minS[i].Y);
                    t1.writeFloat(minS[i].Z);

                    if (!conScale[i])
                    {
                        maxS[i].X -= minS[i].X;
                        maxS[i].Y -= minS[i].Y;
                        maxS[i].Z -= minS[i].Z;

                        t1.writeFloat(maxS[i].X);
                        t1.writeFloat(maxS[i].Y);
                        t1.writeFloat(maxS[i].Z);

                        t2Size += 6;
                    }
                }
            }

            o.writeIntAt(o.size(), 0x18);

            o.writeOutput(t1);

            o.writeIntAt(o.size(), 0x1C);

            // INTERPOLATION

            a.SetFrame(0);

            bool go = true;

            for (int i = 0; i < a.FrameCount; i++)
            {
                a.NextFrame(vbn);
                for (int j = 0; j < a.Bones.Count; j++)
                {
                    Bone node = vbn.getBone(a.Bones[j].Text);
                    if (node == null)
                    {
                        continue;
                    }

                    if (hasTrans[j] && !conTrans[j])
                    {
                        t2.writeShort((int)(((node.pos.X - minT[j].X) / maxT[j].X) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Y - minT[j].Y) / maxT[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((node.pos.Z - minT[j].Z) / maxT[j].Z) * 0xFFFF));
                    }

                    if (hasRot[j] && !conRot[j])
                    {
                        Quaternion r = node.rot;
                        r.Normalize();
                        t2.writeShort((int)(((r.X - minR[j].X) / maxR[j].X) * 0xFFFF));
                        t2.writeShort((int)(((r.Y - minR[j].Y) / maxR[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((r.Z - minR[j].Z) / maxR[j].Z) * 0xFFFF));
                    }

                    if (hasScale[j] && !conScale[j])
                    {
                        t2.writeShort((int)(((node.sca.X - minS[j].X) / maxS[j].X) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Y - minS[j].Y) / maxS[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((node.sca.Z - minS[j].Z) / maxS[j].Z) * 0xFFFF));
                    }
                }

                if (go)
                {
                    o.writeShortAt(t2.size(), 0x12);
                    go = false;
                }
            }

            o.writeOutput(t2);
            return(o.getBytes());
        }
    }
예제 #15
0
        public static byte[] encodeETC(Bitmap b)
        {
            int width  = b.Width;
            int height = b.Height;

            int[] pixels = new int[width * height];
            init();

            int i, j;

            FileOutput o = new FileOutput();

            o.Endian = System.IO.Endianness.Little;

            for (i = 0; i < height; i += 8)
            {
                for (j = 0; j < width; j += 8)
                {
                    int x, y;

                    Color[] temp = new Color[16];
                    int     pi   = 0;
                    for (x = i; x < i + 4; x++)
                    {
                        for (y = j; y < j + 4; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    o.writeBytes(GenETC1(temp));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i; x < i + 4; x++)
                    {
                        for (y = j + 4; y < j + 8; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    o.writeBytes(GenETC1(temp));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i + 4; x < i + 8; x++)
                    {
                        for (y = j; y < j + 4; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    o.writeBytes(GenETC1(temp));


                    temp = new Color[16];
                    pi   = 0;
                    for (x = i + 4; x < i + 8; x++)
                    {
                        for (y = j + 4; y < j + 8; y++)
                        {
                            temp[pi++] = b.GetPixel(y, x);
                        }
                    }

                    o.writeBytes(GenETC1(temp));
                }
            }

            return(o.getBytes());
        }
예제 #16
0
        public override byte[] Rebuild()
        {
            FileOutput file = new FileOutput();

            if (file != null)
            {
                if (Endian == Endianness.Little)
                {
                    file.Endian = Endianness.Little;
                    file.writeString(" NBV");
                    file.writeShort(0x02);
                    file.writeShort(0x01);
                }
                else if (Endian == Endianness.Big)
                {
                    file.Endian = Endianness.Big;
                    file.writeString("VBN ");
                    file.writeShort(0x01);
                    file.writeShort(0x02);
                }


                file.writeInt(bones.Count);
                if (boneCountPerType[0] == 0)
                {
                    boneCountPerType[0] = (uint)bones.Count;
                }
                for (int i = 0; i < 4; i++)
                {
                    file.writeInt((int)boneCountPerType[i]);
                }

                for (int i = 0; i < bones.Count; i++)
                {
                    file.writeString(bones[i].Text);
                    for (int j = 0; j < 64 - bones[i].Text.Length; j++)
                    {
                        file.writeByte(0);
                    }
                    file.writeInt((int)bones[i].boneType);
                    if (bones[i].parentIndex == -1)
                    {
                        file.writeInt(0x0FFFFFFF);
                    }
                    else
                    {
                        file.writeInt(bones[i].parentIndex);
                    }
                    file.writeInt((int)bones[i].boneId);
                }

                for (int i = 0; i < bones.Count; i++)
                {
                    file.writeFloat(bones[i].position[0]);
                    file.writeFloat(bones[i].position[1]);
                    file.writeFloat(bones[i].position[2]);
                    file.writeFloat(bones[i].rotation[0]);
                    file.writeFloat(bones[i].rotation[1]);
                    file.writeFloat(bones[i].rotation[2]);
                    file.writeFloat(bones[i].scale[0]);
                    file.writeFloat(bones[i].scale[1]);
                    file.writeFloat(bones[i].scale[2]);
                }
            }
            return(file.getBytes());
        }