Direct3D中模拟机械手动作
来源:互联网 发布:总是想起前男友 知乎 编辑:程序博客网 时间:2024/05/17 05:59
人的动作是如何实现的呢?这就要用到分级网格(mesh)的知识了。
所谓分级也属于场景管理的基本知识,就是把不同模型分级管理,比如人的手臂是一级,作为父母级,然后前臂是下一级,手掌又是一级,这样分开,以达到模拟人手动作的效果。如下:
相当于一个机械手,以各个节点为分界,分级。
跟一般的变形(transformation)差不多,只不过世界坐标作为root坐标,由root坐标分为一级一级的节点,这些节点的变形都不是根据世界坐标来转换了,而是以他们各自的父母节点来变形了。主要的原理就那么简单,不要想得太复杂了。
主要还是要看程序,着手实现,不然还是不会。
表示节点的数据结构:
struct BoneFrame{ // 根节点就是世界坐标 D3DXVECTOR3 pos; // 相对于父母的相对位置 float zAngle; // 相对于父母的相对角度. D3DXMATRIX toParentXForm;//转换到父母空间的矩阵 D3DXMATRIX toWorldXForm;//转换到世界的变形矩阵 };
下面设置其初始化位置和角度
for(int i = 1; i < NUM_BONES; ++i) // Ignore root.{ // Describe each bone frame relative to its parent frame. mBones[i].pos = D3DXVECTOR3(2.0f, 0.0f, 0.0f); mBones[i].zAngle = 0.0f;}// Root frame at center of world.mBones[0].pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);mBones[0].zAngle = 0.0f;
定义一个整数,可以通过directx input控制数值变化,然后控制相应的机器关节
int mBoneSelected;
下面看程序的详细注释:
void RobotArmDemo::buildBoneWorldTransforms(){ // 计算当前节点到父母节点的矩阵。只是一个非常简单的循环 // the ith bone into the coordinate system of its parent. D3DXMATRIX R, T; D3DXVECTOR3 p; for(int i = 0; i < NUM_BONES; ++i) { p = mBones[i].pos;//这个是当前节点的位置 D3DXMatrixRotationZ(&R, mBones[i].zAngle);//这个是DirectX API自动生成当前节点的旋转角度 D3DXMatrixTranslation(&T, p.x, p.y, p.z);//然后也是DirectXAPI自动生成当前节点转移的位置矩阵 mBones[i].toParentXForm = R * T;//然后把这两个矩阵合并起来就一步可以转换并旋转到最终想要得到的位置了,这个是本节重点注意的地方!!!就是这样确定各个节点的位置,及其位置关系的。 }
这里值得多解释几句:每个模型都有自己的坐标,自己的模型坐标是以自己为中心的,所以任何模型在自己坐标的位置都是(0,0,0),那么自己在父母的位置是多少就是个相对位置了,比如距离自己父母模型为x轴为2个单位的位置,那么就用转换矩阵把自己转换到离父母模型坐标为2的位置,然后再用同样的办法把父母转换到父母的父母空间坐标中,最后到了root空间,就是世界坐标了。
// 计算每个节点的世界转换矩阵,就是把各个父母以上的矩阵接起来就可以啦。 for(int i = 0; i < NUM_BONES; ++i) { // 世界矩阵是单位对角阵,对角线都是1,其他是零的矩阵。 D3DXMatrixIdentity(&mBones[i].toWorldXForm); // 连接各个父母以上的矩阵,多学算法就觉得这是个很简单的算法,看来算法还是非常有用的。 for(int j = i; j >= 0; --j) { mBones[i].toWorldXForm *= mBones[j].toParentXForm; } }}
控制我们的机械手代码:
if( gDInput->keyDown(DIK_1) )mBoneSelected = 0;//按下按键1,2,3,4分别选择四个不同级别的节点(或叫关节)。if( gDInput->keyDown(DIK_2) )mBoneSelected = 1;if( gDInput->keyDown(DIK_3) )mBoneSelected = 2;if( gDInput->keyDown(DIK_4) )mBoneSelected = 3;if( gDInput->keyDown(DIK_5) )mBoneSelected = 4;
// 按下A或者D坐旋或右旋机械手。if( gDInput->keyDown(DIK_A) ) mBones[mBoneSelected].zAngle += 1.0f * dt;if( gDInput->keyDown(DIK_D) ) mBones[mBoneSelected].zAngle -= 1.0f * dt;// 转的太猛了,过了360度就置零吧,角度0和360在现有的空间中是不变的。if( fabsf(mBones[mBoneSelected].zAngle) >= 2.0f*D3DX_PI) mBones[mBoneSelected].zAngle = 0.0f;
- Direct3D中模拟机械手动作
- 在LR中怎么模拟下载动作?
- 关于怎么在LR中模拟下载的动作
- DirectX学习笔记(六):Direct3D中模拟实现光照下的物体绘制
- c# 模拟键盘动作
- VR模拟真人动作
- Direct3D中绘制
- Direct3D中使用纹理
- Qt中使用Direct3D
- 超强机械手
- jquery模拟鼠标点击动作
- 外挂编程-动作模拟技术
- jquery模拟下拉框动作
- monkeyrunner 模拟测试用户动作
- 添加模拟power key 动作
- jquery模拟鼠标点击动作
- JAVA 模拟多用户提交动作
- Python-模拟鼠标键盘动作
- FFMPEG处理音频时间戳的主要逻辑
- 0009算法笔记——【动态规划】动态规划与斐波那契数列问题,最短路径问题
- renren
- git签出远程分支问题解决
- unity实现折线图功能
- Direct3D中模拟机械手动作
- redhat5.0下安装linux-2.6.28内核步骤
- 阅读一款3D引擎的方法备忘
- Archlinux启动黑屏,无法进入终端的解决办法
- php魔术方法汇总之__construct(),__destruct()
- sicily 1034.Forest
- C++中的类模板
- 关于数学和程序
- 有关css3的target伪类的问题