已阅读5页,还剩47页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
/zh_cn/中国科学技术大学大学生研究计划结题报告课题名称三维人体建模与运动仿真姓 名学 院信息科学与技术学院系 别电子工程与信息科学系(eeis)专 业(未分配)年 级07级学 号pb07210297指导老师导师单位中国科学院 自动化研究所2010年 9月 30日目录1.引 言22.概述22.1 directx简介22.2 三维人体模型的获取22.3 基于directx三维人体运动仿真的原理简介22.4 mfc应用程序框架上的三维模型编辑软件的构建23.人体建模与运动仿真实现原理23.1三维人体模型关节运动控制原理23.1.1三维人体模型结构剖析23.1.2变换矩阵作用原理蒙皮网格模型中变换矩阵的作用原理标准网格模型中变换矩阵的作用原理23.2 .x文件中的模型及其读取方法23.2.1 .x文件的结构说明23.2.2 .x文件的解析方法概述23.3 多种模式下的模型运动控制23.3.1 模型运动控制原理23.3.2 三种类型变换的作用效果和施加变换的次序规则23.3.3 44顶点变换矩阵的生成与解析24.运动仿真控制应用程序设计24.1编程环境的配置24.2 程序设计框图24.3 创建内嵌direct3d的mfc应用程序项目24.4主要的数据结构及功能函数24.5程序用户界面(gui)简介25.自我拓展之xscenestudio梦想平台26.结论27.致谢2三维人体建模与运动仿真基于directx sdk*中国科学技术大学 信息科学与技术学院 电子工程与信息科学系,安徽省合肥市(230027)摘 要: 本文给出了一种三维人体模型的形态编辑及运动仿真控制的方法。该方法采用directx sdk函数库,在mfc应用程序框架上,通过程序设计,实现对.x文件中存储的三维模型的读取,以及通过键盘控制,对具有规范部位层次结构的模型进行尺寸、角度、方位上的编辑操作。同时本文特别讲述骨骼动画的原理和4x4特定变换矩阵的剖析问题。关键词:剖析.x文件结合mfc与direct3d骨骼动画4x4变换矩阵剖析中图分类号:1. 引 言近年来,三维仿真技术被广泛的应用。尤其在娱乐多媒体领域,从由来已久的3d游戏到气势恢宏倍受青睐的3d电影阿凡达(afatar),再到由此掀起的当今的3d热潮,无不展现出3d的巨大魅力。而在工程研究领域,3d仿真同样得到了广泛的运用,从城市规划的模拟视图,到机械设计中的运动仿真,3d都起到了重要的辅助的作用。然而,在三维设计中,商业领域,有3ds max、maya两大软件;在工程运用上,有autocad、solid works等专业建模工具。它们分别都有各自的设计标准和文件格式定义,在需要通过外部接口控制某一特定模型时,便遇到软件接口以及通用性的问题,在信息处理领域尤为如此。微软公司(microsoft)的directx在解决这一问题上起到重要的作用,由其定义的.x文件能够存储三维模型信息,而directx sdk程序开发库或opengl开源函数库中的相关函数允许我们通过c+语言的程序设计,对.x文件中的模型做一定程度上的编辑。在某些信息处理领域已经可以满足需求。所以深入研究三维模型的建模规则,熟练掌握directx的使用方法,实现对三维模型的灵活编辑控制,尤其将direct3d与同用的mfc应用程序框架相结合,可以使得3d仿真技术在信息处理领域的运用变得更加方便。当然,目前在使用这两类函数库进行模型编辑的运用中,大多为直接替换整个作用在模型某一部位的变换矩阵,而不是对模型的尺度、角度及方位分别进行控制。本文介绍的方法可以实现对特定规则生成的综合变换矩阵的反解析,从而获取上述三方面变换的矩阵,通过将原变换矩阵与新添的控制变换矩阵的各自分别组合后相乘,得到最终变换矩阵,可以达到对模型的精确控制。2. 概述2.1 directx简介directx是微软推出的一套基于windows系统的多媒体应用程式接口apis函式。在开发中,directx分为两个部分,一个是运行库,通过directx编译出来的程式必须要有运行库的支持;另外一个是开发库,也就是常说的sdk,这部分是在编译directx程序中是必需的。图1 direct3d 与其他系统组件之间的关系示意图从功能角度,directx是一种图形应用程序接口(api),简单的说它是一个辅助软件,一个提高系统性能的加速软件。direct意为直接,x代表多样性,组合起来就是一个具有某种共性的组件的集合,这个共性就是直接,微软定义它为“硬件设备无关性”。directx 又是图形及媒体加速接口,只有安装了它,系统中软件才能比较直接的利用硬件加速资源(高速访问硬件),目前该软件最高版本为directx 11.0。directx包含如下组件:directx graphics(包含directdraw & direct3d)、directsound、directplay、direct3d、directinput、directsetup、autoplay等。表1 directx成员及其作用directx成员作用简述directx graphics集成了以前的directdraw 和direct3d技术。directdraw主要负责2d加速,以实现对显卡内存和系统内存的直接操作;direct3d主要提供三维绘图硬件接口,它是开发三维directx游戏的基础。directinput主要支持输入服务(包括鼠标、键盘、游戏杆等),同时支持输出设备。directplay主要提供多人网络游戏的通信、组织功能。directsetup主要提供自动安装directx组件的api功能。directmusic主要支持midi音乐合成和播放功能。directsound主要提供音频捕捉、回放、音效处理、硬件加速、直接设备访问等功能。directshow为windows平台上处理各种格式的媒体文件的回放、音视频采集等高性能要求的多媒体应用,提供了完整的解决方案。directx media objectsdirectshow filter 的简化模型,提供更方便的流数据处理方案。总之,directx的主要好处有两个:为软件开发者提供与硬件的无关性;为硬件开发提供策略。本文所介绍的三维人体建模与运动仿真主要使用其中的direct3d组件。2.2 三维人体模型的获取微软公司(microsoft)为directx定义的.x文件具有存储三维模型的作用,direct3d的库函数中也具备一定的三维建模功能。然而在精细建模以及使用、操作便捷程度方面,directx尚未能与专业的三维建模软件,如3ds max、maya等,相匹敌。好在微软公司等为这些大型三维建模软件研发了模型格式转换插件,使得用户可以在3ds max等常用三维建模软件中设计优质的三维模型,然后利用第三方插件,将建好的模型导出到.x文件中,如pandadirectxmaxexporter_x86_6.2010.71.0就是用于将3ds max建模软件生成的.max文件转换为.x文件的插件之一。值得特别说明的是,由于对模型的形态编辑与控制时基于对作用在模型上的变换矩阵的编辑实现的,故而所建立的模型必须按照严格的设计规则,尤其是各个部位间的链接关系和层次关系,它们将直接关系到模型是否能得到正常、合理的控制。具体的建模规则由下文“三维人体模型的结构分析部分”介绍。2.3 基于directx三维人体运动仿真的原理简介所谓运动仿真,初步地说,可以看作是让一个人体模型做出真实人体能够做出的运动状态;高级地说,还需嵌入一些重力、机械动力学等物理因素到其中,使之更贴切地模拟真实世界中人体的运动。当然前者是后者的基础,有了对模型的灵活控制技术,才能够使之应对于不同的力学条件,更趋于真实地做运动仿真。在实现效果上,如果可以做到让模型做出人们所期望的动作,那么运动便可以是一系列动作的按时序的组合形成的一套动画,因此如果达到可以任意控制模型动作的目的,那么运动仿真的初步实现问题就基本突破了。三维模型由点、线、面按照特定的规则组合而成。两点确定一条线段,各条线段通过公共顶点连接成模型网格。其中常见的三个顶点确定一张三角平面,按这三点的某一种“绕序”确定该张平面的法向量,逆其法向量观察平面可见,顺其法向量观察平面则不可见。众多三角平面的拼接,围成一个三维、立体的模型外壳,通过为三角面配置不同的材质,为顶点确定不同的纹理,得到一个具有特色的仿真模型。.x文件对模型的存储不仅有确定模型的顶点信息、平面信息、材质信息,还具有用于控制顶点位置的变换矩阵。归属于某一模型部位的顶点组成一个集合,一个集合对应一组变换矩阵。通过对变换矩阵的解析、重建,便可以改变相应顶点的位置,对应的模型部位便在空间位置上做出改变,整体上看,便像是模型做出了某一个动作一般。如上所述,一个模型部位对应一个顶点集合,一个顶点集合对应一组变换矩阵,而变换矩阵作用在顶点上时是对集合中所有的顶点做同样的变换,从而相应的模型部位以一个整体在空间中做出相应的变化。换言之,用.x文件存储的三维模型中,对模型的编辑精细程度只能停留在模型建立过程中确定的最小单元上。例如,在模型建立中,如果头部被当作一个整体后,作为人体的一个单元,与其他身体部位连接构成整个人体,存储在.x文件里,那么构成头部的各个顶点组成一个顶点集合,这个集合对应一组变换矩阵。在模型编辑与控制过程中,对应于头部,我们只能够做到使之点头扭头等以整个头部为控制单元的动作,而不能够使之皱眉头、扮笑脸、转眼珠之类的动作;要实现这些目的,只能通过将建模的单元细化到能表现这些特征的程度,比如将眼珠作为一个部位存储,那么通过单独改变与之相应的变换矩阵,使得眼珠的方位相对于眼眶发生变化,便可以实现“转眼珠”的效果了。2.4 mfc应用程序框架上的三维模型编辑软件的构建mfc应用程序框架是工程以及信息处理领域专业应用型程序编写所基于的主要程序框架。 由此框架编写的应用程序具有较强的通用性,其特殊而强大的程序架构更有利于工程中其他功能的添加,使得相关应用得以拓展。然而directx中direct3d应用程序的开发,以游戏编程领域基于win32的应用程序为主,结合mfc应用程序框架的direct3d应用程序的开发并不多见,所以熟练掌握mfc与direct3d的结合方法至关重要。在应用程序中要实现对三维模型的编辑以及运动仿真控制功能,首先要解决模型读取的问题;其次是根据模型控制原理,实现相应的模型控制算法;最后完成模型控制的人机交互界面。3. 人体建模与运动仿真实现原理3.1三维人体模型关节运动控制原理结合真实人体运动的特点可以清楚地知道,模型中的关节运动主要是各部位绕着彼此间连接处的关节点的旋转运动,在单个关节的运动过程中要保证模型的整体性,则要确保与之连接的上一个关节和下一个关节仍然保持原有的连接关系,即一个关节的运动,势必影响其他与之相关的关节的变化,形象的说,这种变换带来的影响是传递的。而在模型的简单编辑中,对模型的操作综合了对关节的尺度、角度及方位等三方面的变换处理。为了能够模拟的人体达到多样化,对模型某关节的尺度、位置做细微的调整也是必不可少的。比如,当我们只想要一个女性模型的上手臂细一些,而保持其臂长及其他部位的形状,那么我们需要对手臂在垂直于手臂方向上的尺度分量做缩减,在手臂方向上的尺度分量保持不变;并且在这个问题上,对上臂的编辑所带来的影响不期望被传递,一面影响模型的其他部位。又如,当我们发现一个模型整条手臂的比例都很协调很美观,然而它相对于身体的其他部位显得小了一些,那么我们是期望可以对整个手臂做一个比例缩放,使之与其他的关节在尺度上协调起来。如此又是连接,又有独立,又是整体的,那么 模型关节的运动到底是如何实现的呢?首先来了解一下人体模型各个关节的连接关系。3.1.1三维人体模型结构剖析根据真实人体结构,我们知道当我们举起下手臂时,与之连接的手掌是一起被举起来的,而当我们举起同样与下手臂连接的上手臂时,则是手掌和下手臂都一起连带着被举起;当我们扭动脖子时,与之连接的头部便随之转动一定角度,而当我们转动与同样与脖子连接的脊椎时,则脖子和头部都将随之转动一定角度。似乎作用在某一个关节上的控制都向下传递给了与之相连接的关节,同时接收到简介控制的关节又将控制信息传递给与它连接的下一个关节,直到底层的关节。由此两例可以看出,人体结构具有特殊而严格的连接关系,这种连接关系影响着机体运动的方式。结合真实人体结构,我们可以给出图2所示的人体模型及其连接关系示意图:图2三维人体模型结构及连接关系示意图如图所示,箭头方向显示了作用的传递方向,由盆骨出发,首先连接的是底下的第一根脊椎骨(暂且称之为脊椎0);脊椎0连接了脊椎1和左右两只大腿;大腿连接小腿,再到脚掌,再往脚趾;而脊椎1则往上连接脊椎2,再到脊椎3,然后是脖子;此时脖子连接着头部和左右锁骨;锁骨连接上臂,再到下手臂,然后是手掌,再是手指。其层次关系可由如下图3表示出来:图3三维人体模型关节层析结构图从而,层次结构图中上层关节的运动,则带动与之有连接关系的下层关节的运动。这便体现了人体关节运动的关联特性。常言道“牵一发而动全身”,那是因为被弄疼了做出的夸张反应,而此处的“动盆骨则动全身”,则是我们的身体结构所决定的,否则我们的骨架就要脱臼了。3.1.2变换矩阵作用原理常见三维模型有标准网格模型和蒙皮网格模型。其中标准网格模型只是单纯地以每一个关节部位为单元,存储对应的所有的顶点、相应的材质、纹理信息,以及一组变换矩阵;因此在这种网格模型中,修改变换矩阵所带来的影响是针对一个部位所有的顶点,并且作用的程度是完全一样的。而在蒙皮网格模型中,采用了另外一种存储方式,其中规定了一系列的骨骼,每个骨骼对应整个人体模型中一组特定的顶点,比如手掌骨骼对应模型中手掌上的一系列顶点;同样的,相应于标准网模型中的顶点集合,在蒙皮网格中顶点也按照归属的骨骼的不同而被分配到不同的顶点集合中。稍有不同的是,标准网格中的顶点只能绝对地属于某一特定部位,从而归属于某一特定的集合;而蒙皮网格中的顶点则可以归属于多个与之相关的骨骼,如上臂和下手臂之间连接处的顶点就同时归属于两个骨骼,从而这些连接处的顶点就受到多重变换矩阵的控制。由此观之,在蒙皮网格与标准网格模型中变换矩阵作用方式是所有区别的,下文分别说明之。首先介绍蒙皮网格中模型的存储方式和变换矩阵作用原理。蒙皮网格模型中变换矩阵的作用原理1、蒙皮网格模型的存储方式蒙皮网格模型在建立过程中便如绘画一般将模型以一个整体的形式构建起来,得到一个完全静态的,不具备受控能力的完整的人体模型。随后才分块定义不同的骨骼,相当于将一个模型根据所需的精细程度,按部位的不同分割开,然后通过变换矩阵an将各个骨骼移动到世界坐标系的中心处,并确保其中与上层关节的连接点与原点重合。于是在世界坐标系的中心,我们得到一组零散的人体骨骼。在重新显示完整的人体模型时,再次通过变换矩阵bn将各个骨骼还原到原来的位置上。当矩阵bn为矩阵an的逆矩阵时,模型可以完全还原到原来的模样,当矩阵bn有别于矩阵an的逆矩阵时,便得到有别于原始模型的新模型。所以在蒙皮网格模型的存储过程中,原始模型上的所有的顶点被原样记录下来,其次是各个骨骼对应的变换矩阵an,然后是将骨骼还原到原始位置或近似原始位置的矩阵bn。2、蒙皮网格模型的变换矩阵作用原理1图4蒙皮网格模型的变换矩阵作用原理讲解图一如图4所示,左上角顶端的坐标系为世界坐标系。模型上肢的网格分为上臂、前和手掌3个部分。逐次在上臂、前臂和手掌的mesh内部选定骨骼,形成图中的3条骨骼。其中,从连接关系上,骨骼1是骨骼2的父骨骼,骨骼2是骨骼3的父骨骼。角色网格的每一个顶点都有一个局部坐标,这些顶点局部坐标构成.x文件的mesh对象的数据。在角色网格中相继点击鼠标,为角色网格设置一系列的骨骼。鼠标的首次点击位置就是该骨骼的首关节点,尾关节点由再次点击鼠标选定子骨骼时确定,尾关节点则是子骨骼的首关节点。在每一条骨骼上建立一个骨骼坐标系。由于骨骼坐标系会随着骨骼的运动而运动,骨骼上的皮肤顶点的骨骼坐标在骨骼的运动过程中保持不变。图5蒙皮网格模型的变换矩阵作用原理讲解图二如图5中的点p,在骨骼2的坐标系下的坐标保持不变。由于任意两个父子骨骼的坐标系,一定存在一个坐标变换矩阵aframe,使得子骨骼蒙皮上顶点的骨骼坐标xchild 与该顶点在父骨骼坐标系中的坐标xfather满足如下关系式xfather = xchild*aframe,矩阵aframe 称为子骨骼的骨骼矩阵。如果将根骨骼(层次关系中处于最上层的那块骨骼)的父骨骼坐标系定义为世界坐标系(包含网格顶点坐标的frame所在的坐标系实际就是所谓的局部坐标系),那么,每个骨骼都有一个骨骼矩阵,折叠矩阵就是在.x文件中看到的一系列具有层次关系的frame对象中的变换矩阵。利用骨骼矩阵,可计算出骨骼蒙皮顶点所在骨骼坐标系下的坐标和世界坐标。图6蒙皮网格模型的变换矩阵作用原理讲解图三其中,矩阵“(anan-1amam+1)-1 ”称为骨骼的权重矩阵,是从局部坐标系所在的框架开始遍历到该骨骼,通过各层的骨骼矩阵左乘,然后求逆计算出来的。骨骼的权重矩阵就是在.x文件中各个骨骼的skin weights对象中的偏移矩阵,用来反响求出顶点在所属骨骼的坐标系下的坐标。现在烤炉骨骼绕关节点的旋转。如图5 所示,骨骼2绕关节点2抬起,即骨骼2绕关节点2轴线的一个旋转变换。旋转后,骨骼2的骨骼矩阵(即相对于父骨骼1的坐标系)发生改变,而其他子骨骼的骨骼矩阵维持不变。由此看出,应用反应父子相对关系的骨骼矩阵来存储骨骼动画的运动变化,需要较少的数据更新。在.x文件中,骨骼在某一帧时刻的animation key矩阵对象就是这些骨骼矩阵。此时,通过骨骼矩阵自定向下进行乘法累积,可获得旋转后的各个骨骼的世界坐标变换矩阵。设旋转后的骨骼2世界坐标变换矩阵为w2,顶点旋转后的世界坐标xworld_new和骨骼坐标xframe_new满足关系式xworld_new = xframe_new*w2,由于顶点相对于它的骨骼坐标系的坐标在旋转过程中保持不变,从而xframe_new = xframe_0,因此有xworld_new = xframe_0*w2。顶点坐在骨骼的权重矩阵为h,顶点最初始的mesh局部坐标为x0。根据权重矩阵的定义,有xframe_0 = x0*h。从而xworld_new = xframe_0*w2 = x0*h*w2,这说明旋转后的顶点世界坐标等于顶点最初始状态下的局部坐标与权重矩阵以及所在骨骼的世界坐标变换矩阵的乘积。通常,关节点附近的网格顶点可以收到多个骨骼的控制。如图7的点p图7蒙皮网格模型的变换矩阵作用原理讲解图四当模型伸手取物时,骨骼2和骨骼3均会同时绕着各自的关节点抬起,此时关节点3附近的顶点p,会随着前臂的骨骼2和手掌的骨骼3的运动而运动。一次,考虑顶点受到多个骨骼影响的情形,顶点运动后的坐标还要与该顶点的权重值想成。顶点的权重由3d建模软件在绘图阶段确定下来,并保存在.x文件的各个骨骼skinweights对象的weights数组中。假定顶点p受骨骼2影响的权重值为,受骨骼3影响的权重值为,骨骼2运动后计算出的顶点p的局部坐标为xlocal_2,骨骼3运动后计算出的顶点p的局部坐标为xlocal_3,那么顶点p最终的坐标应该为xlocal_2+xlocal_3,其中+ = 1。更一般地,一个顶点所有受骨骼影响的权重值之和为1。标准网格模型中变换矩阵的作用原理1、标准网格模型的存储方式标准网格模型的建立过程更像是在制作一台机器,首先我们需要制作构成机器的各个零部件,即人体模型的各个关节,然后再将这些关节拼装起来。每个关节都将被建立在世界坐标系的中心位置,并且,依据该关节与其他关节的连接关系,确保与上层关节的连接点与原点重合。由于关节模型的建立并不考虑所需建立的人体模型的尺度问题,所以关节模型中顶点的最大坐标值不超过1.0,即这些关节都被建立在由(1,1,1)、(1,1,-1)、(1,-1,1)、(1,-1,-1) 、(-1,1,1) 、(-1,1,-1) 、(-1,-1,1) 、(-1,-1,-1)八个顶点链接构成的以原点(0,0,0)为中心,边长为2的立方体内。在构建完整的人体模型时,首先依据所要创建的人体模型的尺度特征,对各个关节分别作一次比例变换an;其次再利用由旋转变换和平移变换组合成的变换矩阵bn分别将它们迁移到世界坐标系中的不同的部位,拼接到一起得到人体模型的样子。所以在标准网格模型的存储过程中,各个关节模型上的各个顶点被原样记录下来,其次是比例变换an,再次是用于拼接的变换矩阵bn。2、标准网格模型的变换矩阵作用原理类比蒙皮网格模型变换矩阵作用的原理,只需将蒙皮网格模型中开始的分解模型那一块省去,然后将标准网格模型的比例变换、旋转变换及平移变换综合在一起类比蒙皮网格模型变换中的拼接,就得到了标准网格模型变换矩阵的作用方式了。此处不再赘述。3.2 .x文件中的模型及其读取方法x文件则是由microsoft为directx量身定制的一种用于存储数据的文件格式类型,其文件扩展名为.x。direct3d中也使用了这种文件格式来存储3d模型的各个信息,如网格数据,纹理数据,动画关键帧数据等。以下从结构和解析方法两方面对.x文件做一个简单介绍。3.2.1 .x文件的结构说明理解.x文件的结构有助于了解.x文件中包含有哪些数据,更有助于理解direct3d的库函数可能是怎么读取、解析.x文件的,甚至在知道.x文件的结构之后,我们可以明白如何去扩展它的功能,让其作用尽可能的得到发挥。从文件整体结构上.x文件分为文件头、数据模板定义和数据对象三个方面。1、.x文件头.x文件头包含文件的类型标识符、文件版本、数据记录格式以及数据中浮点数值的位数等信息。如“xof 0303txt 0032”,表示directx 3.3版本的,以文本格式记录数据,浮点数值为32位的.x文件。2、数据模板定义.x文件中的数据模板用于定义.x文件中数据对象的布局。它由“template”关键字、模板名称、一个guid(globally unique identification number 全局唯一标识号)以及数据变量的定义几个部分组成。2对其理解可以类比c/c+中结构体数据类型的定义,当然还要结合一点编译原理中正则表达式的思想,因为.x文件数据模板是允许嵌套定义的。最具代表性的是directx 标准模板中的“frame”模板,它允许嵌套所有其他的模板。这就意味着在定义模板时,若包含有另一个模板,那么被包含模板所定义的数据对象就可以嵌入到外层模板所定义的数据对象当中去。依据模板是否嵌套定义,嵌套的原则如何,模板分为普通模板和嵌套模板,其中嵌套模板又分为封闭式、开放式和受限式三种。重点说明一下模板的全局唯一标识号(guid):guid是一个用于唯一标识模板的编号。当读取一个.x文件到程序中时,只会访问到每个模板的guids而不是模板的名称。模板的名称只是在.x文件的数据对象定义中时起到模板类型的代称的作用。因此当解析.x文件时,我们是通过这些定义的模板的guid来识别模板的类型,从而依模板的不同用不同的方式来读取模板中的数据信息。特别介绍一下directx标准模板:directx .x标准模板由microsoft公司定义并打包到sdk里。其中direct3d相关的模板可用来包含网格模型的所有相关数据,所以这些标准模板是相当实用的。以下着重讲解与本文相关的四个关键模板,“frame”、“mesh”、“frametransformmatrix”以及“skinweights”的定义:frametemplate frame .用于定义框架容器,可用来装载mesh对象,也可以包含子框架。在骨骼动画中可以装载一块或一系列骨骼(如手臂),(表示骨骼时)可以没有mesh对象。通常包括两部分:mesh对象。转换矩阵,本地转换矩阵,初始化最初动作状态。meshtemplate mesh dword nvertices; array vector verticesnvertices; dword nfaces; array meshface facesnfaces; .用于定义一个mesh对象。通常会有9个部分组成:包含的顶点数顶点列表,一个顶点包含三个浮点值面数面的顶点索引列表,每个面包含三个顶点meshfacewraps 结构,暂时无用meshtexturecoords 纹理坐标,可选meshnormals 法向,可选meshvertexcolors 顶点颜色,默认为白色meshmateriallist 材质,不提供的话默认为白色frametransformmatrixtemplate frametransformmatrix matrix4x4 framematrix;用于定义框架的本地转换矩阵,是一个4x4矩阵(matrix4x4类型),共16个浮点数据(注意这里的4x4矩阵是行主的)。skinweightstemplate skinweights string transformnodename; dword nweights; array dword vertexindicesnweights; array float weightsnweights; matrix4x4 matrixoffset;用于定义骨骼影响权重。包括以下几个部分:骨骼的名字有多少个权重值顶点的索引列表相对应的影响顶点索引列表本地转换矩阵,转换到骨骼空间3、数据对象数据对象是.x文件中,按照上述模板规定的数据组织形式所定义的一系列被具体化的数据信息。 由上文标准网格模型和蒙皮网格模型的结构解析中可知,在.x文件中不同的模型对应有不同的数据信息来存储模型的所有信息。蒙皮网格模型的数据对象结构如图8所示;标准网格模型的数据对象结构如图9所示:信息科学与技术学院 电子工程与信息科学系52(eeis)图8蒙皮网格模型对应的.x文件中数据对象的结构图9标准网格模型对应的.x文件中数据对象的结构(注:其中的框架层次的包含关系体现在框架分布的里外层次中。)由上图可知蒙皮网格模型中只具备一组网格数据,骨骼信息被包含在网格数据所在的子框架中,而骨骼的连接及层次关系则由另一个框架中以相应骨骼名称命名的子框架间的嵌套关系体现出来。而标准网格模型中对应一个关节便有一个套完整的网格数据,并且这些数据又分别被封装在不同的子框架中,不同的关节间的连接及层次关系则由用于封装的子框架之间的嵌套关系来体现。3.2.2 .x文件的解析方法概述将.x文件中的模型读取的过程辨识.x文件的解析过程,大致分为以下步骤:1、定义一个框架容器或直接用direct3d sdk中的d3dxframe结构体,定义一个网格容器或直接用direct3d sdk中的d3dxmeshcontainer。本文介绍的解析方法中分别以d3dxframe和d3dxmeshcontainer为基类,按需拓展其原有的功能,定义专用的框架容器xssd3dxframe_ex和网格容器xssd3dxmeshcontainer_ex。2其中xssd3dxframe的定义如下:/ declare an extended version of d3dxframe/ that contains a constructor and destructor/ as well as a combined transformation matrixtypedef struct xssd3dxframe_ex : public d3dxframed3dxmatrix matcombined;/ combined matrixd3dxmatrix matoriginal;/ original transformation from .xd3dxmatrix matnewfeature;/ new transformation for configuring the dummyd3dxmatrix matnewcontrol;/ new transformation for controlling the dummyd3dxmatrix matnewseparate;/ new transformation for specifying the dummy d3dxmatrix matfeaturet;/ translation transformation to configure the dummyd3dxmatrix matfeaturer;/ rotation transformation to configure the dummyd3dxmatrix matfeatures;/ scaling transformation to configure the dummyd3dxmatrix matcontrolt;/ translation transformation to control the dummyd3dxmatrix matcontrolr;/ rotation transformation to control the dummyd3dxmatrix matcontrols;/ scaling transformation to control the dummyd3dxmatrix matseparates;/ to store separate scaling transformation to configure or control the dummyd3dxmatrix matseparater;/ to store separate rotate transformation to configure or control the dummyd3dxmatrix matseparatet;/ to store separate translate transformation to configure or control the dummy xssd3dxframe_ex * pframeparent;dword nframedepth;dword nrangeindex;xssd3dxframe_ex();xssd3dxframe_ex();/ function to scan hierarchy for matching frame namexssd3dxframe_ex *find(const char *framename);/ function to scan hierarchy for matching frame rangeindexxssd3dxframe_ex * findbyrangeindex(dword ntherangeindex);/ reset transformation matrices to recent configvoid resettorecentconfig();/ reset transformation matrices to recent feature onlyvoid resettorecentfeature();/ reset transformation matrices to recent feature and configurationvoid resettorecent();/ reset transformation matrices to original configvoid resettooriginalconfig();/ reset transformation matrices to original feature onlyvoid resettooriginalfeature();/ reset transformation matrices to original feature and configurationvoid resettooriginal();/ count the number of frames in the x filevoid count(dword *num);bool setnewtransform(dword nnummatrix, dword * pnmatrixindex, d3dxmatrix * prootmatrix, dword ndummyconfigtype = xssdummyconfig_both);bool applynewfeature(dword nnummatrix, d3dxmatrix * prootmatrix, dword ndummyconfigtype = xssdummyconfig_both);bool downloadtransform(dword nnummatrix, dword * pnmatrixindex, d3dxmatrix * prootmatrix, dword ndummyconfigtype = xssdummyconfig_both);bool downloadstate(dword nnummatrix, d3dxmatrix * prootmatrix, dword ndummyconfigtype = xssdummyconfig_both);xssd3dxframe_ex, *lpxssd3dxframe_ex;从xssd3dxframe_ex的定义中可以看到,我们为框架容器添加了用于查找的索引信息、表现框架层次的深度信息、记录与其他框架连接关系的指针变量以及一系列用于控制模型的变换矩阵。功能函数上添加有统计框架数量,查找特定框架,更新变换信息,设置变换信息和导出变换信息等。xssd3dxmeshcontainer_ex的定义如下:/ declare an extended version of d3dxmeshcontainer/ that contains a constructor and destructor/ as well as an array of textures, a mesh object/ that contains the generated skin mesh, and/ matrices that map to the frame hierarchys and/ for updating bones.typedef struct xssd3dxmeshcontainer_ex : public d3dxmeshcontaineridirect3dtexture9*ptextures;id3dxmesh*pskinmesh;xssd3dxframe_ex*ppackcellframe;boolbifselected;dwordnmeshtype;dwordnmeshrangeindex;d3dxmatrix*ppframematrices;d3dxmatrix*pbonematrices;xssd3dxmeshcontainer_ex();xssd3dxmeshcontainer_ex();/ find the mesh by namexssd3dxmeshcontainer_ex *find(char *meshname);/ find the mesh by meshindexxssd3dxmeshcontainer_ex *findbyindex(dword nmeshindextoseek);/ count the number of meshes in the x filevoid count(dword *num);xssd3dxmeshcontainer_ex, *lpxssd3dxmeshcontainer_ex;从xssd3dxmeshcontainer_ex的定义中可以看到,我们为网格容器添加了用于查找网格的索引信息、区别网格类型的标识信息、一个指向包含该网格的框架的指针以及一组指向网格纹理信息的指针。功能函数方面添加有统计网格数量,查找特定网格等。2、定义一个.x文件解析器,完成所需的解析任务。本文介绍的解析方法中所使用的解析器cxinternalparser定义如下:/ declare an internal .x file parser class for loading meshes and framesclass cxinternalparserpublic:/ information passed from calling functionidirect3ddevice9 *m_pd3ddevice;char *m_ptexturepath;dword m_newfvf;dword m_loadflags;/ flags for which data to load/ 1 = mesh, 2 = frames, 3= bothdword m_flags;/ hierarchies used during loadingxssd3dxmeshcontainer_ex *m_prootmesh;xssd3dxframe_ex *m_prootframe;dword m_nnumframecount;dword m_nnummeshcount;protected:/ function called for every template foundbool parseobject(id3dxfiledata *pdataobj,id3dxfiledata *pparentdataobj,dword depth,void *data, bool reference);/ function called to enumerate child templatesbool parsechildobjects(id3dxfiledata *pdataobj,dword depth, void *data,bool forcereference = false);public:/ constructor and destructorcxinternalparser();cxinternalparser();/ function to start parsing an .x filebool parse(char *filename, void *data = null);/ functions to help retrieve template informationconst guid *getobjectguid(id3dxfiledata *pdataobj);char *getobjectname(id3dxfiledata *pdataobj);void *getobjectdata(id3dxfiledata *pdataobj, dword *size);cxinternalparser在解析.x文件时,首先定义一个用于识别.x文件中数据类型的id3dxfileenumobject类型的枚举对象pdxenum,由pdxenum统计.x文件中id3dxfiledata类型数据对象的个数;然后调用parseobject()和parsechildobject()功能函数依次解析每一个数据对象。在对数据对象的解析过程中,首先由getobjectguid()功能函数获取数据对象的guid,此处的guid正是.x文件开始处的模板定义中所说的全局唯一标识号(guid:globally unique identification number);然后根据标识号区分出所解析的数据对象由哪一种模板定义,从而将各数据对象分门别类,与此同时通过getobjectname()和getobjectdata()功能函数将数据对象中的信息导出并记录到不同的数据容器里。当然,在解析数据对象的同时,根据应用的需求应将框架容器与网格容器中的框架索引、网格索引、层次关系等填充清楚。3.3 多种模式下的模型运动控制对三维
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 信息时代背景下的教师管理课件
- 班主任工作范文四年级班级工作计划
- 宾馆装修合同范本(5篇)
- 【政治】历久弥新的思想理念课件-+2024-2025学年统编版道德与法治七年级下册
- 小红书翡翠玉石文玩行业营销通案【互联网】【通案】
- 离婚协议书简单起草,只写房子和孩子分割
- 合同示范文本 住建部
- 《金融危机下的》课件
- 《电力变压器习题》课件
- 《脑出血诊治进展》课件
- 计量经济学练习题
- 第七单元测试卷-2024-2025学年语文四年级上册(统编版)
- 2024年商用密码应用安全性评估从业人员考核试题库-中(多选题)
- 探索心理学的奥秘智慧树知到期末考试答案章节答案2024年北京大学
- 北京市西城区2023-2024学年六年级上学期期末英语试题
- “德能勤绩廉”考核测评表
- 化学反应工程(第三版)第七章-流化床反应器
- PPT模板中华餐饮美食烤鱼宣传PPT课件
- 含氮有机化合物-胺、酰胺、尿素、丙二酰脲、胍、磺胺、吡咯、吡啶和嘧啶的结构及化学性质熟悉
- 电动车项目合作计划书范文模板
- 双柱基础暗梁的计算书
评论
0/150
提交评论