/// <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> /// Prepara una nueva animacion para ser ejecutada /// </summary> protected void initAnimationSettings(string animationName, bool playLoop, float userFrameRate) { isAnimating = true; currentAnimation = animations[animationName]; this.playLoop = playLoop; currentTime = 0; currentFrame = 0; //Cambiar BoundingBox boundingBox = currentAnimation.BoundingBox; updateBoundingBox(); //Si el usuario no especifico un FrameRate, tomar el default de la animacion if (userFrameRate == -1f) { frameRate = (float)currentAnimation.FrameRate; } else { frameRate = userFrameRate; } //La duracion de la animacion. animationTimeLenght = ((float)currentAnimation.FramesCount - 1) / frameRate; //Configurar postura inicial de los huesos for (int i = 0; i < bones.Length; i++) { TgcSkeletalBone bone = bones[i]; if (!currentAnimation.hasFrames(i)) { throw new Exception("El hueso " + bone.Name + " no posee KeyFrames"); } //Determinar matriz local inicial TgcSkeletalAnimationFrame firstFrame = currentAnimation.BoneFrames[i][0]; bone.MatLocal = Matrix.RotationQuaternion(firstFrame.Rotation) * Matrix.Translation(firstFrame.Position); //Multiplicar por matriz del padre, si tiene if (bone.ParentBone != null) { bone.MatFinal = bone.MatLocal * bone.ParentBone.MatFinal; } else { bone.MatFinal = bone.MatLocal; } } //Ajustar vertices a posicion inicial del esqueleto updateMeshVertices(); }
/// <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 datos iniciales /// </summary> protected void initData(Mesh mesh, string name, MeshRenderType renderType, TgcSkeletalBone[] bones) { this.d3dMesh = mesh; this.name = name; this.renderType = renderType; this.enabled = false; this.autoUpdateBoundingBox = true; this.bones = bones; this.attachments = new List <TgcSkeletalBoneAttach>(); this.meshInstances = new List <TgcSkeletalMesh>(); this.renderSkeleton = false; this.alphaBlendEnable = false; //variables de movimiento this.autoTransformEnable = true; this.translation = new Vector3(0f, 0f, 0f); this.rotation = new Vector3(0f, 0f, 0f); this.scale = new Vector3(1f, 1f, 1f); this.transform = Matrix.Identity; //variables de animacion this.isAnimating = false; this.currentAnimation = null; this.playLoop = false; this.frameRate = 0f; this.currentTime = 0f; this.animationTimeLenght = 0f; this.currentFrame = 0; this.animations = new Dictionary <string, TgcSkeletalAnimation>(); //Matrices de huesos this.boneSpaceFinalTransforms = new Matrix[MAX_BONE_COUNT]; //Shader vertexDeclaration = new VertexDeclaration(mesh.Device, mesh.Declaration); this.effect = GuiController.Instance.Shaders.TgcSkeletalMeshShader; this.technique = GuiController.Instance.Shaders.getTgcSkeletalMeshTechnique(this.renderType); //acomodar huesos setupSkeleton(); }
/// <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 datos iniciales /// </summary> protected void initData(Mesh mesh, string name, MeshRenderType renderType, TgcSkeletalBone[] bones) { this.d3dMesh = mesh; this.name = name; this.renderType = renderType; this.enabled = false; this.autoUpdateBoundingBox = true; this.bones = bones; this.attachments = new List<TgcSkeletalBoneAttach>(); this.meshInstances = new List<TgcSkeletalMesh>(); this.renderSkeleton = false; this.alphaBlendEnable = false; //variables de movimiento this.autoTransformEnable = true; this.translation = new Vector3(0f, 0f, 0f); this.rotation = new Vector3(0f, 0f, 0f); this.scale = new Vector3(1f, 1f, 1f); this.transform = Matrix.Identity; //variables de animacion this.isAnimating = false; this.currentAnimation = null; this.playLoop = false; this.frameRate = 0f; this.currentTime = 0f; this.animationTimeLenght = 0f; this.currentFrame = 0; this.animations = new Dictionary<string, TgcSkeletalAnimation>(); //Matrices de huesos this.boneSpaceFinalTransforms = new Matrix[MAX_BONE_COUNT]; //Shader vertexDeclaration = new VertexDeclaration(mesh.Device, mesh.Declaration); this.effect = GuiController.Instance.Shaders.TgcSkeletalMeshShader; this.technique = GuiController.Instance.Shaders.getTgcSkeletalMeshTechnique(this.renderType); //acomodar huesos setupSkeleton(); }
/// <summary> /// Cargar datos iniciales /// </summary> protected void initData(Mesh mesh, string name, MeshRenderType renderType, OriginalData originalData, TgcSkeletalBone[] bones, TgcSkeletalVertexWeight[] verticesWeights) { this.d3dMesh = mesh; this.name = name; this.renderType = renderType; this.originalData = originalData; this.enabled = false; this.autoUpdateBoundingBox = true; this.bones = bones; this.verticesWeights = verticesWeights; this.attachments = new List<TgcSkeletalBoneAttach>(); this.meshInstances = new List<TgcSkeletalMesh>(); this.renderSkeleton = false; this.alphaBlendEnable = false; //Crear vertexDeclaration vertexDeclaration = new VertexDeclaration(mesh.Device, mesh.Declaration); //variables de movimiento this.autoTransformEnable = true; this.translation = new Vector3(0f, 0f, 0f); this.rotation = new Vector3(0f, 0f, 0f); this.scale = new Vector3(1f, 1f, 1f); this.transform = Matrix.Identity; //variables de animacion this.isAnimating = false; this.currentAnimation = null; this.playLoop = false; this.frameRate = 0f; this.currentTime = 0f; this.animationTimeLenght = 0f; this.currentFrame = 0; this.animations = new Dictionary<string, TgcSkeletalAnimation>(); //acomodar huesos setupSkeleton(); }