/// <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 = currentAnimation.FrameRate; } else { frameRate = userFrameRate; } //La duracion de la animacion. animationTimeLenght = ((float)currentAnimation.FramesCount - 1) / frameRate; //Configurar postura inicial de los huesos for (var i = 0; i < bones.Length; i++) { var bone = bones[i]; if (!currentAnimation.hasFrames(i)) { throw new Exception("El hueso " + bone.Name + " no posee KeyFrames"); } //Determinar matriz local inicial var firstFrame = currentAnimation.BoneFrames[i][0]; bone.MatLocal = TGCMatrix.RotationTGCQuaternion(firstFrame.Rotation) * TGCMatrix.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 var boneFrames = new List <TgcSkeletalAnimationFrame> [mesh.Bones.Length]; //Cargar los frames para los huesos que si tienen for (var i = 0; i < animationData.bonesFrames.Length; i++) { var boneData = animationData.bonesFrames[i]; //Crear frames for (var j = 0; j < boneData.keyFrames.Length; j++) { var frameData = boneData.keyFrames[j]; var frame = new TgcSkeletalAnimationFrame( frameData.frame, new TGCVector3(frameData.position[0], frameData.position[1], frameData.position[2]), new TGCQuaternion(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 TgcBoundingAxisAlignBox boundingBox = null; if (animationData.pMin != null && animationData.pMax != null) { boundingBox = new TgcBoundingAxisAlignBox( TGCVector3.Float3ArrayToVector3(animationData.pMin), TGCVector3.Float3ArrayToVector3(animationData.pMax)); } else { boundingBox = mesh.BoundingBox; } //Crear animacion var 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) { d3dMesh = mesh; this.name = name; this.renderType = renderType; enabled = false; autoUpdateBoundingBox = true; this.bones = bones; attachments = new List <TgcSkeletalBoneAttach>(); meshInstances = new List <TgcSkeletalMesh>(); renderSkeleton = false; AlphaBlendEnable = false; //variables de movimiento AutoTransformEnable = false; translation = TGCVector3.Empty; rotation = TGCVector3.Empty; scale = TGCVector3.One; transform = TGCMatrix.Identity; //variables de animacion isAnimating = false; currentAnimation = null; playLoop = false; frameRate = 0f; currentTime = 0f; animationTimeLenght = 0f; currentFrame = 0; animations = new Dictionary <string, TgcSkeletalAnimation>(); //Matrices de huesos boneSpaceFinalTransforms = new TGCMatrix[MAX_BONE_COUNT]; //Shader vertexDeclaration = new VertexDeclaration(mesh.Device, mesh.Declaration); effect = TGCShaders.Instance.TgcSkeletalMeshShader; technique = TGCShaders.Instance.GetTGCSkeletalMeshTechnique(this.renderType); //acomodar huesos setupSkeleton(); }