cocos2d的armature绑定到其他armature骨骼上的bug

在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的变换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值