////////////////////////////////////////////////////////////////////////////////////////////////////////// public void UpdateBoneHierarchyTransformation() //遍历bone层级,计算各个bone的累计matrix { for (int i = 0; i < abi.hierarchy.Length; i++) { if (!boneused[i]) { continue; //当前动画没有使用该骨头,跳过 } int parent = abi.hierarchy[i].ParentIdx; BoneHierarchy bh = abi.hierarchy[i]; if (parent == -1) //root bone,无需更新 { #region 便于理解版本 //global_tranf[i] = local_transf[i] * Matrix.Translation(bh.GlobalOffset); #endregion #region 优化计算版本 global_tranf[i] = local_transf[i]; global_tranf[i].M41 += bh.GlobalOffset.X; global_tranf[i].M42 += bh.GlobalOffset.Y; global_tranf[i].M43 += bh.GlobalOffset.Z; #endregion } else { BoneHierarchy bph = abi.hierarchy[parent]; Vector3 dt = bh.GlobalOffset - bph.GlobalOffset; #region 便于理解版本 //global_tranf[i] = local_transf[i] * Matrix.Translation(dt) * global_tranf[parent]; #endregion #region 优化计算版本 global_tranf[i] = local_transf[i]; global_tranf[i].M41 += dt.X; global_tranf[i].M42 += dt.Y; global_tranf[i].M43 += dt.Z; global_tranf[i] *= global_tranf[parent]; #endregion } } }
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(); //创建所有位图 } }