新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     >>计算机科学论坛<<     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 使用.x文件模型(3) 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5592 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 使用.x文件模型(3) 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 使用.x文件模型(3)

    通过四元数实现模型旋转

    早在1843年,William Roman Hamilton爵士就已经发明了作为复数扩展的四元数(quaternion),但是直到1985年才有一个叫Ken ShoeMake的人在SIGGRAPH(Special Interest Group on Computer Graphics,美国计算机协会的图形专业组)把四元数引入计算机图形处理领域。

    四元数将三维空间中旋转的概念扩展到四维空间,这对于表示和处理3D中点的旋转很有用。四元数还可以用于以下地方:

    (1)骨骼动画(skeletal animation)

    (2)反向动力学动画(inverse cinimatic)

    (3)3D物理学

    在游戏中可以使用四元数来取代旋转矩阵,它可用于描述3D空间中绕任意轴的任意旋转。使用四元数来代替旋转矩阵具有以下优点:

    (1)四元数占用的空间比矩阵少。

    (2)一些操作在视觉上会显得更为平滑,比如可以在两个四元数之间做插值运算。

    Direct3D扩展实用库函数D3DXQuaternionRotationYawPitchRoll()提供了将三个欧拉角转换为一个四元数的功能,该函数声明如下:

    Builds a quaternion with the given yaw, pitch, and roll.

    D3DXQUATERNION * D3DXQuaternionRotationYawPitchRoll(  D3DXQUATERNION * pOut,  FLOAT Yaw,  FLOAT Pitch,  FLOAT Roll);
    Parameters
    pOut
    [in, out] Pointer to the D3DXQUATERNION structure that is the result of the operation.
    Yaw
    [in] Yaw around the y-axis, in radians.
    Pitch
    [in] Pitch around the x-axis, in radians.
    Roll
    [in] Roll around the z-axis, in radians.
    Return Values
    Pointer to a D3DXQUATERNION structure with the specified yaw, pitch, and roll.

    Remarks
    The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXQuaternionRotationYawPitchRoll function can be used as a parameter for another function.

    Use D3DXQuaternionNormalize for any quaternion input that is not already normalized.

    由于Direct3D变换引擎需要用矩阵来执行旋转,所以需要将四元数转换为矩阵格式。Direct3D扩展实用库函数D3DXMatrixRotationQuaternion()提供了将四元数转换成矩阵的功能,该函数声明如下:

    Builds a rotation matrix from a quaternion.

    D3DXMATRIX * D3DXMatrixRotationQuaternion(  D3DXMATRIX * pOut,  CONST D3DXQUATERNION * pQ);
    Parameters
    pOut
    [in, out] Pointer to the D3DXMATRIX structure that is the result of the operation.
    pQ
    [in] Pointer to the source D3DXQUATERNION structure.
    Return Values
    Pointer to a D3DXMATRIX structure built from the source quaternion.

    Remarks
    The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXMatrixRotationQuaternion function can be used as a parameter for another function.

    For information about how to calculate quaternion values from a direction vector ( x, y, z ) and an angle of rotation, see D3DXQUATERNION.

    该示例程序同样可以通过键盘控制飞机模型的位置和姿态,控制方式和上一个示例程序完全相同,但实现代码却简洁得多,主要改动代码如下:

    void setup_world_matrix(){ static long  previous_time = 0; static float elapsed_time  = 0.0f;
     elapsed_time  = (timeGetTime() - previous_time) / 1000.0f; previous_time = timeGetTime();
     float angle_around_right = 0.0f, angle_around_up = 0.0f, angle_around_look = 0.0f;
     if(g_keys['D']) angle_around_look  -= 3 * elapsed_time; if(g_keys['A']) angle_around_look  += 3 * elapsed_time; if(g_keys['S']) angle_around_right -= 3 * elapsed_time; if(g_keys['W']) angle_around_right += 3 * elapsed_time; if(g_keys['Q']) angle_around_up    -= 3 * elapsed_time; if(g_keys['E']) angle_around_up    += 3 * elapsed_time; 
     // now, calculate ratation matrix.
     D3DXQUATERNION quat; D3DXMATRIX mat_rotation;
     D3DXQuaternionRotationYawPitchRoll(&quat, angle_around_up, angle_around_right, angle_around_look); D3DXMatrixRotationQuaternion(&mat_rotation, &quat); D3DXMatrixMultiply(&g_mat_world, &mat_rotation, &g_mat_world);
     // get look vector
     D3DXVECTOR3 look; 
     look.x = g_mat_world._31; look.y = g_mat_world._32; look.z = g_mat_world._33;
     // move model forward or backward
     if(g_keys['F']) {  g_mat_world._41 += 30 * elapsed_time * look.x;  g_mat_world._42 += 30 * elapsed_time * look.y;  g_mat_world._43 += 30 * elapsed_time * look.z; }
     if(g_keys['V']) {  g_mat_world._41 -= 30 * elapsed_time * look.x;  g_mat_world._42 -= 30 * elapsed_time * look.y;  g_mat_world._43 -= 30 * elapsed_time * look.z; }
     g_device->SetTransform(D3DTS_WORLD, &g_mat_world);}
    在该示例程序中,通过用户输入,每一帧都对飞机模型进行重新定位,不断改变飞机模型在空间中的位置或姿态,如果每两帧间的时间间隔足够小,则感到飞机模型位置或姿态的变换是连续的,也就形成了连续的动画,实际上这就是三维动画的基本原理,通过不断改变场景中各物体的位置和姿态使各物体运动起来。为了保证动画的连续性,帧速率要达到25帧/秒以上。

    注意:模型的旋转是绕自身坐标轴的旋转,而不是绕世界坐标系的3个坐标轴旋转,而且在旋转模型时其自身坐标轴也在不断变化。

    [B][URL=http://www.cppblog.com/Files/changingnow/StateControlUseQuat.rar]下载示例工程[/URL][/B]


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2009/6/1 14:10:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/4/28 2:17:57

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    54.688ms