////////////////////////////////////////////////////////////////////////////////////////////////////// #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;//?? 居然两个效果都是一样的? } }
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(); //创建所有位图 } }