Пример #1
0
        public Animation toAnimation(VBN vbn)
        {
            Animation animation = new Animation(anim.Name);

            animation.FrameCount = anim.frameCount;

            int i = 0;

            foreach (Bone b in vbn.bones)
            {
                i = vbn.boneIndex(b.Text);

                if (i < anim.nodes.Count)
                {
                    List <DAT_Animation.DATAnimTrack> tracks = anim.nodes[i];

                    Animation.KeyNode node = new Animation.KeyNode(b.Text);
                    node.RotType = Animation.RotationType.EULER;

                    foreach (DAT_Animation.DATAnimTrack track in tracks)
                    {
                        switch (track.type)
                        {
                        case DAT_Animation.AnimType.XPOS:
                            node.XPOS = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.YPOS:
                            node.YPOS = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.ZPOS:
                            node.ZPOS = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.XROT:
                            node.XROT = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.YROT:
                            node.YROT = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.ZROT:
                            node.ZROT = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.XSCA:
                            node.XSCA = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.YSCA:
                            node.YSCA = CreateKeyGroup(i, track, false);
                            break;

                        case DAT_Animation.AnimType.ZSCA:
                            node.ZSCA = CreateKeyGroup(i, track, false);
                            break;
                        }
                    }

                    if (node.XSCA.HasAnimation() || node.YSCA.HasAnimation() || node.ZSCA.HasAnimation() ||
                        node.XPOS.HasAnimation() || node.YPOS.HasAnimation() || node.ZPOS.HasAnimation() ||
                        node.XROT.HasAnimation() || node.YROT.HasAnimation() || node.ZROT.HasAnimation())
                    {
                        animation.Bones.Add(node);
                    }
                }
            }

            return(animation);
        }
Пример #2
0
        public static AnimationGroupNode Read(string filename, ResFile TargetWiiUBFRES)
        {
            FileData f = new FileData(filename);

            f.seek(0);

            f.Endian = Endianness.Little;

            Console.WriteLine("Reading Animations ...");

            f.seek(4);                     // magic check
            int SwitchCheck = f.readInt(); //Switch version only has padded magic

            f.skip(4);
            if (SwitchCheck == 0x20202020)
            {
                //    SwitchAnim2WiiU(path); //Hacky auto convert switch anims to wii u


                ResNSW.ResFile b = new ResNSW.ResFile(filename);

                AnimationGroupNode ThisAnimation = new AnimationGroupNode()
                {
                    Text = "Skeleton Animations"
                };

                TreeNode dummy = new TreeNode()
                {
                    Text = "Animation Set"
                };

                int i = 0;
                foreach (ResNSW.SkeletalAnim ska in b.SkeletalAnims)
                {
                    Animation a = new Animation(ska.Name);
                    ThisAnimation.Nodes.Add(a);

                    a.FrameCount = ska.FrameCount;
                    i++;
                    try
                    {
                        foreach (Syroot.NintenTools.NSW.Bfres.BoneAnim bn in ska.BoneAnims)
                        {
                            FSKANode bonean = new FSKANode(bn);

                            Animation.KeyNode bone = new Animation.KeyNode("");
                            a.Bones.Add(bone);
                            if (ska.FlagsRotate == ResNSW.SkeletalAnimFlagsRotate.EulerXYZ)
                            {
                                bone.RotType = Animation.RotationType.EULER;
                            }
                            else
                            {
                                bone.RotType = Animation.RotationType.QUATERNION;
                            }

                            bone.Text = bonean.Text;

                            for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                            {
                                //Set base/start values for bones.
                                //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                if (Frame == 0 && Runtime.HasNoAnimationBaseValues == false)
                                {
                                    bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = 1
                                    });
                                    bone.XROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.X
                                    });
                                    bone.YROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Y
                                    });
                                    bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Z
                                    });
                                    bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.X
                                    });
                                    bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Y
                                    });
                                    bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Z
                                    });
                                }
                                foreach (FSKATrack track in bonean.tracks)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.HERMITE;
                                    frame.Frame     = Frame;

                                    FSKAKey left  = track.GetLeft(Frame);
                                    FSKAKey right = track.GetRight(Frame);
                                    float   value;



                                    value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                    // interpolate the value and apply
                                    switch (track.flag)
                                    {
                                    case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                    case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                    case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                    case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                    case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                    case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                    case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                    case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                    case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                return(ThisAnimation);
            }
            else
            {
                f.eof();

                TargetWiiUBFRES = new ResFile(filename);

                ThisAnimation = new AnimationGroupNode()
                {
                    Text = "Skeleton Animations"
                };

                TreeNode dummy = new TreeNode()
                {
                    Text = "Animation Set"
                };

                int i = 0;
                foreach (SkeletalAnim ska in TargetWiiUBFRES.SkeletalAnims.Values)
                {
                    Animation a = new Animation(ska.Name);
                    ThisAnimation.Nodes.Add(a);

                    a.FrameCount = ska.FrameCount;
                    i++;
                    try
                    {
                        foreach (BoneAnim bn in ska.BoneAnims)
                        {
                            FSKANodeWiiU bonean = new FSKANodeWiiU(bn);

                            Animation.KeyNode bone = new Animation.KeyNode("");
                            a.Bones.Add(bone);
                            if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ)
                            {
                                bone.RotType = Animation.RotationType.EULER;
                            }
                            else
                            {
                                bone.RotType = Animation.RotationType.QUATERNION;
                            }

                            bone.Text = bonean.Text;


                            for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                            {
                                //Set base/start values for bones.
                                //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                if (Frame == 0 && Runtime.HasNoAnimationBaseValues == false)
                                {
                                    bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.X
                                    });
                                    bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.Y
                                    });
                                    bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.sca.Z
                                    });
                                    bone.XROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.X
                                    });
                                    bone.YROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Y
                                    });
                                    bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.rot.Z
                                    });
                                    bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.X
                                    });
                                    bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Y
                                    });
                                    bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                    {
                                        Frame = 0, Value = bonean.pos.Z
                                    });
                                }
                                foreach (FSKATrack track in bonean.tracks)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.HERMITE;
                                    frame.Frame     = Frame;

                                    FSKAKey left  = track.GetLeft(Frame);
                                    FSKAKey right = track.GetRight(Frame);
                                    float   value;



                                    value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                    // interpolate the value and apply
                                    switch (track.flag)
                                    {
                                    case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                    case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                    case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                    case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                    case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                    case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                    case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                    case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                    case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
                return(ThisAnimation);
            }
        }
Пример #3
0
        public static void read(string fname, Animation a, VBN v)
        {
            StreamReader reader = File.OpenText(fname);
            string       line;

            string   current = "";
            bool     readBones = false;
            int      frame = 0, prevframe = 0;
            KeyFrame k = new KeyFrame();

            VBN vbn = v;

            if (v != null && v.bones.Count == 0)
            {
                readBones = true;
            }
            else
            {
                vbn = new VBN();
            }

            while ((line = reader.ReadLine()) != null)
            {
                line = Regex.Replace(line, @"\s+", " ");
                string[] args = line.Replace(";", "").TrimStart().Split(' ');

                if (args[0].Equals("nodes") || args[0].Equals("skeleton") || args[0].Equals("end") || args[0].Equals("time"))
                {
                    current = args[0];
                    if (args.Length > 1)
                    {
                        prevframe = frame;
                        frame     = int.Parse(args[1]);

                        /*if (frame != prevframe + 1) {
                         *                              Console.WriteLine ("Needs interpolation " + frame);
                         *                      }*/

                        k       = new KeyFrame();
                        k.frame = frame;
                        //a.addKeyframe(k);
                    }
                    continue;
                }

                if (current.Equals("nodes"))
                {
                    Bone b = new Bone(vbn);
                    b.Text        = args[1].Replace("\"", "");
                    b.parentIndex = int.Parse(args[2]);
                    //b.children = new System.Collections.Generic.List<int> ();
                    vbn.totalBoneCount++;
                    vbn.bones.Add(b);
                    Animation.KeyNode node = new Animation.KeyNode(b.Text);
                    a.Bones.Add(node);
                }

                if (current.Equals("time"))
                {
                    //Animation.KeyFrame n = new Animation.KeyFrame();

                    /*n.id = v.boneIndex(vbn.bones[int.Parse(args[0])].Text);
                     * if (n.id == -1)
                     * {
                     *  continue;
                     * }
                     * else
                     *  n.hash = v.bones[n.id].boneId;*/

                    // only if it finds the node
                    //k.addNode(n);

                    // reading the skeleton if this isn't an animation
                    if (readBones && frame == 0)
                    {
                        Bone b = vbn.bones[int.Parse(args[0])];
                        b.position    = new float[3];
                        b.rotation    = new float[3];
                        b.scale       = new float[3];
                        b.position[0] = float.Parse(args[1]);
                        b.position[1] = float.Parse(args[2]);
                        b.position[2] = float.Parse(args[3]);
                        b.rotation[0] = float.Parse(args[4]);
                        b.rotation[1] = float.Parse(args[5]);
                        b.rotation[2] = float.Parse(args[6]);
                        b.scale[0]    = 1f;
                        b.scale[1]    = 1f;
                        b.scale[2]    = 1f;

                        b.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                        b.rot = VBN.FromEulerAngles(float.Parse(args[6]), float.Parse(args[5]), float.Parse(args[4]));

                        if (b.parentIndex != -1)
                        {
                            vbn.bones [b.parentIndex].Nodes.Add(b);
                        }
                    }
                    Animation.KeyNode bone = a.GetBone(vbn.bones[int.Parse(args[0])].Text);
                    bone.RotType = Animation.RotationType.EULER;

                    Animation.KeyFrame n = new Animation.KeyFrame();
                    n.Value = float.Parse(args[1]);
                    n.Frame = frame;
                    bone.XPOS.Keys.Add(n);

                    n       = new Animation.KeyFrame();
                    n.Value = float.Parse(args[2]);
                    n.Frame = frame;
                    bone.YPOS.Keys.Add(n);

                    n       = new Animation.KeyFrame();
                    n.Value = float.Parse(args[3]);
                    n.Frame = frame;
                    bone.ZPOS.Keys.Add(n);

                    n       = new Animation.KeyFrame();
                    n.Value = float.Parse(args[4]);
                    n.Frame = frame;
                    bone.XROT.Keys.Add(n);

                    n       = new Animation.KeyFrame();
                    n.Value = float.Parse(args[5]);
                    n.Frame = frame;
                    bone.YROT.Keys.Add(n);

                    n       = new Animation.KeyFrame();
                    n.Value = float.Parse(args[6]);
                    n.Frame = frame;
                    bone.ZROT.Keys.Add(n);

                    if (args.Length > 7)
                    {
                        n       = new Animation.KeyFrame();
                        n.Value = float.Parse(args[7]);
                        n.Frame = frame;
                        bone.XSCA.Keys.Add(n);

                        n       = new Animation.KeyFrame();
                        n.Value = float.Parse(args[8]);
                        n.Frame = frame;
                        bone.YSCA.Keys.Add(n);

                        n       = new Animation.KeyFrame();
                        n.Value = float.Parse(args[9]);
                        n.Frame = frame;
                        bone.ZSCA.Keys.Add(n);
                    }
                }
            }

            a.FrameCount = frame;

            vbn.boneCountPerType[0] = (uint)vbn.bones.Count;
            vbn.update();
        }
Пример #4
0
        public static AnimationGroupNode Read(string filename, ResFile TargetWiiUBFRES, BFRES bfres)
        {
            string path = filename;

            FileData f = new FileData(filename);


            int Magic = f.readInt();

            if (Magic == 0x59617A30) //YAZO compressed
            {
                using (FileStream input = new FileStream(path, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    Yaz0Compression.Decompress(path, TEMP_FILE);

                    path = TEMP_FILE;
                }
            }

            f = new FileData(path);

            f.seek(0);

            f.Endian = Endianness.Little;

            Console.WriteLine("Reading Animations ...");

            f.seek(4);                     // magic check
            int SwitchCheck = f.readInt(); //Switch version only has padded magic

            f.skip(4);


            //    SwitchAnim2WiiU(path); //Hacky auto convert switch anims to wii u


            Syroot.NintenTools.NSW.Bfres.ResFile b = new Syroot.NintenTools.NSW.Bfres.ResFile(path);

            AnimationGroupNode ThisAnimation = new AnimationGroupNode()
            {
                Text = "Bone Visual Animations"
            };

            TreeNode dummy = new TreeNode()
            {
                Text = "Animation Set"
            };

            int i = 0;

            foreach (Syroot.NintenTools.NSW.Bfres.VisibilityAnim vis in b.BoneVisibilityAnims)
            {
                Animation a = new Animation(vis.Name);

                ThisAnimation.Nodes.Add(a);

                a.FrameCount = vis.FrameCount;
                i++;

                int boneindx = 0;
                if (vis.Names != null)
                {
                    foreach (string nm in vis.Names) //Loop through every bone. Not all have base and curve data
                    {
                        Animation.KeyNode bone = new Animation.KeyNode("");
                        a.Bones.Add(bone);
                        bone.Text = vis.Names[boneindx];



                        if (boneindx < vis.BaseDataList.Length)
                        {
                            bool bas = vis.BaseDataList[boneindx];

                            if (bas == true)
                            {
                                bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                                bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                                bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 1
                                });
                            }
                            else
                            {
                                bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                                bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                                bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                {
                                    Frame = 0, Value = 0
                                });
                            }
                        }


                        if (vis.Curves.Count != 0)
                        {
                            if (boneindx < vis.Curves.Count)
                            {
                                Syroot.NintenTools.NSW.Bfres.AnimCurve cr = vis.Curves[boneindx];

                                Console.WriteLine($"{vis.Name} {vis.Names[boneindx]}");

                                int frm = 0;
                                foreach (bool bn in cr.KeyStepBoolData)
                                {
                                    Animation.KeyFrame frame = new Animation.KeyFrame();
                                    frame.InterType = Animation.InterpolationType.STEP;
                                    frame.Frame     = cr.Frames[frm];



                                    Console.WriteLine(vis.Name + " " + vis.Names[boneindx] + " " + bn);

                                    switch (bn)
                                    {
                                    case true:
                                        frame.Value = 1; bone.XSCA.Keys.Add(frame);
                                        frame.Value = 1; bone.YSCA.Keys.Add(frame);
                                        frame.Value = 1; bone.ZSCA.Keys.Add(frame);
                                        break;

                                    case false:
                                        frame.Value = 0; bone.XSCA.Keys.Add(frame);
                                        frame.Value = 0; bone.YSCA.Keys.Add(frame);
                                        frame.Value = 0; bone.ZSCA.Keys.Add(frame);
                                        break;
                                    }
                                    frm++;
                                }
                            }
                        }

                        boneindx++;
                    }
                }
            }
            return(ThisAnimation);
        }
Пример #5
0
        public static Animation readAnim(FileData d, VBN m)
        {
            int offset  = d.readInt();
            int nameoff = d.readInt();

            d.skip(4);
            int fCount        = d.readShort();
            int animDataCount = d.readShort();

            d.skip(8);

            Animation anim = new Animation(d.readString(nameoff, -1));

            anim.FrameCount = fCount;

            //anim.setModel(m);

            d.seek(offset);
            int sectionOffset = d.readInt() + offset;
            int size          = d.readInt();    // size again

            for (int i = 0; i < size; i++)
            {
                //			System.out.print(d.readShort()); // id
                d.skip(4);                 // id and unknown
                d.readShort();             //left
                d.readShort();             //right
                int nameOffset = d.readInt() + offset;
                int dataOffset = d.readInt() + offset;
                if (dataOffset == offset)
                {
                    i--;
                    continue;
                    //				d.skip(8);
                    //				nameOffset = d.readInt() + 4;
                    //				dataOffset = d.readInt() + offset;
                }


                int temp = d.pos();

                d.seek(dataOffset);

                int pos     = d.pos();
                int nameOff = d.readInt() + sectionOffset + (d.pos() - sectionOffset) - 4;
                int flags   = d.readInt();

                int t_type = (flags >> 0x1e) & 0x3;
                int r_type = (flags >> 0x1b) & 0x7;
                int s_type = (flags >> 0x19) & 0x3;

                int hasT = (flags >> 0x18) & 0x1;
                int hasR = (flags >> 0x17) & 0x1;
                int hasS = (flags >> 0x16) & 0x1;

                int Zfixed = (flags >> 0x15) & 0x1;
                int Yfixed = (flags >> 0x14) & 0x1;
                int Xfixed = (flags >> 0x13) & 0x1;

                int RZfixed = (flags >> 0x12) & 0x1;
                int RYfixed = (flags >> 0x11) & 0x1;
                int RXfixed = (flags >> 0x10) & 0x1;

                int SZfixed = (flags >> 0xf) & 0x1;
                int SYfixed = (flags >> 0xe) & 0x1;
                int SXfixed = (flags >> 0xd) & 0x1;

                int Tiso = (flags >> 0x6) & 0x1;
                int Riso = (flags >> 0x5) & 0x1;
                int Siso = (flags >> 0x4) & 0x1;

                Animation.KeyNode node = new Animation.KeyNode(d.readString(nameOff, -1));
                anim.Bones.Add(node);
                node.RotType = Animation.RotationType.EULER;

                if (hasS == 1)
                {
                    if (Siso == 1)
                    {
                        float iss = d.readFloat();
                        node.XSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZSCA.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (SXfixed == 1)
                        {
                            node.XSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SX", false, anim);
                        }
                        if (SYfixed == 1)
                        {
                            node.YSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SY", false, anim);
                        }
                        if (SZfixed == 1)
                        {
                            node.ZSCA.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, s_type, pos, node, "SZ", false, anim);
                        }
                    }
                }

                if (hasR == 1)
                {
                    if (Riso == 1)
                    {
                        float iss = (float)((d.readFloat()) * Math.PI / 180f);
                        node.XROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZROT.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (RXfixed == 1)
                        {
                            node.XROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RX", false, anim);
                        }
                        if (RYfixed == 1)
                        {
                            node.YROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RY", false, anim);
                        }
                        if (RZfixed == 1)
                        {
                            node.ZROT.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = (float)(Math.PI / 180f) * (d.readFloat())
                            });
                        }
                        else
                        {
                            process(d, r_type, pos, node, "RZ", false, anim);
                        }
                    }
                }

                if (hasT == 1)
                {
                    if (Tiso == 1)
                    {
                        float iss = d.readFloat();
                        node.XPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.YPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                        node.ZPOS.Keys.Add(new Animation.KeyFrame()
                        {
                            Frame = 0, Value = iss
                        });
                    }
                    else
                    {
                        if (Xfixed == 1)
                        {
                            node.XPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "X", false, anim);
                        }
                        if (Yfixed == 1)
                        {
                            node.YPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "Y", false, anim);
                        }
                        if (Zfixed == 1)
                        {
                            node.ZPOS.Keys.Add(new Animation.KeyFrame()
                            {
                                Frame = 0, Value = d.readFloat()
                            });
                        }
                        else
                        {
                            process(d, t_type, pos, node, "Z", false, anim);
                        }
                    }
                }

                d.seek(temp);
            }

            return(anim);
        }
Пример #6
0
        public static void process(FileData d, int type, int secOff, Animation.KeyNode node, String part, bool debug, Animation a)
        {
            int offset = d.readInt() + secOff;
            int temp   = d.pos();

            d.seek(offset);

            int   max    = 0;
            int   fCount = -1;
            float scale  = 0;

            float[] frame = null, step = null, tan = null;

            if (type == 0x1)
            {
                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();
                float stepb = d.readFloat();
                float base2 = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readByte();
                    int th = d.readThree();
                    step[i] = base2 + ((th >> 12) & 0xfff) * stepb;
                    tan[i]  = (FileData.sign12Bit(th & 0xfff) / 32f);

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            if (type == 0x2)
            {
                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();
                float stepb = d.readFloat();
                float base2 = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readShort() / 32f;
                    step[i]  = base2 + d.readShort() * stepb;
                    tan[i]   = ((short)d.readShort() / 256f);

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            if (type == 0x3)
            {
                //if(debug)
                //System.out.println(part + "\tInterpolated 12 " + Integer.toHexString(offset));

                fCount = d.readShort();
                d.skip(2);
                scale = d.readFloat();

                frame = new float[fCount];
                step  = new float[fCount];
                tan   = new float[fCount];

                for (int i = 0; i < fCount; i++)
                {
                    frame[i] = d.readFloat();
                    step[i]  = d.readFloat();
                    tan[i]   = d.readFloat();

                    if (frame[i] > max)
                    {
                        max = (int)frame[i];
                    }
                }
            }

            //a.FrameCount = max;

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

            if (frame != null)
            {
                for (int i = 0; i < fCount; i++)
                {
                    Animation.KeyFrame f = new Animation.KeyFrame();
                    f.InterType = Animation.InterpolationType.HERMITE;
                    f.Value     = step[i];
                    f.Frame     = frame[i];
                    f.In        = tan[i];
                    switch (part)
                    {
                    case "RX":
                        f.Value = step[i] * degrad;
                        node.XROT.Keys.Add(f);
                        f.Degrees = true;
                        break;

                    case "RY":
                        f.Value = step[i] * degrad;
                        node.YROT.Keys.Add(f);
                        f.Degrees = true;
                        break;

                    case "RZ":
                        f.Value = step[i] * degrad;
                        node.ZROT.Keys.Add(f);
                        f.Degrees = true;
                        break;

                    case "X":
                        node.XPOS.Keys.Add(f);
                        break;

                    case "Y":
                        node.YPOS.Keys.Add(f);
                        break;

                    case "Z":
                        node.ZPOS.Keys.Add(f);
                        break;

                    case "SX":
                        node.XSCA.Keys.Add(f);
                        break;

                    case "SY":
                        node.YSCA.Keys.Add(f);
                        break;

                    case "SZ":
                        node.ZSCA.Keys.Add(f);
                        break;
                    }
                }
            }

            if (type == 0x4)
            {
                float stepb = d.readFloat();
                float base2 = d.readFloat();
                for (int i = 0; i < a.FrameCount; i++)
                {
                    float v = base2 + stepb * (d.readByte());

                    Animation.KeyFrame f = new Animation.KeyFrame();
                    f.InterType = Animation.InterpolationType.LINEAR;
                    f.Value     = v;
                    f.Frame     = i;

                    switch (part)
                    {
                    case "RX":
                        f.Value = v * degrad;
                        node.XROT.Keys.Add(f);
                        break;

                    case "RY":
                        f.Value = v * degrad;
                        node.YROT.Keys.Add(f);
                        break;

                    case "RZ":
                        f.Value = v * degrad;
                        node.ZROT.Keys.Add(f);
                        break;

                    case "X":
                        node.XPOS.Keys.Add(f);
                        break;

                    case "Y":
                        node.YPOS.Keys.Add(f);
                        break;

                    case "Z":
                        node.ZPOS.Keys.Add(f);
                        break;

                    case "SX":
                        node.XSCA.Keys.Add(f);
                        break;

                    case "SY":
                        node.YSCA.Keys.Add(f);
                        break;

                    case "SZ":
                        node.ZSCA.Keys.Add(f);
                        break;
                    }
                }
            }

            if (type == 0x6)
            {
                for (int i = 0; i < a.FrameCount; i++)
                {
                    float v = d.readFloat();

                    Animation.KeyFrame f = new Animation.KeyFrame();
                    f.InterType = Animation.InterpolationType.LINEAR;
                    f.Value     = v;
                    f.Frame     = i;
                    switch (part)
                    {
                    case "RX":
                        f.Value = v * degrad;
                        node.XROT.Keys.Add(f);
                        break;

                    case "RY":
                        f.Value = v * degrad;
                        node.YROT.Keys.Add(f);
                        break;

                    case "RZ":
                        f.Value = v * degrad;
                        node.ZROT.Keys.Add(f);
                        break;

                    case "X":
                        node.XPOS.Keys.Add(f);
                        break;

                    case "Y":
                        node.YPOS.Keys.Add(f);
                        break;

                    case "Z":
                        node.ZPOS.Keys.Add(f);
                        break;

                    case "SX":
                        node.XSCA.Keys.Add(f);
                        break;

                    case "SY":
                        node.YSCA.Keys.Add(f);
                        break;

                    case "SZ":
                        node.ZSCA.Keys.Add(f);
                        break;
                    }
                }
            }

            d.seek(temp);
        }
Пример #7
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.readShort();
            int frameCount = d.readShort();
            int frameSize  = d.readShort();

            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.t_type = 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.t_type = 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.t_type = 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.r_type = KeyNode.COMPRESSED;
                    }

                    if ((rFlag & 0xF0) == 0x50)
                    { // interpolated
                        node.r_type = 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.r_type  = KeyNode.KEYFRAME;
                        node.rv      = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                        node.r_extra = d.readFloat() / 65535;
                    }

                    if ((rFlag & 0xF0) == 0x70)
                    {
                        node.r_type = KeyNode.CONSTANT;
                        node.rv     = new Vector3(d.readFloat(), d.readFloat(), d.readFloat());
                    }
                }

                if (hasScale)
                {
                    if ((sFlag & 0xF0) == 0x80)
                    { // interpolated
                        node.s_type = 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.s_type = 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].t_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / 0xffff);
                        float i2 = ((float)d.readShort() / 0xffff);
                        float i3 = ((float)d.readShort() / 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].t_type == 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].t_type == 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].r_type == 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].r_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (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].r_type == KeyNode.KEYFRAME)
                    {
                        float scale = d.readShort() * baseNode[j].r_extra;
                        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].s_type == KeyNode.INTERPOLATED)
                    {
                        float i1 = ((float)d.readShort() / (0xffff));
                        float i2 = ((float)d.readShort() / (0xffff));
                        float i3 = ((float)d.readShort() / (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);
        }
Пример #8
0
        public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn)
        {
            if (vbn == null || a == null)
            {
                return new byte[] { }
            }
            ;

            // Test Actual Bones
            //-------------------------

            List <Animation.KeyNode> toRem = new List <Animation.KeyNode>();

            for (int j = 0; j < a.Bones.Count; j++)
            {
                Animation.KeyNode keynode = ((Animation.KeyNode)a.Bones[j]);
                Bone b = vbn.getBone(keynode.Text);

                if (b == null)
                {
                    toRem.Add(keynode);
                }
            }
            foreach (Animation.KeyNode r in toRem)
            {
                Console.WriteLine("Removing " + r.Text);
                a.Bones.Remove(r);
            }

            //-------------------------

            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);
                    for (int i = 0; i < a.FrameCount; i++)
                    {
                        Quaternion r = new Quaternion();
                        if (keynode.RotType == Animation.RotationType.QUATERNION)
                        {
                            Animation.KeyFrame[] x  = keynode.XROT.GetFrame(i);
                            Animation.KeyFrame[] y  = keynode.YROT.GetFrame(i);
                            Animation.KeyFrame[] z  = keynode.ZROT.GetFrame(i);
                            Animation.KeyFrame[] w  = keynode.WROT.GetFrame(i);
                            Quaternion           q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value);
                            Quaternion           q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value);
                            if (x[0].Frame == i)
                            {
                                r = q1;
                            }
                            else
                            if (x[1].Frame == i)
                            {
                                r = q2;
                            }
                            else
                            {
                                r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame));
                            }
                        }
                        else
                        if (keynode.RotType == Animation.RotationType.EULER)
                        {
                            float x = keynode.XROT.HasAnimation() ? keynode.XROT.GetValue(i) : b.rotation[0];
                            float y = keynode.YROT.HasAnimation() ? keynode.YROT.GetValue(i) : b.rotation[1];
                            float z = keynode.ZROT.HasAnimation() ? keynode.ZROT.GetValue(i) : b.rotation[2];
                            r = Animation.EulerToQuat(z, y, x);
                        }
                        r.Normalize();

                        maxR[j].X = Math.Max(maxR[j].X, r.X);
                        minR[j].X = Math.Min(minR[j].X, r.X);
                        maxR[j].Y = Math.Max(maxR[j].Y, r.Y);
                        minR[j].Y = Math.Min(minR[j].Y, r.Y);
                        maxR[j].Z = Math.Max(maxR[j].Z, r.Z);
                        minR[j].Z = Math.Min(minR[j].Z, r.Z);
                    }

                    //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);

                    Animation.KeyNode anode = a.Bones[j];
                    //if (node == null) continue;

                    if (hasTrans[j] && !conTrans[j])
                    {
                        t2.writeShort((int)(((anode.XPOS.GetValue(i) - minT[j].X) / maxT[j].X) * 0xFFFF));
                        t2.writeShort((int)(((anode.YPOS.GetValue(i) - minT[j].Y) / maxT[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((anode.ZPOS.GetValue(i) - minT[j].Z) / maxT[j].Z) * 0xFFFF));
                    }

                    if (hasRot[j] && !conRot[j])
                    {
                        Quaternion r = new Quaternion();
                        if (anode.RotType == Animation.RotationType.QUATERNION)
                        {
                            Animation.KeyFrame[] x  = anode.XROT.GetFrame(i);
                            Animation.KeyFrame[] y  = anode.YROT.GetFrame(i);
                            Animation.KeyFrame[] z  = anode.ZROT.GetFrame(i);
                            Animation.KeyFrame[] w  = anode.WROT.GetFrame(i);
                            Quaternion           q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value);
                            Quaternion           q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value);
                            if (x[0].Frame == i)
                            {
                                r = q1;
                            }
                            else
                            if (x[1].Frame == i)
                            {
                                r = q2;
                            }
                            else
                            {
                                r = Quaternion.Slerp(q1, q2, (i - x[0].Frame) / (x[1].Frame - x[0].Frame));
                            }
                        }
                        else
                        if (anode.RotType == Animation.RotationType.EULER)
                        {
                            float x = anode.XROT.HasAnimation() ? anode.XROT.GetValue(i) : node.rotation[0];
                            float y = anode.YROT.HasAnimation() ? anode.YROT.GetValue(i) : node.rotation[1];
                            float z = anode.ZROT.HasAnimation() ? anode.ZROT.GetValue(i) : node.rotation[2];
                            r = Animation.EulerToQuat(z, y, x);
                        }
                        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)(((anode.XSCA.GetValue(i) - minS[j].X) / maxS[j].X) * 0xFFFF));
                        t2.writeShort((int)(((anode.YSCA.GetValue(i) - minS[j].Y) / maxS[j].Y) * 0xFFFF));
                        t2.writeShort((int)(((anode.ZSCA.GetValue(i) - minS[j].Z) / maxS[j].Z) * 0xFFFF));
                    }
                }

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

            o.writeOutput(t2);
            return(o.getBytes());
        }
    }
Пример #9
0
        public static byte[] CreateOMOFromAnimation(Animation a, VBN vbn)
        {
            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);

            //for (int i = 0; i < a.FrameCount; i++)
            {
                //a.NextFrame(vbn);

                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);
                    }
                    //TODO: Euler Rotation Values
                    a.SetFrame(0);
                    Bone b = vbn.getBone(keynode.Text);
                    if (b == null)
                    {
                        continue;
                    }
                    for (int i = 0; i < a.FrameCount; i++)
                    {
                        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);
                        a.NextFrame(vbn);
                    }

                    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];
                        }
                    }
                }
            }

            // 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 (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);

            for (int i = 0; i < a.FrameCount; i++)
            {
                //Console.WriteLine("Workin on" + 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;

                        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 (i == 0)
                {
                    o.writeShortAt(t2.size(), 0x12);
                }
            }

            //Console.WriteLine("Saving");
            o.writeOutput(t2);
            return(o.getBytes());
        }
Пример #10
0
            public void Read(ResFile TargetWiiUBFRES, AnimationGroupNode ThisAnimation, ResNSW.ResFile b)
            {
                Console.WriteLine("Reading Skeleton Animations ...");

                if (b != null)
                {
                    TreeNode SkeletonAnimation = new TreeNode()
                    {
                        Text = "Skeleton Animations"
                    };

                    ThisAnimation.Nodes.Add(SkeletonAnimation);

                    TreeNode dummy = new TreeNode()
                    {
                        Text = "Animation Set"
                    };

                    int i = 0;
                    foreach (ResNSW.SkeletalAnim ska in b.SkeletalAnims)
                    {
                        if (i == 0)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "0 - 100"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 100)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "100 - 200"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 200)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "200 - 300"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 300)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "300 - 400"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 400)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "400 - 500"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 500)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "500 - 600"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 600)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "600 - 700"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 700)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "700 - 800"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 800)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "800 - 900"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 900)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "900 - 1000"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 1000)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "1000+"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }

                        Animation a = new Animation(ska.Name);
                        SkeletonAnimations.Add(a);

                        a.FrameCount = ska.FrameCount;

                        if (i >= 0 && i < 100)
                        {
                            SkeletonAnimation.Nodes[0].Nodes.Add(a);
                        }
                        if (i >= 100 && i < 200)
                        {
                            SkeletonAnimation.Nodes[1].Nodes.Add(a);
                        }
                        if (i >= 200 && i < 300)
                        {
                            SkeletonAnimation.Nodes[2].Nodes.Add(a);
                        }
                        if (i >= 300 && i < 400)
                        {
                            SkeletonAnimation.Nodes[3].Nodes.Add(a);
                        }
                        if (i >= 400 && i < 500)
                        {
                            SkeletonAnimation.Nodes[4].Nodes.Add(a);
                        }
                        if (i >= 500 && i < 600)
                        {
                            SkeletonAnimation.Nodes[5].Nodes.Add(a);
                        }
                        if (i >= 600 && i < 700)
                        {
                            SkeletonAnimation.Nodes[6].Nodes.Add(a);
                        }
                        if (i >= 700 && i < 800)
                        {
                            SkeletonAnimation.Nodes[7].Nodes.Add(a);
                        }
                        if (i >= 800 && i < 900)
                        {
                            SkeletonAnimation.Nodes[8].Nodes.Add(a);
                        }
                        if (i >= 900 && i < 1000)
                        {
                            SkeletonAnimation.Nodes[9].Nodes.Add(a);
                        }

                        i++;
                        try
                        {
                            foreach (ResNSW.BoneAnim bn in ska.BoneAnims)
                            {
                                FSKANode bonean = new FSKANode(bn);

                                Animation.KeyNode bone = new Animation.KeyNode("");
                                a.Bones.Add(bone);
                                if (ska.FlagsRotate == ResNSW.SkeletalAnimFlagsRotate.EulerXYZ)
                                {
                                    bone.RotType = Animation.RotationType.EULER;
                                }
                                else
                                {
                                    bone.RotType = Animation.RotationType.QUATERNION;
                                }

                                bone.Text = bonean.Text;

                                for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                                {
                                    //Set base/start values for bones.
                                    //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                    if (Frame == 0)
                                    {
                                        if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Scale))
                                        {
                                            bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.X
                                            });
                                            bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.Y
                                            });
                                            bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.Z
                                            });
                                        }
                                        if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Rotate))
                                        {
                                            bone.XROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.X
                                            });
                                            bone.YROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.Y
                                            });
                                            bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.Z
                                            });
                                            bone.WROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.W
                                            });
                                        }
                                        if (bn.FlagsBase.HasFlag(ResNSW.BoneAnimFlagsBase.Translate))
                                        {
                                            bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.X
                                            });
                                            bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.Y
                                            });
                                            bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.Z
                                            });
                                        }
                                    }
                                    foreach (FSKATrack track in bonean.tracks)
                                    {
                                        Animation.KeyFrame frame = new Animation.KeyFrame();
                                        frame.InterType = Animation.InterpolationType.HERMITE;
                                        frame.Frame     = Frame;

                                        FSKAKey left  = track.GetLeft(Frame);
                                        FSKAKey right = track.GetRight(Frame);
                                        float   value;



                                        value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                        // interpolate the value and apply
                                        switch (track.flag)
                                        {
                                        case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                        case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                        case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                        case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                        case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                        case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                        case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                        case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                        case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                        }
                                    }
                                }
                            }
                        }
                        catch
                        {
                        }
                    }
                }
                else
                {
                    TreeNode SkeletonAnimation = new TreeNode()
                    {
                        Text = "Skeleton Animations"
                    };

                    ThisAnimation.Nodes.Add(SkeletonAnimation);

                    TreeNode dummy = new TreeNode()
                    {
                        Text = "Animation Set"
                    };

                    int i = 0;
                    foreach (SkeletalAnim ska in TargetWiiUBFRES.SkeletalAnims.Values)
                    {
                        if (i == 0)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "0 - 100"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 100)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "100 - 200"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 200)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "200 - 300"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 300)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "300 - 400"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 400)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "400 - 500"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 500)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "500 - 600"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 600)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "600 - 700"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 700)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "700 - 800"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 800)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "800 - 900"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 900)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "900 - 1000"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }
                        if (i == 1000)
                        {
                            dummy = new TreeNode()
                            {
                                Text = "Animation Set " + "1000+"
                            };
                            SkeletonAnimation.Nodes.Add(dummy);
                        }

                        Animation a = new Animation(ska.Name);
                        SkeletonAnimations.Add(a);

                        if (i >= 0 && i < 100)
                        {
                            SkeletonAnimation.Nodes[0].Nodes.Add(a);
                        }
                        if (i >= 100 && i < 200)
                        {
                            SkeletonAnimation.Nodes[1].Nodes.Add(a);
                        }
                        if (i >= 200 && i < 300)
                        {
                            SkeletonAnimation.Nodes[2].Nodes.Add(a);
                        }
                        if (i >= 300 && i < 400)
                        {
                            SkeletonAnimation.Nodes[3].Nodes.Add(a);
                        }
                        if (i >= 400 && i < 500)
                        {
                            SkeletonAnimation.Nodes[4].Nodes.Add(a);
                        }
                        if (i >= 500 && i < 600)
                        {
                            SkeletonAnimation.Nodes[5].Nodes.Add(a);
                        }
                        if (i >= 600 && i < 700)
                        {
                            SkeletonAnimation.Nodes[6].Nodes.Add(a);
                        }
                        if (i >= 700 && i < 800)
                        {
                            SkeletonAnimation.Nodes[7].Nodes.Add(a);
                        }
                        if (i >= 800 && i < 900)
                        {
                            SkeletonAnimation.Nodes[8].Nodes.Add(a);
                        }
                        if (i >= 900 && i < 1000)
                        {
                            SkeletonAnimation.Nodes[9].Nodes.Add(a);
                        }


                        a.FrameCount = ska.FrameCount;
                        i++;
                        try
                        {
                            foreach (BoneAnim bn in ska.BoneAnims)
                            {
                                FSKANodeWiiU bonean = new FSKANodeWiiU(bn);

                                Animation.KeyNode bone = new Animation.KeyNode("");
                                a.Bones.Add(bone);
                                if (ska.FlagsRotate == SkeletalAnimFlagsRotate.EulerXYZ)
                                {
                                    bone.RotType = Animation.RotationType.EULER;
                                }
                                else
                                {
                                    bone.RotType = Animation.RotationType.QUATERNION;
                                }

                                bone.Text = bonean.Text;


                                for (int Frame = 0; Frame < ska.FrameCount; Frame++)
                                {
                                    //Set base/start values for bones.
                                    //Note. BOTW doesn't use base values as it uses havok engine. Need to add option to disable these
                                    if (Frame == 0)
                                    {
                                        if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Scale))
                                        {
                                            bone.XSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.X
                                            });
                                            bone.YSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.Y
                                            });
                                            bone.ZSCA.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.sca.Z
                                            });
                                        }
                                        if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Rotate))
                                        {
                                            bone.XROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.X
                                            });
                                            bone.YROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.Y
                                            });
                                            bone.ZROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.Z
                                            });
                                            bone.WROT.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.rot.W
                                            });
                                        }
                                        if (bn.FlagsBase.HasFlag(BoneAnimFlagsBase.Translate))
                                        {
                                            bone.XPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.X
                                            });
                                            bone.YPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.Y
                                            });
                                            bone.ZPOS.Keys.Add(new Animation.KeyFrame()
                                            {
                                                Frame = 0, Value = bonean.pos.Z
                                            });
                                        }
                                    }
                                    foreach (FSKATrack track in bonean.tracks)
                                    {
                                        Animation.KeyFrame frame = new Animation.KeyFrame();
                                        frame.InterType = Animation.InterpolationType.HERMITE;
                                        frame.Frame     = Frame;

                                        FSKAKey left  = track.GetLeft(Frame);
                                        FSKAKey right = track.GetRight(Frame);
                                        float   value;



                                        value = Animation.Hermite(Frame, left.frame, right.frame, 0, 0, left.unk1, right.unk1);

                                        // interpolate the value and apply
                                        switch (track.flag)
                                        {
                                        case (int)TrackType.XPOS: frame.Value = value; bone.XPOS.Keys.Add(frame); break;

                                        case (int)TrackType.YPOS: frame.Value = value; bone.YPOS.Keys.Add(frame); break;

                                        case (int)TrackType.ZPOS: frame.Value = value; bone.ZPOS.Keys.Add(frame); break;

                                        case (int)TrackType.XROT: frame.Value = value; bone.XROT.Keys.Add(frame); break;

                                        case (int)TrackType.YROT: frame.Value = value; bone.YROT.Keys.Add(frame); break;

                                        case (int)TrackType.ZROT: frame.Value = value; bone.ZROT.Keys.Add(frame); break;

                                        case (int)TrackType.XSCA: frame.Value = value; bone.XSCA.Keys.Add(frame); break;

                                        case (int)TrackType.YSCA: frame.Value = value; bone.YSCA.Keys.Add(frame); break;

                                        case (int)TrackType.ZSCA: frame.Value = value; bone.ZSCA.Keys.Add(frame); break;
                                        }
                                    }
                                }
                            }
                        }
                        catch
                        {
                        }
                    }
                }


                Console.WriteLine("Saving " + SkeletonAnimations.Count + " anims");

                foreach (var anim in SkeletonAnimations)
                {
                    anim.SaveAsExpeditedAnim();
                }
            }
Пример #11
0
        public static AnimationGroupNode Read(string filename)
        {
            bchHeader header = new bchHeader();
            FileData  f      = new FileData(filename);

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

            f.skip(4);
            header.backwardCompatibility = f.readByte();
            header.forwardCompatibility  = f.readByte();
            header.version = f.readUShort();

            header.mainHeaderOffset  = f.readInt();
            header.stringTableOffset = f.readInt();
            header.gpuCommandsOffset = f.readInt();
            header.dataOffset        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedOffset = f.readInt();
            }
            header.relocationTableOffset = f.readInt();

            header.mainHeaderLength  = f.readInt();
            header.stringTableLength = f.readInt();
            header.gpuCommandsLength = f.readInt();
            header.dataLength        = f.readInt();
            if (header.backwardCompatibility > 0x20)
            {
                header.dataExtendedLength = f.readInt();
            }
            header.relocationTableLength = f.readInt();

            header.uninitializedDataSectionLength        = f.readInt();
            header.uninitializedDescriptionSectionLength = f.readInt();

            if (header.backwardCompatibility > 7)
            {
                header.flags        = f.readUShort();
                header.addressCount = f.readUShort();
            }

            // Relocation table
            for (int i = 0; i < header.relocationTableLength; i += 4)
            {
                f.seek(header.relocationTableOffset + i);
                int  val  = f.readInt();
                int  off  = val & 0x1FFFFFF;
                byte flag = (byte)(val >> 25);

                switch (flag)
                {
                case 0:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.mainHeaderOffset);
                    break;

                case 1:
                    f.seek(off + header.mainHeaderOffset);
                    f.writeInt((off) + header.mainHeaderOffset, f.readInt() + header.stringTableOffset);
                    break;

                case 2:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.gpuCommandsOffset);
                    break;

                case 0xc:
                    f.seek((off * 4) + header.mainHeaderOffset);
                    f.writeInt((off * 4) + header.mainHeaderOffset, f.readInt() + header.dataOffset);
                    break;
                }
            }


            // Content Header
            f.seek(header.mainHeaderOffset);
            bchContentHeader content = new bchContentHeader();
            {
                content.modelsPointerTableOffset        = f.readInt();
                content.modelsPointerTableEntries       = f.readInt();
                content.modelsNameOffset                = f.readInt();
                content.materialsPointerTableOffset     = f.readInt();
                content.materialsPointerTableEntries    = f.readInt();
                content.materialsNameOffset             = f.readInt();
                content.shadersPointerTableOffset       = f.readInt();
                content.shadersPointerTableEntries      = f.readInt();
                content.shadersNameOffset               = f.readInt();
                content.texturesPointerTableOffset      = f.readInt();
                content.texturesPointerTableEntries     = f.readInt();
                content.texturesNameOffset              = f.readInt();
                content.materialsLUTPointerTableOffset  = f.readInt();
                content.materialsLUTPointerTableEntries = f.readInt();
                content.materialsLUTNameOffset          = f.readInt();
                content.lightsPointerTableOffset        = f.readInt();
                content.lightsPointerTableEntries       = f.readInt();
                content.lightsNameOffset                = f.readInt();
                content.camerasPointerTableOffset       = f.readInt();
                content.camerasPointerTableEntries      = f.readInt();
                content.camerasNameOffset               = f.readInt();
                content.fogsPointerTableOffset          = f.readInt();
                content.fogsPointerTableEntries         = f.readInt();
                content.fogsNameOffset = f.readInt();
                content.skeletalAnimationsPointerTableOffset    = f.readInt();
                content.skeletalAnimationsPointerTableEntries   = f.readInt();
                content.skeletalAnimationsNameOffset            = f.readInt();
                content.materialAnimationsPointerTableOffset    = f.readInt();
                content.materialAnimationsPointerTableEntries   = f.readInt();
                content.materialAnimationsNameOffset            = f.readInt();
                content.visibilityAnimationsPointerTableOffset  = f.readInt();
                content.visibilityAnimationsPointerTableEntries = f.readInt();
                content.visibilityAnimationsNameOffset          = f.readInt();
                content.lightAnimationsPointerTableOffset       = f.readInt();
                content.lightAnimationsPointerTableEntries      = f.readInt();
                content.lightAnimationsNameOffset           = f.readInt();
                content.cameraAnimationsPointerTableOffset  = f.readInt();
                content.cameraAnimationsPointerTableEntries = f.readInt();
                content.cameraAnimationsNameOffset          = f.readInt();
                content.fogAnimationsPointerTableOffset     = f.readInt();
                content.fogAnimationsPointerTableEntries    = f.readInt();
                content.fogAnimationsNameOffset             = f.readInt();
                content.scenePointerTableOffset             = f.readInt();
                content.scenePointerTableEntries            = f.readInt();
                content.sceneNameOffset = f.readInt();
            }


            //Skeletal animation
            AnimationGroupNode ThisAnimation = new AnimationGroupNode()
            {
                Text = filename
            };

            for (int index1 = 0; index1 < content.skeletalAnimationsPointerTableEntries; index1++)//
            {
                f.seek(content.skeletalAnimationsPointerTableOffset + (index1 * 4));
                int dataOffset = f.readInt();
                f.seek(dataOffset);


                string skeletalAnimationName = f.readString(f.readInt(), -1);
                int    animationFlags        = f.readInt();
                //int skeletalAnimationloopMode = f.readByte();  //pas ça du tout
                float skeletalAnimationframeSize = f.readFloat();
                int   boneTableOffset            = f.readInt();
                int   boneTableEntries           = f.readInt();
                int   metaDataPointerOffset      = f.readInt();

                //Runtime.Animations.Add(skeletalAnimationName, a);
                //MainForm.animNode.Nodes.Add(skeletalAnimationName);

                Animation a = new Animation(skeletalAnimationName);
                ThisAnimation.Nodes.Add(a);

                for (int i = 0; i < boneTableEntries; i++)
                {
                    f.seek(boneTableOffset + (i * 4));
                    int offset = f.readInt();

                    Animation.KeyNode bone = new Animation.KeyNode("");
                    a.Bones.Add(bone);
                    f.seek(offset);
                    bone.Text = f.readString(f.readInt(), -1);
                    //Console.WriteLine("Bone Name: " + bone.name);
                    int  animationTypeFlags = f.readInt();
                    uint flags = (uint)f.readInt();

                    OSegmentType segmentType = (OSegmentType)((animationTypeFlags >> 16) & 0xf);
                    //Debug.WriteLine(bone.Text + " " + flags.ToString("x"));
                    switch (segmentType)
                    {
                    case OSegmentType.transform:
                        f.seek(offset + 0xC);
                        //Console.WriteLine(f.pos().ToString("x") + " " + flags.ToString("x"));

                        uint notExistMask = 0x10000;
                        uint constantMask = 0x40;

                        for (int j = 0; j < 3; j++)
                        {
                            for (int axis = 0; axis < 3; axis++)
                            {
                                bool notExist = (flags & notExistMask) > 0;
                                bool constant = (flags & constantMask) > 0;
                                //Console.WriteLine(notExist + " " + constant);

                                Animation.KeyGroup group = new Animation.KeyGroup();
                                //frame.exists = !notExist;
                                if (!notExist)
                                {
                                    if (constant)
                                    {
                                        Animation.KeyFrame frame = new Animation.KeyFrame();
                                        frame.InterType = Animation.InterpolationType.LINEAR;
                                        frame.Value     = f.readFloat();
                                        frame.Frame     = 0;
                                        group.Keys.Add(frame);
                                    }
                                    else
                                    {
                                        int frameOffset = f.readInt();
                                        int position    = f.pos();
                                        f.seek(frameOffset);
                                        float c = 0;
                                        //Debug.WriteLine(j + " " + axis + " " + bone.Text);
                                        getAnimationKeyFrame(f, group, out c);
                                        if (c > a.FrameCount)
                                        {
                                            a.FrameCount = (int)c;
                                        }
                                        f.seek(position);
                                    }
                                }
                                else
                                {
                                    f.seek(f.pos() + 0x04);
                                }
                                bone.RotType = Animation.RotationType.EULER;

                                if (j == 0)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XSCA = group; break;

                                    case 1: bone.YSCA = group; break;

                                    case 2: bone.ZSCA = group; break;
                                    }
                                }
                                else
                                if (j == 1)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XROT = group; break;

                                    case 1: bone.YROT = group; break;

                                    case 2: bone.ZROT = group; break;
                                    }
                                }
                                else
                                if (j == 2)
                                {
                                    switch (axis)
                                    {
                                    case 0: bone.XPOS = group; break;

                                    case 1: bone.YPOS = group; break;

                                    case 2: bone.ZPOS = group; break;
                                    }
                                }

                                notExistMask <<= 1;
                                constantMask <<= 1;
                            }
                            if (j == 1)
                            {
                                constantMask <<= 1;
                            }
                        }

                        break;

                    /*case OSegmentType.transformQuaternion:
                     *  bone.isFrameFormat = true;
                     *
                     *  int scaleOffset = f.readInt();
                     *  int rotationOffset = f.readInt();
                     *  int translationOffset = f.readInt();
                     *
                     *  if ((flags & 0x20) == 0)
                     *  {
                     *      bone.scale.exists = true;
                     *      f.seek(scaleOffset);
                     *
                     *      if ((flags & 4) > 0)
                     *      {
                     *          bone.scale.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              0));
                     *      }
                     *      else
                     *      {
                     *          bone.scale.startFrame = f.readFloat();
                     *          bone.scale.endFrame = f.readFloat();
                     *
                     *          int scaleFlags = f.readInt();
                     *          int scaleDataOffset = f.readInt();
                     *          int scaleEntries = f.readInt();
                     *
                     *          f.seek(scaleDataOffset);
                     *          for (int j = 0; j < scaleEntries; j++)
                     *          {
                     *              bone.scale.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  0));
                     *          }
                     *      }
                     *  }
                     *
                     *  if ((flags & 0x10) == 0)
                     *  {
                     *      bone.rotationQuaternion.exists = true;
                     *      f.seek(rotationOffset);
                     *
                     *      if ((flags & 2) > 0)
                     *      {
                     *          bone.rotationQuaternion.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat()));
                     *      }
                     *      else
                     *      {
                     *          bone.rotationQuaternion.startFrame = f.readFloat();
                     *          bone.rotationQuaternion.endFrame = f.readFloat();
                     *
                     *          int rotationFlags = f.readInt();
                     *          int rotationDataOffset = f.readInt();
                     *          int rotationEntries = f.readInt();
                     *
                     *          f.seek(rotationDataOffset);
                     *          for (int j = 0; j < rotationEntries; j++)
                     *          {
                     *              bone.rotationQuaternion.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat()));
                     *          }
                     *      }
                     *  }
                     *
                     *  if ((flags & 8) == 0)
                     *  {
                     *      bone.translation.exists = true;
                     *      f.seek(translationOffset);
                     *
                     *      if ((flags & 1) > 0)
                     *      {
                     *          bone.translation.vector.Add(new Vector4(
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              f.readFloat(),
                     *              0));
                     *      }
                     *      else
                     *      {
                     *          bone.translation.startFrame = f.readFloat();
                     *          bone.translation.endFrame = f.readFloat();
                     *
                     *          int translationFlags = f.readInt();
                     *          int translationDataOffset = f.readInt();
                     *          int translationEntries = f.readInt();
                     *
                     *          f.seek(translationDataOffset);
                     *          for (int j = 0; j < translationEntries; j++)
                     *          {
                     *              bone.translation.vector.Add(new Vector4(
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  f.readFloat(),
                     *                  0));
                     *          }
                     *      }
                     *  }
                     *
                     *  break;
                     * case OSegmentType.transformMatrix:
                     *  bone.isFullBakedFormat = true;
                     *
                     *  f.readInt();
                     *  f.readInt();
                     *  int matrixOffset = f.readInt();
                     *  int entries = f.readInt();
                     *
                     *  f.seek(matrixOffset);
                     *  for (int j = 0; j < entries; j++)
                     *  {
                     *      OMatrix transform = new OMatrix();
                     *      transform.M11 = f.readFloat();
                     *      transform.M21 = f.readFloat();
                     *      transform.M31 = f.readFloat();
                     *      transform.M41 = f.readFloat();
                     *
                     *      transform.M12 = f.readFloat();
                     *      transform.M22 = f.readFloat();
                     *      transform.M32 = f.readFloat();
                     *      transform.M42 = f.readFloat();
                     *
                     *      transform.M13 = f.readFloat();
                     *      transform.M23 = f.readFloat();
                     *      transform.M33 = f.readFloat();
                     *      transform.M43 = f.readFloat();
                     *
                     *      bone.transform.Add(transform);
                     *  }
                     *
                     *  break;*/
                    default: throw new Exception(string.Format("BCH: Unknow Segment Type {0} on Skeletal Animation bone {1}! STOP!", segmentType, bone.Text));
                    }

                    //skeletalAnimation.bone.Add(bone);
                }
            }
            //return a;
            return(ThisAnimation);
        }
Пример #12
0
        public static Animation read(string filename, VBN vbn)
        {
            Animation a = new Animation(filename);

            Animation.KeyNode  current = null;
            Animation.KeyFrame att     = new Animation.KeyFrame();

            StreamReader reader = File.OpenText(filename);
            string       line;

            AnimHeader header   = new AnimHeader();
            bool       inHeader = true;
            bool       inKeys   = false;
            string     type     = "";

            while ((line = reader.ReadLine()) != null)
            {
                string[] args = line.Replace(";", "").TrimStart().Split(' ');

                if (inHeader)
                {
                    if (args[0].Equals("anim"))
                    {
                        inHeader = false;
                    }
                    else if (args[0].Equals("animVersion"))
                    {
                        header.animVersion = args[1];
                    }
                    else if (args[0].Equals("mayaVersion"))
                    {
                        header.mayaVersion = args[1];
                    }
                    else if (args[0].Equals("startTime"))
                    {
                        header.startTime = float.Parse(args[1]);
                    }
                    else if (args[0].Equals("endTime"))
                    {
                        header.endTime = float.Parse(args[1]);
                    }
                    else if (args[0].Equals("startUnitless"))
                    {
                        header.startUnitless = float.Parse(args[1]);
                    }
                    else if (args[0].Equals("endUnitless"))
                    {
                        header.endUnitless = float.Parse(args[1]);
                    }
                    else if (args[0].Equals("timeUnit"))
                    {
                        header.timeUnit = args[1];
                    }
                    else if (args[0].Equals("linearUnit"))
                    {
                        header.linearUnit = args[1];
                    }
                    else if (args[0].Equals("angularUnit"))
                    {
                        header.angularUnit = args[1];
                    }
                }
                if (!inHeader)
                {
                    if (inKeys)
                    {
                        if (args[0].Equals("}"))
                        {
                            inKeys = false;
                            continue;
                        }
                        Animation.KeyFrame k = new Animation.KeyFrame();
                        //att.keys.Add (k);
                        if (type.Contains("translate"))
                        {
                            if (type.Contains("X"))
                            {
                                current.XPOS.Keys.Add(k);
                            }
                            if (type.Contains("Y"))
                            {
                                current.YPOS.Keys.Add(k);
                            }
                            if (type.Contains("Z"))
                            {
                                current.ZPOS.Keys.Add(k);
                            }
                        }
                        if (type.Contains("rotate"))
                        {
                            if (type.Contains("X"))
                            {
                                current.XROT.Keys.Add(k);
                            }
                            if (type.Contains("Y"))
                            {
                                current.YROT.Keys.Add(k);
                            }
                            if (type.Contains("Z"))
                            {
                                current.ZROT.Keys.Add(k);
                            }
                        }
                        if (type.Contains("scale"))
                        {
                            if (type.Contains("X"))
                            {
                                current.XSCA.Keys.Add(k);
                            }
                            if (type.Contains("Y"))
                            {
                                current.YSCA.Keys.Add(k);
                            }
                            if (type.Contains("Z"))
                            {
                                current.ZSCA.Keys.Add(k);
                            }
                        }
                        k.Frame = float.Parse(args [0]) - 1;
                        k.Value = float.Parse(args [1]);
                        if (type.Contains("rotate"))
                        {
                            k.Value *= (float)(Math.PI / 180f);
                        }
                        //k.intan = (args [2]);
                        //k.outtan = (args [3]);
                        if (args.Length > 7 && att.Weighted)
                        {
                            k.In  = float.Parse(args[7]) * (float)(Math.PI / 180f);
                            k.Out = float.Parse(args[8]) * (float)(Math.PI / 180f);
                        }
                    }

                    if (args [0].Equals("anim"))
                    {
                        inKeys = false;
                        if (args.Length == 5)
                        {
                            //TODO: finish this type
                            // can be name of attribute
                        }
                        if (args.Length == 7)
                        {
                            // see of the bone of this attribute exists
                            current = null;
                            foreach (Animation.KeyNode b in a.Bones)
                            {
                                if (b.Text.Equals(args [3]))
                                {
                                    current = b;
                                    break;
                                }
                            }
                            if (current == null)
                            {
                                current         = new Animation.KeyNode(args[3]);
                                current.RotType = Animation.RotationType.EULER;
                                a.Bones.Add(current);
                            }
                            current.Text = args [3];

                            att           = new Animation.KeyFrame();
                            att.InterType = Animation.InterpolationType.HERMITE;
                            type          = args [2];
                            //current.Nodes.Add (att);

                            // row child attribute aren't needed here
                        }
                    }

                    /*if (args [0].Equals ("input"))
                     *  att.input = args [1];
                     * if (args [0].Equals ("output"))
                     *  att.output = args [1];
                     * if (args [0].Equals ("preInfinity"))
                     *  att.preInfinity = args [1];
                     * if (args [0].Equals ("postInfinity"))
                     *  att.postInfinity = args [1];*/
                    if (args[0].Equals("weighted"))
                    {
                        att.Weighted = args[1].Equals("1");
                    }


                    // begining keys section
                    if (args [0].Contains("keys"))
                    {
                        inKeys = true;
                    }
                }
            }

            int startTime = (int)Math.Ceiling(header.startTime);
            int endTime   = (int)Math.Ceiling(header.endTime);

            a.FrameCount = (endTime + 1) - startTime;

            reader.Close();
            return(a);
        }
Пример #13
0
        private static void writeKey(StreamWriter file, Animation.KeyGroup keys, Animation.KeyNode rt, int size, string type)
        {
            file.WriteLine("animData {\n input time;\n output linear;\n weighted 1;\n preInfinity constant;\n postInfinity constant;\n keys {");

            if (((Animation.KeyFrame)keys.Keys[0]).InterType == Animation.InterpolationType.CONSTANT)
            {
                size = 1;
            }

            foreach (Animation.KeyFrame key in keys.Keys)
            {
                float v = 0;

                float scale = 1;
                switch (type)
                {
                case "translateX":
                    v = key.Value;
                    break;

                case "translateY":
                    v = key.Value;
                    break;

                case "translateZ":
                    v = key.Value;
                    break;

                case "rotateX":
                    if (rt.RotType == Animation.RotationType.EULER)
                    {
                        v = key.Value * (float)(180f / Math.PI);
                    }
                    if (rt.RotType == Animation.RotationType.QUATERNION)
                    {
                        Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame));
                        v = quattoeul(q).X *(float)(180f / Math.PI);
                    }
                    scale = (float)(180f / Math.PI);
                    break;

                case "rotateY":
                    if (rt.RotType == Animation.RotationType.EULER)
                    {
                        v = key.Value * (float)(180f / Math.PI);
                    }
                    if (rt.RotType == Animation.RotationType.QUATERNION)
                    {
                        Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame));
                        v = quattoeul(q).Y *(float)(180f / Math.PI);
                    }
                    scale = (float)(180f / Math.PI);
                    break;

                case "rotateZ":
                    if (rt.RotType == Animation.RotationType.EULER)
                    {
                        v = key.Value * (float)(180f / Math.PI);
                    }
                    if (rt.RotType == Animation.RotationType.QUATERNION)
                    {
                        Quaternion q = new Quaternion(rt.XROT.GetValue(key.Frame), rt.YROT.GetValue(key.Frame), rt.ZROT.GetValue(key.Frame), rt.WROT.GetValue(key.Frame));
                        v = quattoeul(q).Z *(float)(180f / Math.PI);
                    }
                    scale = (float)(180f / Math.PI);
                    break;

                case "scaleX":
                    v = key.Value;
                    break;

                case "scaleY":
                    v = key.Value;
                    break;

                case "scaleZ":
                    v = key.Value;
                    break;
                }

                file.WriteLine(" " + (key.Frame + 1) + " {0:N6} fixed fixed 1 1 0 " + key.In * scale + " 1 " + (key.Out != -1 ? key.Out : key.In) * scale + " 1;", v);
            }

            file.WriteLine(" }");
        }
Пример #14
0
        public static void CreateANIM(string fname, Animation a, VBN vbn)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(@fname))
            {
                AnimHeader header = new AnimHeader();
                file.WriteLine("animVersion " + header.animVersion + ";");
                file.WriteLine("mayaVersion " + header.mayaVersion + ";");
                file.WriteLine("timeUnit " + header.timeUnit + ";");
                file.WriteLine("linearUnit " + header.linearUnit + ";");
                file.WriteLine("angularUnit " + header.angularUnit + ";");
                file.WriteLine("startTime " + 1 + ";");
                file.WriteLine("endTime " + a.FrameCount + ";");

                a.SetFrame(a.FrameCount - 1);             //from last frame
                for (int li = 0; li < a.FrameCount; ++li) //go through each frame with nextFrame
                {
                    a.NextFrame(vbn);
                }
                a.NextFrame(vbn);  //go on first frame

                int i = 0;

                // writing node attributes
                foreach (Bone b in vbn.getBoneTreeOrder())
                {
                    i = vbn.boneIndex(b.Text);

                    if (a.HasBone(b.Text))
                    {
                        // write the bone attributes
                        // count the attributes
                        Animation.KeyNode n = a.GetBone(b.Text);
                        int ac = 0;

                        if (n.XPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateX translateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XPOS, n, a.Size(), "translateX");
                            file.WriteLine("}");
                        }
                        if (n.YPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateY translateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YPOS, n, a.Size(), "translateY");
                            file.WriteLine("}");
                        }
                        if (n.ZPOS.HasAnimation())
                        {
                            file.WriteLine("anim translate.translateZ translateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZPOS, n, a.Size(), "translateZ");
                            file.WriteLine("}");
                        }
                        if (n.XROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateX rotateX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XROT, n, a.Size(), "rotateX");
                            file.WriteLine("}");
                        }
                        if (n.YROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateY rotateY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YROT, n, a.Size(), "rotateY");
                            file.WriteLine("}");
                        }
                        if (n.ZROT.HasAnimation())
                        {
                            file.WriteLine("anim rotate.rotateZ rotateZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZROT, n, a.Size(), "rotateZ");
                            file.WriteLine("}");
                        }
                        if (n.XSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleX scaleX " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.XSCA, n, a.Size(), "scaleX");
                            file.WriteLine("}");
                        }
                        if (n.YSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleY scaleY " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.YSCA, n, a.Size(), "scaleY");
                            file.WriteLine("}");
                        }
                        if (n.ZSCA.HasAnimation())
                        {
                            file.WriteLine("anim scale.scaleZ scaleZ " + b.Text + " 0 0 " + (ac++) + ";");
                            writeKey(file, n.ZSCA, n, a.Size(), "scaleZ");
                            file.WriteLine("}");
                        }

                        if (ac == 0)
                        {
                            file.WriteLine("anim " + b.Text + " 0 0 0;");
                        }
                    }
                    else
                    {
                        file.WriteLine("anim " + b.Text + " 0 0 0;");
                    }
                }
            }
        }
Пример #15
0
        private void Render(object sender, PaintEventArgs e)
        {
            if (!ReadyToRender)
            {
                return;
            }

            glViewport.MakeCurrent();

            GL.LoadIdentity();
            GL.Viewport(glViewport.ClientRectangle);

            // Push all attributes so we don't have to clean up later
            GL.PushAttrib(AttribMask.AllAttribBits);
            // clear the gf buffer
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);

            // use fixed function pipeline for drawing background and floor grid
            GL.UseProgram(0);

            if (MeshList.treeView1.SelectedNode != null)
            {
                if (MeshList.treeView1.SelectedNode is BCH_Texture)
                {
                    GL.PopAttrib();
                    BCH_Texture tex = ((BCH_Texture)MeshList.treeView1.SelectedNode);
                    RenderTools.DrawTexturedQuad(tex.display, tex.Width, tex.Height, true, true, true, true, false, true);
                    glViewport.SwapBuffers();
                    return;
                }
                if (MeshList.treeView1.SelectedNode is NUT_Texture)
                {
                    GL.PopAttrib();
                    NUT_Texture tex = ((NUT_Texture)MeshList.treeView1.SelectedNode);
                    RenderTools.DrawTexturedQuad(((NUT)tex.Parent).draw[tex.HASHID], tex.Width, tex.Height, true, true, true, true, false, true);
                    glViewport.SwapBuffers();
                    return;
                }
            }

            if (Runtime.renderBackGround)
            {
                // background uses different matrices
                GL.MatrixMode(MatrixMode.Modelview);
                GL.LoadIdentity();
                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();

                RenderTools.RenderBackground();
            }

            // Camera Update
            // -------------------------------------------------------------
            GL.MatrixMode(MatrixMode.Projection);
            if (glViewport.ClientRectangle.Contains(glViewport.PointToClient(Cursor.Position)) &&
                glViewport.Focused &&
                CurrentMode == Mode.Normal &&
                !TransformTool.hit)
            {
                Camera.Update();
                //if (cameraPosForm != null && !cameraPosForm.IsDisposed)
                //    cameraPosForm.updatePosition();
            }
            try
            {
                if (OpenTK.Input.Mouse.GetState() != null)
                {
                    Camera.mouseSLast = OpenTK.Input.Mouse.GetState().WheelPrecise;
                }
            } catch
            {
            }

            Matrix4 matrix = Camera.getMVPMatrix();

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref matrix);

            // Floor
            // -------------------------------------------------------------
            if (Runtime.renderFloor)
            {
                RenderTools.drawFloor();
            }

            // Shadows
            // -------------------------------------------------------------
            if (Runtime.drawModelShadow)
            {
                CalculateLightSource();
                // update light matrix and setup shadowmap rendering
                GL.MatrixMode(MatrixMode.Modelview);
                GL.LoadMatrix(ref lightMatrix);
                GL.Enable(EnableCap.DepthTest);
                GL.Viewport(0, 0, sw, sh);
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, sfb);

                foreach (ModelContainer m in draw)
                {
                    m.RenderShadow(Camera, 0, Matrix4.Zero, Camera.getMVPMatrix());
                }

                // reset matrices and viewport for model rendering again
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
                GL.LoadMatrix(ref matrix);
                GL.Viewport(glViewport.ClientRectangle);
            }

            // render models into hdr buffer
            // -------------------------------------------------------------
            if (Runtime.useDepthTest)
            {
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Lequal);
            }

            else
            {
                GL.Disable(EnableCap.DepthTest);
            }

            GL.Enable(EnableCap.DepthTest);

            // Models
            // -------------------------------------------------------------
            //frameTime.Start();
            if (Runtime.renderModel || Runtime.renderModelWireframe)
            {
                foreach (TreeNode m in draw)
                {
                    if (m is ModelContainer)
                    {
                        ((ModelContainer)m).Render(Camera, 0, Matrix4.Zero, Camera.getMVPMatrix());
                    }
                }
            }

            if (ViewComboBox.SelectedIndex == 1)
            {
                foreach (TreeNode m in draw)
                {
                    if (m is ModelContainer)
                    {
                        ((ModelContainer)m).RenderPoints(Camera);
                    }
                }
            }


            //GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

            /*// render gaussian blur stuff
             * if (Runtime.drawQuadBlur)
             *  DrawQuadBlur();
             *
             * // render full screen quad for post processing
             * if (Runtime.drawQuadFinalOutput)
             *  DrawQuadFinalOutput();*/

            // use fixed function pipeline again for area lights, lvd, bones, hitboxes, etc
            SetupFixedFunctionRendering();

            /*// draw path.bin
             * if (Runtime.renderPath)
             *  DrawPathDisplay();
             *
             * // area light bounding boxes should intersect stage geometry and not render on top
             * if (Runtime.drawAreaLightBoundingBoxes)
             *  DrawAreaLightBoundingBoxes();*/

            // clear depth buffer so stuff will render on top of the models
            GL.Clear(ClearBufferMask.DepthBufferBit);

            if (Runtime.renderLVD)
            {
                _lvd.Render();
            }

            if (Runtime.renderBones)
            {
                foreach (ModelContainer m in draw)
                {
                    m.RenderBones();
                }
            }


            // ACMD
            if (ParamManager != null && Runtime.renderHurtboxes && draw.Count > 0 && (draw[0] is ModelContainer))
            {
                ParamManager.RenderHurtboxes(Frame, scriptId, ACMDScript, ((ModelContainer)draw[0]).GetVBN());
            }

            if (ACMDScript != null && draw.Count > 0 && (draw[0] is ModelContainer))
            {
                ACMDScript.Render(((ModelContainer)draw[0]).GetVBN());
            }
            //Debug.WriteLine(frameTime.getAverageRenderTime());



            // Bone Transform Tool
            if (ViewComboBox.SelectedIndex == 2)
            {
                if (modeBone.Checked)
                {
                    TransformTool.Render(Camera, new Ray(Camera, glViewport));
                    if (TransformTool.state == 1)
                    {
                        CurrentMode = Mode.Selection;
                    }
                    else
                    {
                        CurrentMode = Mode.Normal;
                    }
                }

                if (TransformTool.HasChanged())
                {
                    if (Animation != null && TransformTool.b != null)
                    {
                        // get the node group for the current bone in animation
                        Animation.KeyNode ThisNode = null;
                        foreach (Animation.KeyNode node in Animation.Bones)
                        {
                            if (node.Text.Equals(TransformTool.b.Text))
                            {
                                // found
                                ThisNode = node;
                                break;
                            }
                        }
                        if (ThisNode == null)
                        {
                            ThisNode = new Animation.KeyNode(TransformTool.b.Text);
                            Animation.Bones.Add(ThisNode);
                        }

                        // update or add the key frame
                        ThisNode.SetKeyFromBone((float)currentFrame.Value, TransformTool.b);
                    }
                }
            }


            // Mouse selection
            // -------------------------------------------------------------
            if (ViewComboBox.SelectedIndex == 1)
            {
                try
                {
                    if (CurrentMode == Mode.Normal && OpenTK.Input.Mouse.GetState().IsButtonDown(OpenTK.Input.MouseButton.Right))
                    {
                        CurrentMode = Mode.Selection;
                        Vector2 m = GetMouseOnViewport();
                        sx1 = m.X;
                        sy1 = m.Y;
                    }
                }
                catch
                {
                }
                if (CurrentMode == Mode.Selection)
                {
                    if (!OpenTK.Input.Mouse.GetState().IsButtonDown(OpenTK.Input.MouseButton.Right))
                    {
                        checkSelect();
                        CurrentMode = Mode.Normal;
                    }

                    GL.MatrixMode(MatrixMode.Modelview);
                    GL.PushMatrix();
                    GL.LoadIdentity();

                    Vector2 m = GetMouseOnViewport();
                    GL.Color3(Color.Black);
                    GL.LineWidth(2f);
                    GL.Begin(PrimitiveType.LineLoop);
                    GL.Vertex2(sx1, sy1);
                    GL.Vertex2(m.X, sy1);
                    GL.Vertex2(m.X, m.Y);
                    GL.Vertex2(sx1, m.Y);
                    GL.End();

                    GL.Color3(Color.White);
                    GL.LineWidth(1f);
                    GL.Begin(PrimitiveType.LineLoop);
                    GL.Vertex2(sx1, sy1);
                    GL.Vertex2(m.X, sy1);
                    GL.Vertex2(m.X, m.Y);
                    GL.Vertex2(sx1, m.Y);
                    GL.End();
                    GL.PopMatrix();
                }
            }

            /*if (CurrentMode == Mode.Photoshoot)
             * {
             *  freezeCamera = false;
             *  if (Keyboard.GetState().IsKeyDown(Key.W) && Mouse.GetState().IsButtonDown(MouseButton.Left))
             *  {
             *      shootX = this.PointToClient(Cursor.Position).X;
             *      shootY = this.PointToClient(Cursor.Position).Y;
             *      freezeCamera = true;
             *  }
             *  // Hold on to your pants, boys
             *  RenderTools.DrawPhotoshoot(glViewport, shootX, shootY, shootWidth, shootHeight);
             * }*/

            GL.PopAttrib();
            glViewport.SwapBuffers();
        }