在cocos2dx中,rmature的骨骼上能够绑定另外的armature,在我的项目中使用了该功能来完毕骑乘功能,可是在使用过程发现了例如以下的bug,特写在这里做一下记录。

</span>

首先说说cocos2dx的代码。在cocos2dx的骨骼的update函数中有例如以下代码用于骨骼的矩阵更新。

    if (_boneTransformDirty)
{
if (_dataVersion >= VERSION_COMBINED)
{
TransformHelp::nodeConcat(*_tweenData, *_boneData);
_tweenData->scaleX -= 1;
_tweenData->scaleY -= 1;
}
<span style="white-space:pre"> </span>//(1)
_worldInfo->copy(_tweenData); _worldInfo->x = _tweenData->x + _position.x;
_worldInfo->y = _tweenData->y + _position.y;
_worldInfo->scaleX = _tweenData->scaleX * _scaleX;
_worldInfo->scaleY = _tweenData->scaleY * _scaleY;
_worldInfo->skewX = _tweenData->skewX + _skewX + CC_DEGREES_TO_RADIANS(_rotationZ_X);
_worldInfo->skewY = _tweenData->skewY + _skewY - CC_DEGREES_TO_RADIANS(_rotationZ_Y);
<span style="white-space:pre"> </span>//(2)
if(_parentBone)
{
applyParentTransform(_parentBone);
}
else
{
if (_armatureParentBone) //(3)
{
applyParentTransform(_armatureParentBone);
}
}
<span style="white-space:pre"> </span>//(4)
TransformHelp::nodeToMatrix(*_worldInfo, _worldTransform);
<span style="white-space:pre"> </span>//(5)
if (_armatureParentBone)
{
_worldTransform = TransformConcat(_worldTransform, _armature->getNodeToParentTransform());
}
}

在上面的代码中,

1、程序首先计算了bone本身的变换信息,

2、然后在第二步。假设骨骼有父骨骼,则乘以父骨骼的变换信息。假设没有父骨骼可是该骨骼所在的armature有父骨骼(即armayure被作为了其它armature的bone的display。这时就先乘以armature的父骨骼的变换信息。

3、第四步将worldinfo转换为矩阵。

4、第五步计算再将bone所在的armature的变换信息应用于变换矩阵上,得到终于的骨骼的矩阵信息。

问题就出在上面代码标号为3的地方,我们都知道矩阵变换是不满足交换定律的(当然少数情况除外)。

可是骨骼矩阵之间的关系应该例如以下:

parentArmature-------armatureParentBone------------armature------------bone

或者是armature-----------。。。。------parentBone-----bone  中间省略一些parentBone。

因此在上面的代码中。假设不包括armatureParentBone,那么矩阵变换关系是bone * parentBone *...*parentBone,结果正确。即没有armature作为bone的render。

可是假设有armature作为bone的render,那么关系是bone*armatureParentBone*armature,那么在矩阵变换的顺序上就出现了问题。

因此我将代码做了一些改动例如以下:

  //if it is a armature display render node, apply transform to armature.
BaseData worldInfo;
if (!_parentBone && _armatureParentBone)
{ //bone * armature
TransformHelp::nodeToMatrix(*_worldInfo, _worldTransform);
_worldTransform = TransformConcat( _armature->getNodeToParentTransform(), _worldTransform);
TransformHelp::matrixToNode(_worldTransform, worldInfo);
} else {
worldInfo = *_worldInfo;
} BaseData cache = *_worldInfo;
*_worldInfo = worldInfo;
//apply to parent bone.
if(_parentBone) //bone * parentbone
{
applyParentTransform(_parentBone);
} else { // * armatureParentBone
if (_armatureParentBone)
{
applyParentTransform(_armatureParentBone);
}
}
TransformHelp::nodeToMatrix(*_worldInfo, _worldTransform);

上面的代码中,假设bone没有parentBone而且有armatureParentBone。则先乘以armature的矩阵。

假设没有 则直接乘以parentBone的变换。

最后假设有armatureparentBone。还的乘以parenBone的变换。

最新文章

  1. SQL Server 常用内置函数(built-in)持续整理
  2. Spring类型转换 ConversionSerivce Convertor
  3. 如何基于纯GDI实现alpha通道的矢量和文字绘制
  4. 翻译:AKKA笔记 - 介绍Actors
  5. 深入理解计算机中的 csapp.h和csapp.c
  6. JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码
  7. Encapsulation and Requiring Files
  8. Creating, Stopping, Re-Starting and Deleting a Timer in Oracle Forms
  9. 150 Opening ASCII mode data connection. FTP连接的PASV和PORT方式
  10. HTML5和CSS3的学习视频
  11. 微信公众平台Token验证失败的解决办法
  12. LayoutInflater
  13. Win7无法设置背景图片的快速解决办法
  14. 质因数分解的rho以及miller-rabin
  15. System.IO
  16. 调用一个系统命令,并读取它的输出值(使用QProcess.readAll)
  17. 一个关于Python正则表达式的快速使用手册
  18. hdu4417
  19. 动态请求数据并放入bootstrap轮播图
  20. 一个好看的php验证码源码

热门文章

  1. pyrthon 简单爬虫实现
  2. HDU_3182_Hamburger Magi_状态压缩dp
  3. Vue指令3:v-for
  4. Vue渲染原理
  5. layer弹出层无法关闭问题
  6. springmvc视图解析
  7. SpringMVC中@Controller和@RequestMapping用法和其他常用注解(转)
  8. 恶补数论(二) Baby-Step-Giant-Step 大步小步求离散模对数
  9. [bzoj3106][cqoi2013][棋盘游戏] (对抗搜索+博弈论)
  10. nyoj 911 Registration system(map)