예제 #1
0
 public static void effectiveScale(SkelAnimation anim, Matrix4 sca)
 {
     foreach (KeyFrame frame in anim.frames)
     {
         foreach (KeyNode node in frame.nodes)
         {
             if (node.tType != -1)
             {
                 Vector3 pos = Vector3.TransformVector(node.t, sca);
                 if (node.t.X != -99)
                 {
                     node.t.X = pos.X;
                 }
                 if (node.t.Y != -99)
                 {
                     node.t.Y = pos.Y;
                 }
                 if (node.t.Z != -99)
                 {
                     node.t.Z = pos.Z;
                 }
             }
         }
     }
 }
예제 #2
0
        public SkelAnimation BakeToSkel(VBN skel)
        {
            SkelAnimation a = new SkelAnimation();

            for (int i = 1; i < anim.frameCount + 1; i++)
            {
                a.frames.Add(new KeyFrame());
            }

            for (int i = 0; i < anim.nodes.Count; i++)
            {
                Frame[] frames = Bake(i);

                int fr = 0;
                foreach (Frame f in frames)
                {
                    if (fr == 0)
                    {
                        fr++;
                        continue;
                    }
                    if (i >= skel.bones.Count)
                    {
                        continue;
                    }

                    KeyFrame frame = a.frames[fr - 1];
                    KeyNode  node  = new KeyNode();
                    frame.nodes.Add(node);

                    node.hash = skel.bones[i].boneId;

                    node.tType = 1;
                    node.rType = 1;
                    node.sType = 1;

                    node.t.X = f.x != -99 ? f.x : skel.bones[i].position[0];
                    node.t.Y = f.y != -99 ? f.y : skel.bones[i].position[1];
                    node.t.Z = f.z != -99 ? f.z : skel.bones[i].position[2];

                    node.r.X = f.rx != -99 ? f.rx * (float)Math.PI / 180 : skel.bones[i].rotation[0];
                    node.r.Y = f.ry != -99 ? f.ry * (float)Math.PI / 180 : skel.bones[i].rotation[1];
                    node.r.Z = f.rz != -99 ? f.rz * (float)Math.PI / 180 : skel.bones[i].rotation[2];

                    node.s.X = f.sx != -99 ? f.sx : skel.bones[i].scale[0];
                    node.s.Y = f.sy != -99 ? f.sy : skel.bones[i].scale[1];
                    node.s.Z = f.sz != -99 ? f.sz : skel.bones[i].scale[2];

                    node.r = VBN.FromEulerAngles(node.r.Z, node.r.Y, node.r.X);

                    fr++;
                }
            }

            return(a);
        }
예제 #3
0
        // temp stuff
        public static Dictionary <string, SkelAnimation> LoadAJ(string fname, VBN vbn)
        {
            // a note, I know that the main player file has the offsets for
            // animations, this is just for viewing
            FileData f = new FileData(fname);

            f.endian = System.IO.Endianness.Big;

            int pos = 0;

            Dictionary <string, SkelAnimation> animations = new Dictionary <string, SkelAnimation>();
            AnimationGroupNode group = new AnimationGroupNode()
            {
                Text = fname
            };

            MainForm.Instance.animList.treeView1.Nodes.Add(group);
            while (pos < f.Size())
            {
                Console.WriteLine(pos.ToString("x"));
                int           len  = f.ReadInt();
                DAT_Animation anim = new DAT_Animation();
                anim.Read(new FileData(f.GetSection(pos, len)));
                AnimTrack track = new AnimTrack(anim);

                if (pos == 0)
                {
                    //track.Show();
                }
                group.Nodes.Add(track.ToAnimation(vbn));
                SkelAnimation sa = track.BakeToSkel(vbn);
                //sa.Tag = track;
                //Runtime.Animations.Add(anim.Name, sa);
                // MainForm.Instance.animList.treeView1.Nodes.Add(anim.Name);
                animations.Add(anim.Name, sa);

                if (pos != 0)
                {
                    track.Dispose();
                    track.Close();
                }

                f.Skip(len - 4);
                f.Align(32);
                pos = f.Pos();
            }

            return(animations);
        }
예제 #4
0
        public static Animation read(FileData d)
        {
            d.endian = Endianness.Big;

            d.Skip(4); // header OMO
            d.Skip(4); // two shorts, idk

            d.Skip(4); //flags?

            d.Skip(2);
            int boneCount  = d.ReadUShort();
            int frameCount = d.ReadUShort();
            int frameSize  = d.ReadUShort();

            int offset1 = d.ReadInt();  // nodeOffset
            int offset2 = d.ReadInt();  // interOffset
            int offset3 = d.ReadInt();  // keyOffset

            SkelAnimation anim = new SkelAnimation();

            anim.tag = d;

            if (boneCount > offset2 / 0x10)
            {
                boneCount = offset2 / 0x10;
                anim.tag  = null;
            }

            // base frames
            // These are linked to bones via hashes
            d.Seek(offset1); //
            int[]     framekey = new int[boneCount];
            KeyNode[] baseNode = new KeyNode[boneCount];

            // Start positions for bones/nodes
            for (int i = 0; i < boneCount; i++)
            {
                flagsused = flagsused | d.ReadInt(); d.Seek(d.Pos() - 4);
                //Console.WriteLine(flagsused.ToString("x"));

                int flags = d.ReadByte();
                int tFlag = d.ReadByte();
                int rFlag = d.ReadByte();
                int sFlag = d.ReadByte();
                int hash  = d.ReadInt(); // used to find the identifying bone
                int off1  = d.ReadInt() + offset2;
                framekey[i] = d.ReadInt();

                bool hasTrans = (flags & 0x01) == 0x01;
                bool hasScale = (flags & 0x04) == 0x04;
                bool hasRot   = (flags & 0x02) == 0x02;

                KeyNode node = new KeyNode();
                baseNode[i] = node;

                node.hash = (uint)hash;

                int temp = d.Pos();
                d.Seek(off1);

                if (hasTrans)
                {
                    if (tFlag == 0x8)
                    { // interpolated
                        node.tType = KeyNode.Interpolated;
                        node.t     = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                        node.t2    = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }
                    else if (tFlag == 0x20)
                    {
                        node.tType = KeyNode.Constant;
                        node.t     = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }
                    else if (tFlag == 0x4)
                    {
                        // entire Vector3 provided in keyframe data i.e. KEYFRAME type
                        node.tType = KeyNode.Keyframe;
                    }
                }
                if (hasRot)
                {
                    if ((rFlag & 0xF0) != 0x50 && (rFlag & 0xF0) != 0x70 && (rFlag & 0xF0) != 0x60 && (rFlag & 0xF0) != 0xA0)
                    {
                        //Console.WriteLine(rFlag);
                    }

                    if ((rFlag & 0xF0) == 0xA0)
                    {
                        // All data is in the keyframe for this type
                        node.rType = KeyNode.Compressed;
                    }

                    if ((rFlag & 0xF0) == 0x50)
                    { // interpolated
                        node.rType = KeyNode.Interpolated;
                        node.rv    = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                        node.rv2   = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }

                    if ((rFlag & 0xF0) == 0x60)
                    {
                        node.rType  = KeyNode.Keyframe;
                        node.rv     = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                        node.rExtra = d.ReadFloat() / 65535;
                    }

                    if ((rFlag & 0xF0) == 0x70)
                    {
                        node.rType = KeyNode.Constant;
                        node.rv    = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }
                }

                if (hasScale)
                {
                    if ((sFlag & 0xF0) == 0x80)
                    { // interpolated
                        node.sType = KeyNode.Interpolated;
                        node.s     = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                        node.s2    = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }
                    // TODO: investigate the difference between these
                    if ((rFlag & 0x0F) == 0x02 || (rFlag & 0x0F) == 0x03)
                    { // constant
                        node.sType = KeyNode.Constant;
                        node.s     = new Vector3(d.ReadFloat(), d.ReadFloat(), d.ReadFloat());
                    }
                }
                d.Seek(temp);
            }

            // Interpolated type below here is always a set translation/rotation/scale
            // from the coords specified with the bone node above

            Animation a = new Animation("Anim");

            a.Tag        = anim.tag;
            a.frameCount = frameCount;

            d.Seek(offset3);

            for (int j = 0; j < boneCount; j++)
            {
                string bid  = "";
                int    hash = -1;
                if (!MainForm.hashes.ids.TryGetValue(baseNode[j].hash, out bid))
                {
                    hash = (int)baseNode[j].hash;
                }
                Animation.KeyNode n = new Animation.KeyNode(bid);
                n.hash = hash;
                a.bones.Add(n);
                n.type = Animation.BoneType.Normal;

                /*foreach (ModelContainer con in Runtime.ModelContainers)
                 *  if (con.VBN != null)
                 *      bid = con.VBN.getBone(baseNode[j].hash) == null ? "" : con.VBN.getBone(baseNode[j].hash).Text;*/

                for (int i = 0; i < a.frameCount; i++)
                {
                    d.Seek(offset3 + frameSize * i + framekey[j]);

                    if (baseNode[j].tType == KeyNode.Interpolated)
                    {
                        float i1 = ((float)d.ReadUShort() / 0xffff);
                        float i2 = ((float)d.ReadUShort() / 0xffff);
                        float i3 = ((float)d.ReadUShort() / 0xffff);

                        float x = baseNode[j].t.X + (baseNode[j].t2.X * (i1));
                        float y = baseNode[j].t.Y + (baseNode[j].t2.Y * (i2));
                        float z = baseNode[j].t.Z + (baseNode[j].t2.Z * (i3));

                        //node.t = new Vector3(x, y, z);  // Translation
                        n.xpos.keys.Add(new Animation.KeyFrame(x, i));
                        n.ypos.keys.Add(new Animation.KeyFrame(y, i));
                        n.zpos.keys.Add(new Animation.KeyFrame(z, i));
                    }
                    else if (baseNode[j].tType == KeyNode.Constant)
                    {
                        //node.t = baseNode[j].t;
                        n.xpos.keys.Add(new Animation.KeyFrame(baseNode[j].t.X, i));
                        n.ypos.keys.Add(new Animation.KeyFrame(baseNode[j].t.Y, i));
                        n.zpos.keys.Add(new Animation.KeyFrame(baseNode[j].t.Z, i));
                    }
                    else if (baseNode[j].tType == 2)
                    {
                        float x = d.ReadFloat();
                        float y = d.ReadFloat();
                        float z = d.ReadFloat();

                        //node.t = new Vector3(x, y, z);
                        n.xpos.keys.Add(new Animation.KeyFrame(x, i));
                        n.ypos.keys.Add(new Animation.KeyFrame(y, i));
                        n.zpos.keys.Add(new Animation.KeyFrame(z, i));
                    }

                    if (baseNode[j].rType == KeyNode.Compressed)
                    {
                        // There are 64 bits present for each node of this rot type
                        // The format is: 20bits * 3 of encoded floats, and 4 bits of flags
                        // The flags describe which 3 components of the quaternion are being presented
                        int b1 = d.ReadByte();
                        int b2 = d.ReadByte();
                        int b3 = d.ReadByte();
                        int b4 = d.ReadByte();
                        int b5 = d.ReadByte();
                        int b6 = d.ReadByte();
                        int b7 = d.ReadByte();
                        int b8 = d.ReadByte();

                        // Capture 20 bits at a time of the raw data
                        int f1    = (b1 << 12) | (b2 << 4) | ((b3 & 0xF0) >> 4);
                        int f2    = ((b3 & 0xF) << 16) | (b4 << 8) | b5;
                        int f3    = (b6 << 12) | (b7 << 4) | ((b8 & 0xF0) >> 4);
                        int flags = b8 & 0xF;

                        Quaternion r = new Quaternion();
                        switch (flags)
                        {
                        case 0:      // y, z, w provided
                            r.Y = encodedRot10ToQuaternionComponent(f1);
                            r.Z = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.X = (float)Math.Sqrt(Math.Abs(1 - (r.Y * r.Y + r.Z * r.Z + r.W * r.W)));
                            break;

                        case 1:      // x, z, w provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Z = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.Y = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Z * r.Z + r.W * r.W)));
                            break;

                        case 2:      // x, y, w provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Y = encodedRot10ToQuaternionComponent(f2);
                            r.W = encodedRot10ToQuaternionComponent(f3);

                            r.Z = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.W * r.W)));
                            break;

                        case 3:      // x, y, z, provided
                            r.X = encodedRot10ToQuaternionComponent(f1);
                            r.Y = encodedRot10ToQuaternionComponent(f2);
                            r.Z = encodedRot10ToQuaternionComponent(f3);

                            r.W = (float)Math.Sqrt(Math.Abs(1 - (r.X * r.X + r.Y * r.Y + r.Z * r.Z)));
                            break;

                        default:
                            Console.WriteLine("Unknown rotation type3 flags: " + flags);
                            break;
                        }
                        n.rotType = Animation.RotationType.Quaternion;
                        n.xrot.keys.Add(new Animation.KeyFrame(r.X, i));
                        n.yrot.keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.zrot.keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.wrot.keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else if (baseNode[j].rType == KeyNode.Interpolated)
                    {
                        float i1 = ((float)d.ReadUShort() / (0xffff));
                        float i2 = ((float)d.ReadUShort() / (0xffff));
                        float i3 = ((float)d.ReadUShort() / (0xffff));

                        float x = baseNode[j].rv.X + (baseNode[j].rv2.X * (i1));
                        float y = baseNode[j].rv.Y + (baseNode[j].rv2.Y * (i2));
                        float z = baseNode[j].rv.Z + (baseNode[j].rv2.Z * (i3));

                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        Quaternion r = new Quaternion(new Vector3(x, y, z), w);
                        r.Normalize();

                        n.rotType = Animation.RotationType.Quaternion;
                        n.xrot.keys.Add(new Animation.KeyFrame(r.X, i));
                        n.yrot.keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.zrot.keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.wrot.keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else if (baseNode[j].rType == KeyNode.Keyframe)
                    {
                        float scale = d.ReadUShort() * baseNode[j].rExtra;
                        float x     = baseNode[j].rv.X;
                        float y     = baseNode[j].rv.Y;
                        float z     = baseNode[j].rv.Z + scale;
                        float w     = rot6CalculateW(x, y, z);

                        Quaternion r = new Quaternion(x, y, z, w);
                        n.rotType = Animation.RotationType.Quaternion;
                        n.xrot.keys.Add(new Animation.KeyFrame(r.X, i));
                        n.yrot.keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.zrot.keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.wrot.keys.Add(new Animation.KeyFrame(r.W, i));
                    }
                    else
                    {
                        float x = baseNode[j].rv.X;
                        float y = baseNode[j].rv.Y;
                        float z = baseNode[j].rv.Z;
                        float w = (float)Math.Sqrt(Math.Abs(1 - (x * x + y * y + z * z)));

                        Quaternion r = new Quaternion(baseNode[j].rv, w);
                        r.Normalize();
                        n.rotType = Animation.RotationType.Quaternion;
                        n.xrot.keys.Add(new Animation.KeyFrame(r.X, i));
                        n.yrot.keys.Add(new Animation.KeyFrame(r.Y, i));
                        n.zrot.keys.Add(new Animation.KeyFrame(r.Z, i));
                        n.wrot.keys.Add(new Animation.KeyFrame(r.W, i));
                    }

                    if (baseNode[j].sType == KeyNode.Interpolated)
                    {
                        float i1 = ((float)d.ReadUShort() / (0xffff));
                        float i2 = ((float)d.ReadUShort() / (0xffff));
                        float i3 = ((float)d.ReadUShort() / (0xffff));

                        float x = baseNode[j].s.X + (baseNode[j].s2.X * (i1));
                        float y = baseNode[j].s.Y + (baseNode[j].s2.Y * (i2));
                        float z = baseNode[j].s.Z + (baseNode[j].s2.Z * (i3));

                        //node.s = new Vector3(x, y, z);
                        n.xsca.keys.Add(new Animation.KeyFrame(x, i));
                        n.ysca.keys.Add(new Animation.KeyFrame(y, i));
                        n.zsca.keys.Add(new Animation.KeyFrame(z, i));
                    }
                    else
                    {
                        //node.s = baseNode[j].s;
                        n.xsca.keys.Add(new Animation.KeyFrame(baseNode[j].s.X, i));
                        n.ysca.keys.Add(new Animation.KeyFrame(baseNode[j].s.Y, i));
                        n.zsca.keys.Add(new Animation.KeyFrame(baseNode[j].s.Z, i));
                    }
                }
            }

            return(a);
        }
예제 #5
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);

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

            for (int i = 0; i < a.Size(); i++)
            {
                a.NextFrame(vbn, true);
                List <Bone> bonelist = new List <Bone>();
                for (int j = 0; j < nodeid.Count; j++)
                {
                    Bone node = getNodeId(vbn, nodeid[j]);

                    Bone f1 = new Bone(tempvbn);
                    f1.pos = node.pos;
                    f1.rot = node.rot;
                    f1.sca = node.sca;
                    bonelist.Add(f1);

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

                        KeyNode n = a.GetFirstNode(nodeid[j]);
                        if (n != null)
                        {
                            if (n.rType != -1)
                            {
                                hasRot[j] = true;
                            }
                            if (n.tType != -1)
                            {
                                hasTrans[j] = true;
                            }
                            if (n.sType != -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 = -1;
                if (MainForm.hashes.names.ContainsKey(getNodeId(vbn, nodeid[i]).Text))
                {
                    hash = (int)MainForm.hashes.names[getNodeId(vbn, nodeid[i]).Text];
                }
                //else hash = (int)FileData.crc12(getNodeId(vbn, nodeid[i]).Text);
                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);

            bool go = false;

            foreach (List <Bone> bonelist in Frames)
            {
                //a.nextFrame(vbn);
                int j = 0;
                foreach (Bone node in bonelist)
                {
                    //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));
                    }
                    j++;
                }
                if (!go)
                {
                    o.WriteShortAt(t2.Size(), 0x12);
                    go = true;
                }
            }

            o.WriteOutput(t2);
            return(o.GetBytes());
        }
예제 #6
0
        public static void generateInter(SkelAnimation anim, int max, int nid, String part, float[] frame, float[] tan, float[] step, VBN vbn)
        {
            int in2  = 0;
            int out2 = 1;

            float degrad = (float)(Math.PI / 180f);

            for (int i = 0; i < max; i++)
            {
                KeyNode n = anim.GetNode(i, nid);
                if (part.Contains("R"))
                {
                    n.rType = 1;
                }
                else
                if (part.Contains("S"))
                {
                    n.sType = 1;
                }
                else
                {
                    n.tType = 1;
                }

                if (i > frame[out2])
                {
                    in2++;
                    out2++;
                }
                float inv    = frame[in2];
                float tanin  = tan[in2];
                float stepin = step[in2];

                if (frame[0] > i)
                {
                    inv    = 0;
                    tanin  = 0;
                    stepin = anim.GetBaseNodeValue(nid, part, vbn);
                    out2   = 0;
                    in2    = 0;
                }

                if (frame[0] == i && out2 == 0)
                {
                    out2 = 1;
                    in2  = 0;
                }

                switch (part)
                {
                case "RX":
                    n.r.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "RY":
                    n.r.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "RZ":
                    n.r.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]) * degrad;
                    break;

                case "X":
                    n.t.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "Y":
                    n.t.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "Z":
                    n.t.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SX":
                    n.s.X = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SY":
                    n.s.Y = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;

                case "SZ":
                    n.s.Z = interHermite(i, inv, frame[out2], tanin, tan[out2], stepin, step[out2]);
                    break;
                }
            }
        }