/// <summary> /// 开始从局部坐标到全局坐标的转换 /// </summary> /// <param name="ct">参考坐标系</param> public void Generate(CoordinateType ct) { CoordPara = ct.ToString().ToLower(); if (null == Skeleton || null == Motion) { return; } for (int indpos = 0; indpos < Motion.Postures.Count; ++indpos) { Motion.Posture motpos = Motion.Postures[indpos]; Posture anipos = new Posture(); anipos.Index = motpos.Index; TransformBone("root", motpos, anipos); Postures.Add(anipos); } }
/// <summary> /// 迭代得到转化坐标系 /// </summary> /// <param name="name">关节名称</param> /// <param name="motpos">动作</param> /// <param name="anipos">经过转化的动作</param> protected void TransformBone(string name, Motion.Posture motpos, Posture anipos) { Skeleton.Bone skebone = Skeleton.Bones[name]; Motion.Bone motbone; #region 判断是否存在节点 bool bonecontains = false; foreach (string key in motpos.Bones.Keys) { if (key.Equals(name)) { bonecontains = true; break; } } if (bonecontains) { motbone = motpos.Bones[name]; } else { motbone = new Motion.Bone(); } #endregion Bone anibone = new Bone(); if ("root" == name) { if ("root" == CoordPara) { anibone.WorldTransform.MakeTransform(Vector3.ZERO, Vector3.UNIT_SCALE, Quaternion.IDENTITY); } else if ("global" == CoordPara) { Vector3 vec = new Vector3(); vec.x = motbone.DofVals[0]; vec.y = motbone.DofVals[1]; vec.z = motbone.DofVals[2]; Matrix3 mx = new Matrix3(); mx.FromAxisAngle(Vector3.UNIT_X, motbone.DofVals[3]); Matrix3 my = new Matrix3(); my.FromAxisAngle(Vector3.UNIT_Y, motbone.DofVals[4]); Matrix3 mz = new Matrix3(); mz.FromAxisAngle(Vector3.UNIT_Z, motbone.DofVals[5]); Quaternion localorient = new Quaternion(mz * my * mx); anibone.WorldTransform.MakeTransform(vec, Vector3.UNIT_SCALE, localorient); } anibone.WorldTranslate = anibone.WorldTransform.GetTrans(); anibone.WorldOrient = anibone.WorldTransform.ExtractQuaternion(); //anibone.WorldTranslateEnd = anibone.WorldTranslate; } else { Vector3 dof = Vector3.ZERO; for (int ind = 0; ind < skebone.DofNames.Count; ++ind) { string dofname = skebone.DofNames[ind]; float val = motbone.DofVals[ind]; if ("rx" == dofname) { dof.x = val; } else if ("ry" == dofname) { dof.y = val; } else if ("rz" == dofname) { dof.z = val; } } Matrix3 mx = new Matrix3(); mx.FromAxisAngle(Vector3.UNIT_X, dof.x); Matrix3 my = new Matrix3(); my.FromAxisAngle(Vector3.UNIT_Y, dof.y); Matrix3 mz = new Matrix3(); mz.FromAxisAngle(Vector3.UNIT_Z, dof.z); Quaternion localorient = new Quaternion(mz * my * mx); string parentname = skebone.Parent.Name; Bone parentanibone = anipos.Bones[parentname]; Skeleton.Bone parentskebone = skebone.Parent; Matrix4 parenttransform = new Matrix4(); parenttransform.MakeTransform( parentskebone.Dir * parentskebone.Length, Vector3.UNIT_SCALE, skebone.ParentOrient * localorient ); anibone.WorldTransform = parentanibone.WorldTransform * parenttransform; anibone.WorldTranslate = anibone.WorldTransform.GetTrans(); anibone.WorldOrient = anibone.WorldTransform.ExtractQuaternion() * Vector3.UNIT_Y.GetRotationTo(skebone.Dir); // anibone.WorldTranslateEnd = anibone.WorldTranslate + anibone.WorldOrient * new Vector3(0, skebone.Length, 0); } anipos.Bones.Add(name, anibone); List <Skeleton.Bone> children = skebone.Children; if (children != null) { for (int ind = 0; ind < children.Count; ++ind) { TransformBone(children[ind].Name, motpos, anipos); } } }