ozzanimation-基于sse的动作系统

本文介绍了ozzanimation库如何利用SIMD技术提升动画处理效率,包括初始化、动作矩阵的更新、混合及转换到模型空间的过程。在多线程版本中,通过ParallelUpdate实现了角色更新的并行处理,提高性能。关键步骤涉及SamplingJob和LocalToModelJob的使用,以及BlendingJob的混合策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介:

ozzanimation是利用sse也就是用simd单指令多数据的形式来处理animation的动作变化、转换坐标以及ik等的处理方式。可以比传统的直接矩阵转换快。

sample_additive.cc是最简单的例子

 

初始化

OnInitialize做初始化,LoadSkeleton加载骨骼,LoadAnimation加载动画,context_.Resize来确定平移旋转缩放的大小,locals_.resize确定局部空间的数据大小,models_.resize确定模型空间的数据大小,blended_locals_.resize确定局部空间混合的大小。

simd更新动作矩阵

核心在OnUpdate中做动画处理,controller_.Update设置播放动作的比率ratio,通过ozz::animation::SamplingJob来设置动作数据并指定输出到locals_。通过sampling_job.Run来执行动作数据采样,UpdateCacheCursor是更新缓存的指针位置,然后UpdateInterpKeyframes是通过指针位置的索引来获取具体的数值,然后平移和缩放都是通过DecompressFloat3来获取到simd运算后的值,缩放是四元数所以是DecompressQuaternion。

获取到平移缩放旋转的数据后,Interpolates来进行插值,插值也是通过simd来执行的。最终输出给output。

以上都是在SamplingJob中完成的事情。

混合:

然后如果有多个层级混合则执行ozz::animation::BlendingJob::Layer获取层的数据,然后ozz::animation::BlendingJob来混合,在BlendingJob::Run()中

 

首先是BlendLayers,他有两种混合方式,一种是一维的混合,直接执行OZZ_BLEND_1ST_PASS,另一种是多维的OZZ_BLEND_N_PASS。

然后是BlendRestPose,这里是如果累计权重小于阈值,则将静止姿势混合到输出。

然后是Normalize,规格化输出旋转。四元数长度不能为零,因为在混合过程中,四元数的相对长度已固定。平移和缩放已经标准化,因为权重已预先乘以标准化比率。

然后是AddLayers,这里是关注的是每个层是否要添加到混合中,或者删除混合。

最后还得执行ozz::animation::LocalToModelJob来转换到模型空间,

然后显示在OnDisplay通过gl来显示模型或骨骼,shader代码直接写在

 

这些类里面。

相关的蒙皮运算等都是传统的方式。

多线程版本:

sample_multithread.cc中ParallelUpdate是执行更新角色的行为,grain_size是多少个对象并行处理,如果超过数量就通过std::async选择异步的方式std::launch::async,他会在另一个线程执行。ParallelUpdate。

 

然后UpdateCharacter中还是通过simd执行SamplingJob和LocalToModelJob。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值