/// <summary> /// Levanta la informacion de una animacion a partir del XML /// </summary> /// <param name="xmlString">Contenido que el XML</param> /// <returns>Información parseada</returns> public TgcSkeletalAnimationData parseAnimationFromString(string xmlString) { XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlString); XmlElement root = dom.DocumentElement; TgcSkeletalAnimationData animation = new TgcSkeletalAnimationData(); //Parsear informacion general de animation XmlElement animationNode = (XmlElement)root.GetElementsByTagName("animation")[0]; animation.name = animationNode.Attributes["name"].InnerText; animation.bonesCount = int.Parse(animationNode.Attributes["bonesCount"].InnerText); animation.framesCount = int.Parse(animationNode.Attributes["framesCount"].InnerText); animation.frameRate = int.Parse(animationNode.Attributes["frameRate"].InnerText); animation.startFrame = int.Parse(animationNode.Attributes["startFrame"].InnerText); animation.endFrame = int.Parse(animationNode.Attributes["endFrame"].InnerText); //Parsear boundingBox, si esta XmlNodeList boundingBoxNodes = animationNode.GetElementsByTagName("boundingBox"); if (boundingBoxNodes != null && boundingBoxNodes.Count == 1) { XmlNode boundingBoxNode = boundingBoxNodes[0]; animation.pMin = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["min"].InnerText); animation.pMax = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["max"].InnerText); } //Parsear bones XmlNodeList boneNodes = animationNode.GetElementsByTagName("bone"); animation.bonesFrames = new TgcSkeletalAnimationBoneData[boneNodes.Count]; int boneIdx = 0; foreach (XmlElement boneNode in boneNodes) { TgcSkeletalAnimationBoneData boneData = new TgcSkeletalAnimationBoneData(); boneData.id = (int)TgcParserUtils.parseInt(boneNode.Attributes["id"].InnerText); boneData.keyFramesCount = (int)TgcParserUtils.parseInt(boneNode.Attributes["keyFramesCount"].InnerText); boneData.keyFrames = new TgcSkeletalAnimationBoneFrameData[boneData.keyFramesCount]; //Parsear frames int frames = 0; foreach (XmlElement frameNode in boneNode.ChildNodes) { TgcSkeletalAnimationBoneFrameData frameData = new TgcSkeletalAnimationBoneFrameData(); frameData.frame = TgcParserUtils.parseInt(frameNode.Attributes["n"].InnerText); frameData.position = TgcParserUtils.parseFloat3Array(frameNode.Attributes["pos"].InnerText); frameData.rotation = TgcParserUtils.parseFloat4Array(frameNode.Attributes["rotQuat"].InnerText); boneData.keyFrames[frames++] = frameData; } animation.bonesFrames[boneIdx++] = boneData; } return(animation); }
/// <summary> /// Carga una animación a un modelo ya cargado, a partir del string del XML. /// La animación se agrega al modelo. /// </summary> /// <param name="mesh">Modelo ya cargado</param> /// <param name="xmlString">contenido del XML</param> public void loadAnimationFromString(TgcSkeletalMesh mesh, string xmlString) { TgcSkeletalParser parser = new TgcSkeletalParser(); TgcSkeletalAnimationData animationData = parser.parseAnimationFromString(xmlString); TgcSkeletalAnimation animation = loadAnimation(mesh, animationData); mesh.Animations.Add(animation.Name, animation); }
/// <summary> /// Levanta la informacion de una animacion a partir del XML /// </summary> /// <param name="xmlString">Contenido que el XML</param> /// <returns>Información parseada</returns> public TgcSkeletalAnimationData parseAnimationFromString(string xmlString) { XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlString); XmlElement root = dom.DocumentElement; TgcSkeletalAnimationData animation = new TgcSkeletalAnimationData(); //Parsear informacion general de animation XmlElement animationNode = (XmlElement)root.GetElementsByTagName("animation")[0]; animation.name = animationNode.Attributes["name"].InnerText; animation.bonesCount = int.Parse(animationNode.Attributes["bonesCount"].InnerText); animation.framesCount = int.Parse(animationNode.Attributes["framesCount"].InnerText); animation.frameRate = int.Parse(animationNode.Attributes["frameRate"].InnerText); animation.startFrame = int.Parse(animationNode.Attributes["startFrame"].InnerText); animation.endFrame = int.Parse(animationNode.Attributes["endFrame"].InnerText); //Parsear boundingBox, si esta XmlNodeList boundingBoxNodes = animationNode.GetElementsByTagName("boundingBox"); if (boundingBoxNodes != null && boundingBoxNodes.Count == 1) { XmlNode boundingBoxNode = boundingBoxNodes[0]; animation.pMin = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["min"].InnerText); animation.pMax = TgcParserUtils.parseFloat3Array(boundingBoxNode.Attributes["max"].InnerText); } //Parsear bones XmlNodeList boneNodes = animationNode.GetElementsByTagName("bone"); animation.bonesFrames = new TgcSkeletalAnimationBoneData[boneNodes.Count]; int boneIdx = 0; foreach (XmlElement boneNode in boneNodes) { TgcSkeletalAnimationBoneData boneData = new TgcSkeletalAnimationBoneData(); boneData.id = (int)TgcParserUtils.parseInt(boneNode.Attributes["id"].InnerText); boneData.keyFramesCount = (int)TgcParserUtils.parseInt(boneNode.Attributes["keyFramesCount"].InnerText); boneData.keyFrames = new TgcSkeletalAnimationBoneFrameData[boneData.keyFramesCount]; //Parsear frames int frames = 0; foreach (XmlElement frameNode in boneNode.ChildNodes) { TgcSkeletalAnimationBoneFrameData frameData = new TgcSkeletalAnimationBoneFrameData(); frameData.frame = TgcParserUtils.parseInt(frameNode.Attributes["n"].InnerText); frameData.position = TgcParserUtils.parseFloat3Array(frameNode.Attributes["pos"].InnerText); frameData.rotation = TgcParserUtils.parseFloat4Array(frameNode.Attributes["rotQuat"].InnerText); boneData.keyFrames[frames++] = frameData; } animation.bonesFrames[boneIdx++] = boneData; } return animation; }
/// <summary> /// Cargar estructura de animacion /// </summary> private TgcSkeletalAnimation loadAnimation(TgcSkeletalMesh mesh, TgcSkeletalAnimationData animationData) { //Crear array para todos los huesos, tengan o no keyFrames List <TgcSkeletalAnimationFrame>[] boneFrames = new List <TgcSkeletalAnimationFrame> [mesh.Bones.Length]; //Cargar los frames para los huesos que si tienen for (int i = 0; i < animationData.bonesFrames.Length; i++) { TgcSkeletalAnimationBoneData boneData = animationData.bonesFrames[i]; //Crear frames for (int j = 0; j < boneData.keyFrames.Length; j++) { TgcSkeletalAnimationBoneFrameData frameData = boneData.keyFrames[j]; TgcSkeletalAnimationFrame frame = new TgcSkeletalAnimationFrame( frameData.frame, new Vector3(frameData.position[0], frameData.position[1], frameData.position[2]), new Quaternion(frameData.rotation[0], frameData.rotation[1], frameData.rotation[2], frameData.rotation[3]) ); //Agregar a lista de frames del hueso if (boneFrames[boneData.id] == null) { boneFrames[boneData.id] = new List <TgcSkeletalAnimationFrame>(); } boneFrames[boneData.id].Add(frame); } } //BoundingBox de la animación, aprovechar lo que viene en el XML o utilizar el de la malla estática TgcBoundingBox boundingBox = null; if (animationData.pMin != null && animationData.pMax != null) { boundingBox = new TgcBoundingBox( TgcParserUtils.float3ArrayToVector3(animationData.pMin), TgcParserUtils.float3ArrayToVector3(animationData.pMax)); } else { boundingBox = mesh.BoundingBox; } //Crear animacion TgcSkeletalAnimation animation = new TgcSkeletalAnimation(animationData.name, animationData.frameRate, animationData.framesCount, boneFrames, boundingBox); return(animation); }
/// <summary> /// Cargar estructura de animacion /// </summary> private TgcSkeletalAnimation loadAnimation(TgcSkeletalMesh mesh, TgcSkeletalAnimationData animationData) { //Crear array para todos los huesos, tengan o no keyFrames List<TgcSkeletalAnimationFrame>[] boneFrames = new List<TgcSkeletalAnimationFrame>[mesh.Bones.Length]; //Cargar los frames para los huesos que si tienen for (int i = 0; i < animationData.bonesFrames.Length; i++) { TgcSkeletalAnimationBoneData boneData = animationData.bonesFrames[i]; //Crear frames for (int j = 0; j < boneData.keyFrames.Length; j++) { TgcSkeletalAnimationBoneFrameData frameData = boneData.keyFrames[j]; TgcSkeletalAnimationFrame frame = new TgcSkeletalAnimationFrame( frameData.frame, new Vector3(frameData.position[0], frameData.position[1], frameData.position[2]), new Quaternion(frameData.rotation[0], frameData.rotation[1], frameData.rotation[2], frameData.rotation[3]) ); //Agregar a lista de frames del hueso if (boneFrames[boneData.id] == null) { boneFrames[boneData.id] = new List<TgcSkeletalAnimationFrame>(); } boneFrames[boneData.id].Add(frame); } } //BoundingBox de la animación, aprovechar lo que viene en el XML o utilizar el de la malla estática TgcBoundingBox boundingBox = null; if (animationData.pMin != null && animationData.pMax != null) { boundingBox = new TgcBoundingBox( TgcParserUtils.float3ArrayToVector3(animationData.pMin), TgcParserUtils.float3ArrayToVector3(animationData.pMax)); } else { boundingBox = mesh.BoundingBox; } //Crear animacion TgcSkeletalAnimation animation = new TgcSkeletalAnimation(animationData.name, animationData.frameRate, animationData.framesCount, boneFrames, boundingBox); return animation; }