Пример #1
0
        public void InitLocalTransformation()         //更新骨骼的本地变换
        {
            boneused = new bool[abi.num_bone];

            local_transf = new Matrix[abi.num_bone];             //每根骨头有一个local_transf
            global_tranf = new Matrix[abi.num_bone];             //每根骨头有一个global_tranf

            Animation ani = abi.animations[animation_idx];

            for (int i = 0; i < ani.num_related_bone; i++)              //遍历所有相关的骨头
            {
                int bidx = ani.bae[i].bone_id;                          //第几根骨头
                TransformTimeAxis tta = ani.bae[i].tta;                 //该骨头对应的时间轴

                Quaternion outq;
                Vector3    outv;

                InterpolationOfLocalTransformation(tta, time, out outq, out outv);

                //注意:这里的左右手系相关的函数:RotationQuaternion
                //注意:这里的outq已经转换至左手系了,可以利用DX的左手系函数来进行实质上的右手系计算了

                #region 便于理解版本
                //Matrix x = Matrix.RotationQuaternion(outq); //!!!
                //Matrix y = Matrix.Translation(outv);
                //local_transf[bidx] = x * y; //先旋转,后平移
                #endregion

                #region 优化计算版本
                Matrix x = Matrix.RotationQuaternion(outq); //!!!
                x.M41 += outv.X;                            //等价于先转转、再平移
                x.M42 += outv.Y;                            //等价于先转转、再平移
                x.M43 += outv.Z;                            //等价于先转转、再平移
                local_transf[bidx] = x;                     //先旋转,后平移
                #endregion

                boneused[bidx] = true;                 //使用标记
            }
        }
Пример #2
0
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        #region 插值、更新骨骼的本地变换
        void InterpolationOfLocalTransformation(TransformTimeAxis tta, float time, out Quaternion q, out Vector3 t)
        {
            RotateTimeAxis rta   = tta.rta;
            float          scale = 0f;
            float          rtime;

            if (rta.rkf[rta.num_keyframe - 1].timestamp == 0)
            {
                rtime = 0f;
            }
            else
            {
                rtime = time % (rta.rkf[rta.num_keyframe - 1].timestamp);
            }

            RotateKeyFrame fromrkf = null, torkf = null;

            if (rta.num_keyframe == 1)             //TODO: 没有考虑num_keyframe==0的情况
            {
                q = Quaternion_RH_To_LH(rta.rkf[0].rotate);
            }
            else
            {
                for (int i = 0; i < rta.num_keyframe - 1; i++)
                {
                    fromrkf = rta.rkf[i];
                    torkf   = rta.rkf[i + 1];

                    if (rtime >= fromrkf.timestamp && rtime <= torkf.timestamp)                     //哪两个关键帧之间?
                    {
                        scale = (rtime - fromrkf.timestamp) / (torkf.timestamp - fromrkf.timestamp);
                        break;
                    }
                }

                //无敌修改!将右手系的旋转数据转换成左手系的,以便于使用DX的左手系函数来进行计算
                //左手系相关的主要函数:RotationQuaternion和Slerp,而矩阵乘法、平移变换是与左右手系无关的
                //总之,这里的重点是:保持模型数据及其计算的右手系特性,利用DX的左手系函数来进行实质上的右手系计算
                Quaternion fromq = Quaternion_RH_To_LH(fromrkf.rotate);
                Quaternion toq   = Quaternion_RH_To_LH(torkf.rotate);
                q = Quaternion.Slerp(fromq, toq, scale);                 //!!
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            TranslateTimeAxis trta = tta.trta;
            float             ttime;

            if (trta.tkf[trta.num_keyframe - 1].timestamp == 0)
            {
                ttime = 0;
            }
            else
            {
                ttime = time % (trta.tkf[trta.num_keyframe - 1].timestamp);
            }

            TranslateKeyFrame fromtkf = null, totkf = null;

            if (trta.num_keyframe == 1)             //TODO: 没有考虑num_keyframe==0的情况
            {
                t = trta.tkf[0].translate;
            }
            else
            {
                for (int i = 0; i < trta.num_keyframe - 1; i++)                 //BUG: 没有考虑num_keyframe==1的情况;未修正
                {
                    fromtkf = trta.tkf[i];
                    totkf   = trta.tkf[i + 1];

                    if (ttime >= fromtkf.timestamp && ttime <= totkf.timestamp)                     //哪两个关键帧之间?
                    {
                        scale = (ttime - fromtkf.timestamp) / (totkf.timestamp - fromtkf.timestamp);
                        break;
                    }
                }

                Vector3 fromt = fromtkf.translate;
                Vector3 tot   = totkf.translate;
                t = (1 - scale) * fromt + scale * tot;                //?? 暂时以jsm的为准
                //t = scale * fromt + (1-scale) * tot;//?? 居然两个效果都是一样的?
            }
        }
Пример #3
0
        public Animation[] animations;                  //num_animation个

        ///////////////////////////////////////////////////////////////////////////////////////////////////////////
        public ABI(string filename)
        {
            this.filename = filename;
            FileInfo fi = new FileInfo(filename);

            this.filename = fi.Name;

            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    int sign = br.ReadInt32();;
                    Debug.Assert(sign == 0x424d444c);

                    version = int.Parse(ConvertBytesToString(br.ReadBytes(4)));
                    Debug.Assert(version == 1060 || version == 1050, "此ABI文件的版本不是1050或1060!");

                    num_timeaxis  = br.ReadInt32();
                    num_animation = br.ReadInt32();
                    num_texture   = br.ReadInt32();

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //所有贴图
                    textureinfos = new TextureInfo[num_texture];
                    for (int i = 0; i < num_texture; i++)
                    {
                        textureinfos[i]         = new TextureInfo();
                        textureinfos[i].UNKNOWN = br.ReadInt32();
                        textureinfos[i].width   = br.ReadInt32();
                        textureinfos[i].height  = br.ReadInt32();
                        textureinfos[i].name    = ConvertBytesToString(br.ReadBytes(32));

                        textureinfos[i].palette = new uint[256];
                        for (int j = 0; j < 256; j++)
                        {
                            uint r = br.ReadByte();
                            uint g = br.ReadByte();
                            uint b = br.ReadByte();

                            textureinfos[i].palette[j] = 0xff000000 | (r << 16) | (g << 8) | b;
                        }

                        textureinfos[i].data = br.ReadBytes(textureinfos[i].width * textureinfos[i].height);
                    }

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //模型数据
                    if (version != 1050)
                    {
                        br.ReadByte();                        //未知标志,并不恒为1,奇怪的是,1050格式里面没有这个自己,而1060却有
                    }
                    //Debug.Assert(br.ReadByte() == 1);

                    num_model = br.ReadInt32();
                    num_bone  = br.ReadInt32();

                    models = new Model[num_model];
                    for (int i = 0; i < num_model; i++)
                    {
                        Model d = models[i] = new Model();
                        d.num_vertice = br.ReadInt32();
                        d.num_polygon = br.ReadInt32();
                        d.name        = ConvertBytesToString(br.ReadBytes(32));

                        d.vertex = new Vertex[d.num_vertice];
                        for (int j = 0; j < d.num_vertice; j++)
                        {
                            Vertex v = d.vertex[j] = new Vertex();
                            v.X = br.ReadSingle();
                            v.Y = br.ReadSingle();
                            v.Z = br.ReadSingle();
                        }

                        d.polygon = new Polygon[d.num_polygon];
                        for (int j = 0; j < d.num_polygon; j++)
                        {
                            Polygon poly = d.polygon[j] = new Polygon();
                            poly.num_lines = br.ReadByte();

                            if (poly.num_lines != 3 && poly.num_lines != 4)
                            {
                                //的确存在num_lines超过3/4的情况,比方说tiger.abi,num_lines就有为6的情况
                                //throw new Exception();
                            }

                            poly.texture_id = br.ReadByte();

                            poly.map_points = new Point[poly.num_lines];
                            for (int k = 0; k < poly.num_lines; k++)
                            {
                                Point p = poly.map_points[k] = new Point();
                                p.vertex_id = br.ReadInt16();
                                p.U         = br.ReadInt16() / 4096f;
                                p.V         = br.ReadInt16() / 4096f;
                            }
                        }

                        d.vbt       = new VidToBoneTable();
                        d.vbt.entry = new VidToBoneTableEntry[num_bone];
                        for (int j = 0; j < num_bone; j++)
                        {
                            d.vbt.entry[j]           = new VidToBoneTableEntry();
                            d.vbt.entry[j].StartVidx = br.ReadInt32();
                            d.vbt.entry[j].EndVidx   = br.ReadInt32();                           //要不要-1?
                        }
                    }

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //骨骼继承结构
                    hierarchy = new BoneHierarchy[num_bone];

                    for (int i = 0; i < num_bone; i++)
                    {
                        hierarchy[i]              = new BoneHierarchy();
                        hierarchy[i].ParentIdx    = br.ReadInt32();
                        hierarchy[i].GlobalOffset = new Vector3(
                            br.ReadSingle(),
                            br.ReadSingle(),
                            br.ReadSingle());
                        hierarchy[i].NodeName = ConvertBytesToString(br.ReadBytes(32));
                        hierarchy[i].UNKNOWN  = br.ReadInt32();

                        Debug.WriteLine(String.Format("{0} - [{1}]:{2}", i, hierarchy[i].ParentIdx, hierarchy[i].NodeName));
                        Debug.Assert(hierarchy[i].UNKNOWN == 0);
                    }

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //关键帧、时间轴相关结构
                    timeaxises = new TransformTimeAxis[num_timeaxis];

                    for (int i = 0; i < num_timeaxis; i++)
                    {
                        TransformTimeAxis ta = timeaxises[i] = new TransformTimeAxis();
                        ta.trta = new TranslateTimeAxis();
                        ta.rta  = new RotateTimeAxis();

                        TranslateTimeAxis tta = ta.trta;
                        tta.num_keyframe = br.ReadInt32();
                        tta.tkf          = new TranslateKeyFrame[tta.num_keyframe];
                        for (int j = 0; j < tta.num_keyframe; j++)
                        {
                            tta.tkf[j]           = new TranslateKeyFrame();
                            tta.tkf[j].timestamp = br.ReadByte();
                            tta.tkf[j].translate = new Vector3(br.ReadInt16() / 256f, br.ReadInt16() / 256f, br.ReadInt16() / 256f);
                        }

                        RotateTimeAxis rta = ta.rta;
                        rta.num_keyframe = br.ReadInt32();
                        rta.rkf          = new RotateKeyFrame[rta.num_keyframe];
                        for (int j = 0; j < rta.num_keyframe; j++)
                        {
                            rta.rkf[j]           = new RotateKeyFrame();
                            rta.rkf[j].timestamp = br.ReadByte();
                            rta.rkf[j].rotate    = new Quaternion(br.ReadInt16() / 32768f, br.ReadInt16() / 32768f, br.ReadInt16() / 32768f, br.ReadInt16() / 32768f);
                        }
                    }

                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //动画行为定义结构
                    animations = new Animation[num_animation];

                    for (int i = 0; i < num_animation; i++)
                    {
                        Animation ani = animations[i] = new Animation();
                        ani.name             = ConvertBytesToString(br.ReadBytes(0x3c));
                        ani.num_related_bone = br.ReadInt32();

                        ani.bae = new BoneAnimationEntry[ani.num_related_bone];
                        for (int j = 0; j < ani.num_related_bone; j++)
                        {
                            BoneAnimationEntry bae = ani.bae[j] = new BoneAnimationEntry();
                            bae.bone_id = br.ReadInt32();
                            bae.transform_time_axis_idx = br.ReadInt32();
                            bae.tta = timeaxises[bae.transform_time_axis_idx];
                        }
                    }

                    Debug.WriteLine("已读长度: " + fs.Position.ToString());
                    Debug.WriteLine("文件长度: " + fs.Length.ToString());
                }

                //GenerateAllBitmaps(); //创建所有位图
            }
        }