Dx高级动画制作 关键帧动画源码

#include "SkeletalAnim.h"    
   
cAnimation::cAnimation()   
{   
  m_Name = NULL;   
  m_Bone = NULL;   
  m_Next = NULL;   
   
  m_NumTranslationKeys = 0;   
  m_NumScaleKeys       = 0;   
  m_NumRotationKeys    = 0;   
  m_NumMatrixKeys      = 0;   
   
  m_TranslationKeys = NULL;   
  m_ScaleKeys       = NULL;   
  m_RotationKeys    = NULL;   
  m_MatrixKeys      = NULL;   
}   
   
cAnimation::~cAnimation()   
{   
  delete [] m_Name; m_Name = NULL;   
  delete m_Next;    m_Next = NULL;   
  delete [] m_TranslationKeys;   
  delete [] m_ScaleKeys;   
  delete [] m_RotationKeys;   
  delete [] m_MatrixKeys;   
}   
   
cAnimationSet::cAnimationSet()   
{   
  m_Name          = NULL;   
  m_Length        = 0;   
  m_Next          = NULL;   
  m_NumAnimations = 0;   
  m_Animations    = NULL;   
}   
   
cAnimationSet::~cAnimationSet()   
{   
  delete [] m_Name;    m_Name = NULL;   
  delete m_Next;       m_Next = NULL;   
  delete m_Animations; m_Animations = NULL;   
}   
   
cAnimationCollection::cAnimationCollection()   
{   
  m_NumAnimationSets = 0;   
  m_AnimationSets    = NULL;   
}   
   
cAnimationCollection::~cAnimationCollection()   
{   
  Free();   
}   
   
BOOL cAnimationCollection::ParseObject(                     \   
                   IDirectXFileData *pDataObj,                \   
                   IDirectXFileData *pParentDataObj,          \   
                   DWORD Depth,                               \   
                   void **Data, BOOL Reference)   
{   
  const GUID *Type = GetObjectGUID(pDataObj);   
  DWORD i;   
   
  // Check if template is AnimationSet type    
  if(*Type == TID_D3DRMAnimationSet) {   
   
    // Create and link in a cAnimationSet object    
    cAnimationSet *AnimSet = new cAnimationSet();   
    AnimSet->m_Next = m_AnimationSets;   
    m_AnimationSets = AnimSet;   
   
    // Increase # of animation sets    
    m_NumAnimationSets++;   
   
    // Set animation set name    
    AnimSet->m_Name = GetObjectName(pDataObj);   
  }   
   
  // Check if template is Animation type    
  if(*Type == TID_D3DRMAnimation && m_AnimationSets) {   
   
    // Add a cAnimation class to top-level cAnimationSet    
    cAnimation *Anim = new cAnimation();   
    Anim->m_Next = m_AnimationSets->m_Animations;   
    m_AnimationSets->m_Animations = Anim;   
   
    // Increase # of animations    
    m_AnimationSets->m_NumAnimations++;   
  }   
   
  // Check if a frame reference inside animation template    
  if(*Type == TID_D3DRMFrame && Reference == TRUE &&          \   
                             m_AnimationSets &&               \   
                             m_AnimationSets->m_Animations) {   
   
    // Make sure parent object is an Animation template    
    if(pParentDataObj && *GetObjectGUID(pParentDataObj) ==  \   
                                        TID_D3DRMAnimation) {   
   
      // Get name of frame and store it as animation    
      m_AnimationSets->m_Animations->m_Name =                 \   
                                  GetObjectName(pDataObj);   
    }   
   
    // Don't process child of reference frames    
    return TRUE;   
  }   
   
  // Check if template is AnimationKey type    
  if(*Type == TID_D3DRMAnimationKey && m_AnimationSets &&     \   
                            m_AnimationSets->m_Animations) {   
   
    // Get a pointer to top-level animation object    
    cAnimation *Anim = m_AnimationSets->m_Animations;   
   
    // Get a data pointer    
    DWORD *DataPtr = (DWORD*)GetObjectData(pDataObj, NULL);   
   
    // Get key type    
    DWORD Type = *DataPtr++;   
   
    // Get # of keys to follow    
    DWORD NumKeys = *DataPtr++;   
   
    // Branch based on key type    
    switch(Type) {   
      case 0: // Rotation    
        delete [] Anim->m_RotationKeys;   
        Anim->m_NumRotationKeys = NumKeys;   
        Anim->m_RotationKeys = new                            \   
                             cAnimationQuaternionKey[NumKeys];   
        for(i=0;i<NumKeys;i++) {   
          // Get time    
          Anim->m_RotationKeys[i].m_Time = *DataPtr++;   
          if(Anim->m_RotationKeys[i].m_Time >                 \   
                                   m_AnimationSets->m_Length)   
            m_AnimationSets->m_Length =                       \   
                              Anim->m_RotationKeys[i].m_Time;   
   
          // Skip # keys to follow (should be 4)    
          DataPtr++;   
   
          // Get rotational values    
          float *fPtr = (float*)DataPtr;   
          Anim->m_RotationKeys[i].m_quatKey.w = *fPtr++;   
          Anim->m_RotationKeys[i].m_quatKey.x = *fPtr++;   
          Anim->m_RotationKeys[i].m_quatKey.y = *fPtr++;   
          Anim->m_RotationKeys[i].m_quatKey.z = *fPtr++;   
          DataPtr+=4;   
        }   
        break;   
   
      case 1: // Scaling    
        delete [] Anim->m_ScaleKeys;   
        Anim->m_NumScaleKeys = NumKeys;   
        Anim->m_ScaleKeys = new cAnimationVectorKey[NumKeys];   
        for(i=0;i<NumKeys;i++) {   
          // Get time    
          Anim->m_ScaleKeys[i].m_Time = *DataPtr++;   
          if(Anim->m_ScaleKeys[i].m_Time >                    \   
                                   m_AnimationSets->m_Length)   
            m_AnimationSets->m_Length =                       \   
                                 Anim->m_ScaleKeys[i].m_Time;   
   
          // Skip # keys to follow (should be 3)    
          DataPtr++;   
   
          // Get scale values    
          D3DXVECTOR3 *vecPtr = (D3DXVECTOR3*)DataPtr;   
          Anim->m_ScaleKeys[i].m_vecKey = *vecPtr;   
          DataPtr+=3;   
        }   
        break;   
   
      case 2: // Translation    
        delete [] Anim->m_TranslationKeys;   
        Anim->m_NumTranslationKeys = NumKeys;   
        Anim->m_TranslationKeys = new                         \   
                                cAnimationVectorKey[NumKeys];   
        for(i=0;i<NumKeys;i++) {   
          // Get time    
          Anim->m_TranslationKeys[i].m_Time = *DataPtr++;   
          if(Anim->m_TranslationKeys[i].m_Time >              \   
                                   m_AnimationSets->m_Length)   
            m_AnimationSets->m_Length =                       \   
                           Anim->m_TranslationKeys[i].m_Time;   
   
          // Skip # keys to follow (should be 3)    
          DataPtr++;   
   
          // Get translation values    
          D3DXVECTOR3 *vecPtr = (D3DXVECTOR3*)DataPtr;   
          Anim->m_TranslationKeys[i].m_vecKey = *vecPtr;   
          DataPtr+=3;   
        }   
        break;   
   
      case 4: // Transformation matrix    
        delete [] Anim->m_MatrixKeys;   
        Anim->m_NumMatrixKeys = NumKeys;   
        Anim->m_MatrixKeys = new cAnimationMatrixKey[NumKeys];   
        for(i=0;i<NumKeys;i++) {   
          // Get time    
          Anim->m_MatrixKeys[i].m_Time = *DataPtr++;   
   
          if(Anim->m_MatrixKeys[i].m_Time >                   \   
                                  m_AnimationSets->m_Length)   
            m_AnimationSets->m_Length =                       \   
                               Anim->m_MatrixKeys[i].m_Time;   
   
          // Skip # keys to follow (should be 16)    
          DataPtr++;   
   
          // Get matrix values    
          D3DXMATRIX *mPtr = (D3DXMATRIX *)DataPtr;   
          Anim->m_MatrixKeys[i].m_matKey = *mPtr;   
          DataPtr += 16;   
        }   
        break;   
    }   
  }   
   
  return ParseChildObjects(pDataObj, Depth, Data, Reference);   
}   
   
BOOL cAnimationCollection::Load(char *Filename)   
{   
  // Free a prior loaded collection    
  Free();   
   
  // Parse the file    
  return Parse(Filename);   
}   
   
void cAnimationCollection::Free()   
{   
  m_NumAnimationSets = 0;   
  delete m_AnimationSets; m_AnimationSets = NULL;   
}   
   
void cAnimationCollection::Map(D3DXFRAME_EX *RootFrame)   
{   
  // Go through each animation set    
  cAnimationSet *AnimSet = m_AnimationSets;   
  while(AnimSet != NULL) {   
   
    // Go through each animation object    
    cAnimation *Anim = AnimSet->m_Animations;   
    while(Anim != NULL) {   
   
      // Go through all frames and look for match    
      Anim->m_Bone = RootFrame->Find(Anim->m_Name);   
   
      // Go to next animation object    
      Anim = Anim->m_Next;   
    }   
   
    // Go to next animation set object    
    AnimSet = AnimSet->m_Next;   
  }   
}   
   
void cAnimationCollection::Update(char *AnimationSetName,     \   
                                  DWORD Time, BOOL Loop)   
{   
  cAnimationSet *AnimSet = m_AnimationSets;   
   
  // Look for matching animation set name if used    
  if(AnimationSetName) {   
   
    // Find matching animation set name    
    while(AnimSet != NULL) {   
   
      // Break when match found    
      if(!stricmp(AnimSet->m_Name, AnimationSetName))   
        break;   
   
      // Go to next animation set object    
      AnimSet = AnimSet->m_Next;   
    }   
  }   
   
  // Return no set found    
  if(AnimSet == NULL)   
    return;   
   
  // Bounds time to animation length    
  if(Time > AnimSet->m_Length)   
    Time = (Loop==TRUE)?Time%(AnimSet->m_Length+1):AnimSet->m_Length;   
   
  // Go through each animation    
  cAnimation *Anim = AnimSet->m_Animations;   
  while(Anim) {   
   
    // Only process if it's attached to a bone    
    if(Anim->m_Bone) {   
   
      // Reset transformation    
      D3DXMatrixIdentity(&Anim->m_Bone->TransformationMatrix);   
   
      // Apply various matrices to transformation    
   
      // Scaling    
      if(Anim->m_NumScaleKeys && Anim->m_ScaleKeys) {   
   
        // Loop for matching scale key    
        DWORD Key1 = 0, Key2 = 0;   
        for(DWORD i=0;i<Anim->m_NumScaleKeys;i++) {   
          if(Time >= Anim->m_ScaleKeys[i].m_Time)   
            Key1 = i;   
        }   
   
        // Get 2nd key number    
        Key2 = (Key1>=(Anim->m_NumScaleKeys-1))?Key1:Key1+1;   
   
        // Get difference in keys' times    
        DWORD TimeDiff = Anim->m_ScaleKeys[Key2].m_Time-   
                         Anim->m_ScaleKeys[Key1].m_Time;   
        if(!TimeDiff)   
          TimeDiff = 1;   
   
        // Calculate a scalar value to use    
        float Scalar = (float)(Time - Anim->m_ScaleKeys[Key1].m_Time) / (float)TimeDiff;   
   
        // Calculate interpolated scale values    
        D3DXVECTOR3 vecScale = Anim->m_ScaleKeys[Key2].m_vecKey -    
                               Anim->m_ScaleKeys[Key1].m_vecKey;   
        vecScale *= Scalar;   
        vecScale += Anim->m_ScaleKeys[Key1].m_vecKey;   
   
        // Create scale matrix and combine with transformation    
        D3DXMATRIX matScale;   
        D3DXMatrixScaling(&matScale, vecScale.x, vecScale.y, vecScale.z);   
        Anim->m_Bone->TransformationMatrix *= matScale;   
      }   
   
      // Rotation    
      if(Anim->m_NumRotationKeys && Anim->m_RotationKeys) {   
   
        // Loop for matching rotation key    
        DWORD Key1 = 0, Key2 = 0;   
        for(DWORD i=0;i<Anim->m_NumRotationKeys;i++) {   
          if(Time >= Anim->m_RotationKeys[i].m_Time)   
            Key1 = i;   
        }   
   
        // Get 2nd key number    
        Key2 = (Key1>=(Anim->m_NumRotationKeys-1))?Key1:Key1+1;   
   
        // Get difference in keys' times    
        DWORD TimeDiff = Anim->m_RotationKeys[Key2].m_Time-   
                         Anim->m_RotationKeys[Key1].m_Time;   
        if(!TimeDiff)   
          TimeDiff = 1;   
   
        // Calculate a scalar value to use    
        float Scalar = (float)(Time - Anim->m_RotationKeys[Key1].m_Time) / (float)TimeDiff;   
   
        // slerp rotation values    
        D3DXQUATERNION quatRotation;   
        D3DXQuaternionSlerp(&quatRotation,   
                            &Anim->m_RotationKeys[Key1].m_quatKey,   
                            &Anim->m_RotationKeys[Key2].m_quatKey,   
                            Scalar);   
   
        // Create rotation matrix and combine with transformation    
        D3DXMATRIX matRotation;   
        D3DXMatrixRotationQuaternion(&matRotation, &quatRotation);   
        Anim->m_Bone->TransformationMatrix *= matRotation;   
      }   
   
      // Translation    
      if(Anim->m_NumTranslationKeys && Anim->m_TranslationKeys) {   
   
        // Loop for matching translation key    
        DWORD Key1 = 0, Key2 = 0;   
        for(DWORD i=0;i<Anim->m_NumTranslationKeys;i++) {   
          if(Time >= Anim->m_TranslationKeys[i].m_Time)   
            Key1 = i;   
        }   
   
        // Get 2nd key number    
        Key2 = (Key1>=(Anim->m_NumTranslationKeys-1))?Key1:Key1+1;   
   
        // Get difference in keys' times    
        DWORD TimeDiff = Anim->m_TranslationKeys[Key2].m_Time-   
                         Anim->m_TranslationKeys[Key1].m_Time;   
        if(!TimeDiff)   
          TimeDiff = 1;   
   
        // Calculate a scalar value to use    
        float Scalar = (float)(Time - Anim->m_TranslationKeys[Key1].m_Time) / (float)TimeDiff;   
   
        // Calculate interpolated vector values    
        D3DXVECTOR3 vecPos = Anim->m_TranslationKeys[Key2].m_vecKey -    
                             Anim->m_TranslationKeys[Key1].m_vecKey;   
        vecPos *= Scalar;   
        vecPos += Anim->m_TranslationKeys[Key1].m_vecKey;   
   
        // Create translation matrix and combine with transformation    
        D3DXMATRIX matTranslation;   
        D3DXMatrixTranslation(&matTranslation, vecPos.x, vecPos.y, vecPos.z);   
        Anim->m_Bone->TransformationMatrix *= matTranslation;   
      }   
   
      // Matrix    
      if(Anim->m_NumMatrixKeys && Anim->m_MatrixKeys) {   
        // Loop for matching matrix key    
        DWORD Key1 = 0, Key2 = 0;   
        for(DWORD i=0;i<Anim->m_NumMatrixKeys;i++) {   
          if(Time >= Anim->m_MatrixKeys[i].m_Time)   
            Key1 = i;   
        }   
   
        // Get 2nd key number    
        Key2 = (Key1>=(Anim->m_NumMatrixKeys-1))?Key1:Key1+1;   
   
        // Get difference in keys' times    
        DWORD TimeDiff = Anim->m_MatrixKeys[Key2].m_Time-   
                         Anim->m_MatrixKeys[Key1].m_Time;   
        if(!TimeDiff)   
          TimeDiff = 1;   
   
        // Calculate a scalar value to use    
        float Scalar = (float)(Time - Anim->m_MatrixKeys[Key1].m_Time) / (float)TimeDiff;   
   
        // Calculate interpolated matrix    
        D3DXMATRIX matDiff = Anim->m_MatrixKeys[Key2].m_matKey -    
                             Anim->m_MatrixKeys[Key1].m_matKey;   
        matDiff *= Scalar;   
        matDiff += Anim->m_MatrixKeys[Key1].m_matKey;   
   
        // Combine with transformation    
        Anim->m_Bone->TransformationMatrix *= matDiff;   
      }   
    }   
   
    // Go to next animation    
    Anim = Anim->m_Next;   
  }   
}   
DX进阶书 【内容简介】 本书是通往高级程序设计的桥梁,其中并不涉及初学者的内容,完全从实战出发讲述核心理论和程序设计!这就意味着没有把时间浪费在一些基础的概念,如初始化Direct3D或使用Windows的消息处理上,所以你需要预先了解一些关于Direct3D的相关知识。啊哈!不要立马想到放弃,我所谓的基础知识是很基础的内容,如初始化Direct3D,使用材质和纹理,操作顶点缓冲器。如果你己知道这些,那么就肯定已经做好了学习该书的准备。 -------------------------------------------------------------------------------- 【目录】 第1篇 预备知识 第1章 做好学习本书的准备工作 1.1 安装DirectX SDK 1.2 选择调试或发布库 1.3 设置编译器 1.4 使用本书的功能函数 1.5 更进一步   第2篇 动画基础 第2章 计时动画和运动 2.1 运用计时运动 2.2 在Windows中读取时间 2.3 计时动画 2.4 计时运动 2.5 运行示范程序 第3章 使用.X文件格式 3.1 使用.X模板和数据对象 3.2 访问.X文件 3.3 从.X文档中加载网格模型 3.4 从.X文件中加载框架层次 3.5 从.X文件中加载动画 3.6 从.X文件中加载定制数据 3.7 运行示范程序第3篇 骨骼动画 第4章 绘制骨骼动画 4.1 骨骼动画 4.2 使用骨骼结构和骨骼层次 4.3 使用蒙皮网格模型 4.4 运行示范程序 第5章 关键帧骨骼动画的运用 5.1 使用关键帧骨骼动画集 5.2 动画中的关键点 5.3 4种关键点类型 5.4 从.X文件中读取动画数据 5.5 匹配动画到骨骼上 5.6 更新动画 5.7 从其他途径获取骨骼网格模型数据 5.8 运行示范程序 第6章 混合的骨骼动画 6.1 混合骨骼动画 6.2 组合变换 6.3 增强的骨骼动画对象 6.4 运行示范程序 第7章 偶人动画的实现 7.1 创建偶人角色 7.2 运用刚体物理学 7.3 创建一个偶人动画系统 7.4 运行示范程序第4篇 渐变动画 第8章 渐变动画的运用 第9章 关键帧渐变动画的运用 第10章 混合的渐变动画 第11章 渐变脸部表情动画 第12章 动画中的粒子技术 第13章 服饰模拟和柔体网格模型动画 第14章 动画纹理的使用 附录 附录A 互联网和参考书籍 附录B 配套光盘 -------------------------------------------------------------------------------- 【作者介绍】 Jim Adams:在他9岁,还是一个未成熟的小孩时,强烈的好奇心和丰富的想象力驱使他开始他的编程生涯。20岁以后直到30岁,已是成年人的Jim 依然对本书中所介绍的各种游戏程序设计技术着迷。在他写的书籍和相关程序中,你可以发现Jim 积极地参与了互联网中顶级的DirectX 论坛,网址是Http://www.GameDev.net 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值