private void FillBoneNodes(ref AMT_JOINT parentBone, XElement boneNode, ref AMT_MODEL amtModel) { //pego todos os nodes List<XElement> nodes = boneNode.Elements(XName.Get("node", Namespace)).ToList(); foreach (var node in nodes) { //se é um bone if (node.Attribute("type") != null && node.Attribute("type").Value.Contains("JOINT")) { Matrix matrix = Matrix.Identity; //pega o nome e a matrix do bone string boneName = node.Attribute("name").Value; string boneId = node.Attribute("id").Value; string sid = node.Attribute("sid").Value; XElement matrixElement = node.Element(XName.Get("matrix", Namespace)); string matrixSID = null; if (matrixElement.Attribute("sid") != null) matrixSID = matrixElement.Attribute("sid").Value; //uso nas animacoes para achar o bone id/sid matrix = Tools.ConvertStringToMatrix(matrixElement.Value, 0); // Create this node, use the current number of bones as number. AMT_JOINT newBone = new AMT_JOINT(); newBone.SID = sid; newBone.TARGET = boneId + "/" + matrixSID; newBone.ID = (uint)amtModel.Joints.Count(); newBone.ParentID = (int)parentBone.ID; newBone.Name = boneName; newBone.NumChildren = 0; newBone.JointChildren = new List<uint>(); newBone.NumKF = 0; newBone.KFData = new List<AMT_KF>(); newBone.IsAnimated = (uint)(string.IsNullOrEmpty(matrixSID) ? 0 : 1); newBone.Flag = 0; //atualiza o bone pai parentBone.NumChildren++; parentBone.JointChildren.Add(newBone.ID); //matrix relativa newBone.BindMatrix = matrix; //absoluta = relativa do atual * absoluta do pai newBone.MatrixAbsolute = matrix * parentBone.MatrixAbsolute; //inversa da matriz relativa newBone.InverseBindMatrix = Matrix.Invert(newBone.MatrixAbsolute); amtModel.Joints.Add(newBone); // vai para os filhos FillBoneNodes(ref newBone, node, ref amtModel); } } }
private void ConvertBones(XElement rootElement, ref AMT_MODEL amtModel) { //primeiro eu encontro o library_visual_scenes XElement libraryVisualScenes = rootElement.Element(XName.Get("library_visual_scenes", Namespace)); XElement visualScene = libraryVisualScenes.Element(XName.Get("visual_scene", Namespace)); //se tem o nodo skeleton XElement rootNode = FindRootSkeletonNodeId(visualScene); amtModel.Joints = new List<AMT_JOINT>(); //Começo a percorrer os nodes procurando pela hierarquia de bones if (rootNode != null) { //adiciona o bone raiz Matrix matrix = Matrix.Identity; string sid = rootNode.Attribute("sid").Value; string boneId = rootNode.Attribute("id").Value; XElement matrixElement = rootNode.Element(XName.Get("matrix", Namespace)); string matrixSID = null; if (matrixElement.Attribute("sid") != null) matrixSID = matrixElement.Attribute("sid").Value; //uso nas animacoes para achar o bone id/sid matrix = Tools.ConvertStringToMatrix(matrixElement.Value, 0); AMT_JOINT newBone = new AMT_JOINT(); newBone.SID = sid; newBone.TARGET = boneId + "/" + matrixSID; newBone.ID = 0; newBone.ParentID = -1; //nao tem pai newBone.Name = "Root"; newBone.NumChildren = 0; newBone.JointChildren = new List<uint>(); newBone.NumKF = 0; newBone.KFData = new List<AMT_KF>(); //se nao tem sid entao ele nao é animado newBone.IsAnimated = (uint)(string.IsNullOrEmpty(matrixSID)? 0 : 1); newBone.Flag = 0; newBone.BindMatrix = matrix; newBone.MatrixAbsolute = matrix; newBone.InverseBindMatrix = Matrix.Invert(matrix); amtModel.Joints.Add(newBone); FillBoneNodes(ref newBone, rootNode, ref amtModel); } }