Direct-X学习笔记--骨骼动画

C#解析DirectX .x文件:从二进制格式到GPU渲染的完整实践 3D模型文件格式是图形应用开发的基础,其本质是存储顶点、索引、材质等数据的结构化容器。以经典的DirectX .x文件为例,它采用基于模板的分块结构,通过解析其二进制格式,开发者可以深入理解顶点缓冲区、索引缓冲区的构建原理。掌握这一流程不仅有助于处理遗留资产,更能提升对现代图形API数据交互机制的认识。在C#生态中,通过SharpDX结合AssimpNet库进行解析,可以绕过Managed DirectX的兼容性限制,实现高效、可控的数据提取与GPU上传。本文聚焦缠绕顺序处理、材质关联等关键细节,为处理工业 阅读详情

学了几个月DX了,终于到了骨骼动画这一步了,好激动!之前导入过一些静态的模型,还是挺帅的。不过不能动,实在是太遗憾了。今天学习了骨骼动画,终于让偶的模型动起来啦!!!

一.简介

说到动画,其实本人又想起了最早开始写小游戏的时候从网上找的那些关键帧素材,设置一个定时器,或者根据游戏循环,不断切换图片,就形成了动态的效果。不过这样实在是太麻烦了,需要美术一张一张的画图或者用PS调整。到了3D时代,骨骼动画这个神器,可以大大的缩短动画的制作周期。
3D中的动画,就是我们常说的模型动画。一共有三种:
1.关节动画:将网格拆分为多个刚体,按照关键帧插值运算,能够实现复杂的动画效果。但是,模型各部分交接的地方容易出现缝隙。
2.渐变动画:与2D游戏中的关键帧类似,每一帧的所有顶点位置等等都记录下来,效果很好,但是由于记录的数据太多,文件很大,载入很慢,还占地方。
3.骨骼蒙皮动画:这种就是现在最常用的方法,取上两者之精华,去之糟粕。占用空间小,但是表现力还很好。

骨骼蒙皮模型中含有按照一定层次组织起来的骨骼,还含有单一网格模型的蒙皮。骨骼层次仿照关节动画的组织结构将模型组织成一个整体,相邻骨骼之间通过关节相连,通过关键帧确定骨骼位置朝向等信息,然后再动画序列中相邻两个关键帧之间做差值运算,获得完整的动画信息。这样就可以很好的表现出动画,而又不至于占用过大空间。


二.X文件

.X文件,之前也有用过,LoadMeshFromFile。就是简单的把网格载入程序中,读取其中的顶点信息,纹理材质信息,然后调用DX的API将它画出来。不过,这只是普通的网格,其实X文件中还可以包含更加深层次的东东,就是骨骼动画。
这个是微软自带的例子:SkinMesh中的那个人物,自带了骨骼动画。看一下.X文件中记录了什么东东:
AnimationSet 动画的组合,包括一个或者多个Animation。
  Animation 描述一个动画,包含一个或几个AnimationKey
  AnimationKey 动画关键帧,定义具体的动作数据,包括一些列旋转、移动、放缩、矩阵变换。
  ColorRGB 定义RGB对象,包括三个Float的值,分别是R、G、B。
  ColorRGBA 定义RGBA对象。包括四个Float的值,分别是R、G、B、alpha。
  Coords2d 定义纹理坐标向量,包括两个Float值,分别是u、v。
  FloatKeys 定义浮点数组,用来定义动画键数值,包括两个部分:浮点值个数,浮点值列表。
  Material 定义材质信息,可以被应用到一个完整的Mesh对象,也可以应用到其中的一个面。包含:
           1.FaceColor环境光
           2.Power镜面反射的强度
           3.specularcolor镜面反射等等。
  Matrix4X4 定义4X4矩阵,16个浮点数值。
  Mesh 定义个Mesh对象,共有9个部分组成:
1、包含的顶点数
2、顶点列表,一个顶点包含三个浮点值
3、面数
4、面的顶点索引列表,每个面包含三个顶点
5、MeshFaceWraps 结构,暂时无用
6、MeshTextureCoords纹理坐标,可选
7、MeshNormals 法向,可选
8、MeshVertexColors 顶点颜色,默认为白色
9、MeshMaterialList 材质,不提供的话默认为白色。
  MeshFace 面索引,包含两部分:面数,定点索引构成的面数组。
  MeshTextureCoords 定义纹理坐标,包括:纹理坐标的个数,纹理坐标(每个纹理坐标有两个浮点值)。
  MeshMaterialList 定义材质的应用,包括:多少个材质被使用,材质影响面的个数,面索引。
  MeshNormals 定义Mesh的法向量,包括4部分:
1.nNormals法向量的个数=顶点数
2.Normals顶点法向量列表
3.nFaceNormals面的个数
4.FaceNormals面对应的法向量。
  MeshVertexColors  指定顶点的颜色代替原来的材质,包含:顶点数目,颜色索引
  TextureFilename  纹理的名称,字符串类型。
  VertexDuplicationIndices  保留副本,用于精简Mesh的操作,包含:顶点数,原始顶点数,实际顶点数。
  XSkinMeshHeader  描述被导出的SkinMesh相关信息,影响一个顶点的最多变换数目,影响每个面三个顶点的最大变换数目,影响一个顶点的骨骼数。
  TimedFloatKeys 时间值,用于Animaterkey中定义时间间隔。
  Vector 三维向量,三个浮点值。
  SkinWeights 定义骨骼影响权重。包括以下几个部分:骨骼的名字,有多少个权重值,顶点的索引列表等等

三.封装一个容易使用的骨骼动画类

DX这个.X文件也看不太懂,不过,我们也没必要看懂这个,关键还是怎么用。给我们一个带动画的.X文件,我们能够把它读取,并播放出来才是最重要的。这个骨骼动画相关的内容貌似还是比较难,不过好在网上有一些教程,最重要的是DX官方文档给的那个例子,其实已经封装了一个可以使用的骨骼动画类。不过他还需要几个全局函数和全局变量才能读取并绘制出骨骼动画,还是没有彻底封装。所以,我们进一步把这几个函数和全局变量加上DX给的那个类,进行再次封装,写一个简单粗暴的骨骼动画类。只用几步就可以播放骨骼动画。
AllocateHierarchy.h文件(DX官方给出的类):
/*!
 * \file AllocateHierarchy.h
 *
 * \author puppet_master
 * \date 九月 2015
 *
 * \微软SDK自带的关于骨骼动画的类,用于骨骼动画的创建以及绘制更新
 * \注:程序不直接使用该类,而是将此类二次封装后再使用。
 */

#ifndef __ALLOCATEHIERARCHY_H_
#define __ALLOCATEHIERARCHY_H_

//--------------------------------------------------------------------------------------
// Name: struct D3DXFRAME_DERIVED
// Desc: 
//--------------------------------------------------------------------------------------
struct D3DXFRAME_DERIVED : public D3DXFRAME
{
	D3DXMATRIXA16 CombinedTransformationMatrix;
};


//--------------------------------------------------------------------------------------
// Name: struct D3DXMESHCONTAINER_DERIVED
// Desc: Structure derived from D3DXMESHCONTAINER so we can add some app-specific
//       info that will be stored with each mesh
//--------------------------------------------------------------------------------------
struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER
{
	//纹理信息
	LPDIRECT3DTEXTURE9* ppTextures;       //纹理数组  

	//网格信息             
	LPD3DXMESH pOrigMesh;					//原始网格
	LPD3DXATTRIBUTERANGE pAttributeTable;	//属性表
	DWORD NumAttributeGroups;				//属性组数量(子网格数量)
	DWORD NumInfl;							//每个顶点最多受几个骨骼影响
	LPD3DXBUFFER pBoneCombinationBuf;		//骨骼结合缓存
	D3DXMATRIX** ppBoneMatrixPtrs;			//骨骼组合变换矩阵
	D3DXMATRIX* pBoneOffsetMatrices;		//骨骼初始变换矩阵
	DWORD NumPaletteEntries;				//骨骼数量上限
	bool UseSoftwareVP;						//是否使用软件顶点处理
	DWORD iAttributeSW;						// used to denote the split between SW and HW if necessary for non-indexed skinning
};

//--------------------------------------------------------------------------------------
// Name: class CAllocateHierarchy
// Desc: Custom version of ID3DXAllocateHierarchy with custom methods to create
//       frames and meshcontainers.
//用来从.X文件中加载网格以及动画数据
//----------------------------------------
DirectX 11 入门(Tutorials) 很经典的DirectX 11入门,包含框架搭建、各种范例,值得阅读和收藏 立即下载

相关推荐

direct3D动画(用Direct3D写得一个3D动画).

direct3D动画,用Direct3D写得一个3D动画。一个学习Direct3D的好例子

机械臂TCP标定实战:从四点法到六点法的精度跃迁

本文详细解析机械臂TCP标定技术,从基础的四点法到高精度的六点法实现精度跃迁。通过工具坐标系与基坐标系的转换原理,结合实战案例展示六点法如何将装配合格率提升至99.5%,并分享环境控制、操作技巧等提升标定精度的关键要素。

weixin_29038345的博客 893

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月13日-安全配置-准备工作

请遵循本规程将SABRE 3D/3DxT/3D Scimitar系统设置为安全配置,以便能够在电镀单元、APT模块、XMM(或SRD)模块、工厂接口(FI)外壳或中央通道内部及周边区域执行作业p104-p117。在生产过程中暂停调度程序存在一定风险:若待维护模块未离线且在其他模块完成处理前重启调度程序,可能对生产晶圆造成影响。维护人员需特别注意电镀模块内的晶圆状态,并尽可能快速地恢复调度程序。确认待维护模块内无晶圆滞留暂停调度程序并将相应模块设置为离线状态打开模块检修门并关闭安全盖板(槽位)

weixin_46735260的博客 1363

告别‘线束丛林’:手把手拆解车身域控制器(BCM/PEPS/网关)的硬件选型与PCB布局要点

本文深入解析车身域控制器的硬件选型与PCB布局要点,涵盖主控MCU选择、通信接口设计、电源架构优化及EMC设计等关键环节。通过实战案例分享,帮助工程师解决高密度集成带来的电源完整性、热管理和信号隔离挑战,实现更稳定高效的汽车电子系统设计。

weixin_42567279的博客 394

Vivado ChipScope Debugging: Overcoming Common DRC Errors in FPGA Design

本文深入解析Vivado ChipScope调试中常见的DRC错误,特别是AVAL-244和AVAL-245等时钟相关问题,提供实用的Tcl命令解决方案和最佳实践。通过将DRC错误降级为警告的技巧,帮助FPGA设计者高效完成调试流程,同时强调何时应保留DRC检查以确保设计可靠性。

weixin_30335575的博客 416

光学仿真案例(1) 铌酸锂非线性波导仿真模拟 FDTD仿真

在过去几年里,许多集成光子学应用往往需要多个相干可调谐光源,而且从外部激光器引入额外的光输入增加了芯片封装的复杂性,如果使用基于III-V族、氮化硅(SiN)或铌酸锂(LNO)的集成光源又大大增加了制造复杂性和成本。然而,通过非线性谐波相互作用产生的光源不需要额外的制造工艺来产生增益、反馈和外部电路,即可支持许多应用。在下面的案例中,演示了一种基于Luo[1]的铌酸锂波导频率转换集成系统。该案例主要仿真了利用温度调制实现高效相位匹配的铌酸锂纳米光子波导的二次谐波产生。

q895235273的博客 4142

碰撞检测 | 图解视线生成Bresenham算法(附ROS C++/Python/Matlab实现)

Bresenham视线生成是一种高效的算法,用于在二维网格上绘制直线。Bresenham算法可以应用在栅格地图中进行一维碰撞检测,即检查起点和终点间直线是否穿过障碍栅格。本文图解Bresenham碰撞检测的原理,并给出ROS C++/Python/Matlab三种实现加深理解

FRIGIDWINTER的博客 1万+

嵌入式面经篇八——进程&线程

记录一些招聘公司在招聘嵌入式软件岗位时的一些问题,此文为第八篇。进程上文:是指进程由用户态切换到内核态时需要保存用户态时CPU寄存器中的值,进程状态以及堆栈上的内容。即保存当前进程的状态,以便再次执行该进程时,能够恢复切换时的状态,继续执行。进程下文:是指切换到内核态后执行的程序,即进程运行在内核空间的部分。中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。

明天你好的博客 1854

基于YOLOv26的护栏损坏检测系统原理讲解

本文介绍了一种基于YOLOv26深度学习的护栏损坏检测系统。该系统通过车载摄像头或固定监控采集道路护栏图像,利用改进的YOLOv26算法实现高效准确的损坏检测。系统采用分层架构设计,包含数据采集、检测处理、分析评估和应用服务四个层次,能够自动识别变形、断裂、缺失等五种常见损坏类型,并评估损坏严重程度。相比传统人工检测方法,该系统大幅提高了检测效率和准确性,降低了人工成本和安全风险。关键技术包括多尺度特征融合、注意力机制和自适应非极大值抑制等创新设计,使系统在复杂道路环境下仍能保持稳定的检测性能。

一键难忘的博客 327

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: VS中修改解决方案/项目/类的名字
下一篇: Direct-X学习笔记--骨骼动画进阶
puppet_master
puppet_master 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄12年 2695粉丝 161原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值