/// <summary> /// Levanta la informacion de una animacion a partir del XML /// </summary> /// <param name="xmlString">Contenido que el XML</param> public TgcKeyFrameAnimationData parseAnimationFromString(string xmlString) { XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlString); XmlElement root = dom.DocumentElement; TgcKeyFrameAnimationData animation = new TgcKeyFrameAnimationData(); //Parsear informacion general de animation XmlElement animationNode = (XmlElement)root.GetElementsByTagName("animation")[0]; animation.name = animationNode.Attributes["name"].InnerText; animation.verticesCount = int.Parse(animationNode.Attributes["verticesCount"].InnerText); animation.framesCount = int.Parse(animationNode.Attributes["framesCount"].InnerText); animation.keyFramesCount = int.Parse(animationNode.Attributes["keyFramesCount"].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); } XmlNodeList frameNodes = animationNode.GetElementsByTagName("frame"); animation.keyFrames = new TgcKeyFrameFrameData[frameNodes.Count]; int i = 0; foreach (XmlElement frameNode in frameNodes) { TgcKeyFrameFrameData frame = new TgcKeyFrameFrameData(); int frameNumber = (int)TgcParserUtils.parseFloat(frameNode.Attributes["time"].InnerText); frame.relativeTime = (float)frameNumber / animation.framesCount; //parsear vertices frame.verticesCoordinates = TgcParserUtils.parseFloatStream(frameNode.InnerText, animation.verticesCount); animation.keyFrames[i++] = frame; } return(animation); }
/// <summary> /// Levanta la informacion de una animacion a partir del XML /// </summary> /// <param name="xmlString">Contenido que el XML</param> public TgcKeyFrameAnimationData parseAnimationFromString(string xmlString) { XmlDocument dom = new XmlDocument(); dom.LoadXml(xmlString); XmlElement root = dom.DocumentElement; TgcKeyFrameAnimationData animation = new TgcKeyFrameAnimationData(); //Parsear informacion general de animation XmlElement animationNode = (XmlElement)root.GetElementsByTagName("animation")[0]; animation.name = animationNode.Attributes["name"].InnerText; animation.verticesCount = int.Parse(animationNode.Attributes["verticesCount"].InnerText); animation.framesCount = int.Parse(animationNode.Attributes["framesCount"].InnerText); animation.keyFramesCount = int.Parse(animationNode.Attributes["keyFramesCount"].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); } XmlNodeList frameNodes = animationNode.GetElementsByTagName("frame"); animation.keyFrames = new TgcKeyFrameFrameData[frameNodes.Count]; int i = 0; foreach (XmlElement frameNode in frameNodes) { TgcKeyFrameFrameData frame = new TgcKeyFrameFrameData(); int frameNumber = (int)TgcParserUtils.parseFloat(frameNode.Attributes["time"].InnerText); frame.relativeTime = (float)frameNumber / animation.framesCount; //parsear vertices frame.verticesCoordinates = TgcParserUtils.parseFloatStream(frameNode.InnerText, animation.verticesCount); animation.keyFrames[i++] = frame; } return animation; }
/// <summary> /// Actualiza el cuadro actual de la animacion. /// Debe ser llamado en cada cuadro antes de render() /// </summary> public void updateAnimation() { Device device = GuiController.Instance.D3dDevice; float elapsedTime = GuiController.Instance.ElapsedTime; //Ver que haya transcurrido cierta cantidad de tiempo if (elapsedTime < 0.0f) { return; } //Sumo el tiempo transcurrido currentTime += elapsedTime; //Se termino la animacion if (currentTime > animationTimeLenght) { //Ver si hacer loop if (playLoop) { currentTime = 0; } else { stopAnimation(); } } //La animacion continua else { //TODO: controlar caso especial cuando hay solo un KeyFrame //Tomar el frame actual. int frameNumber = getCurrentFrame(); this.currentFrame = frameNumber; //KeyFrames a interpolar TgcKeyFrameFrameData keyFrame1 = currentAnimation.Data.keyFrames[frameNumber]; TgcKeyFrameFrameData keyFrame2 = currentAnimation.Data.keyFrames[frameNumber + 1]; float[] verticesFrame1 = keyFrame1.verticesCoordinates; float[] verticesFrame2 = keyFrame2.verticesCoordinates; //La diferencia de tiempo entre el frame actual y el siguiente. float timeDifferenceBetweenFrames = keyFrame2.relativeTime - keyFrame1.relativeTime; //En que posicion relativa de los dos frames actuales estamos. float interpolationValue = ((currentTime / animationTimeLenght) - keyFrame1.relativeTime) / timeDifferenceBetweenFrames; //Cargar array de vertices interpolados float[] verticesFrameFinal = new float[verticesFrame1.Length]; for (int i = 0; i < verticesFrameFinal.Length; i++) { verticesFrameFinal[i] = (verticesFrame2[i] - verticesFrame1[i]) * interpolationValue + verticesFrame1[i]; } //expandir array para el vertex buffer fillVertexBufferData(verticesFrameFinal); } }