zoukankan      html  css  js  c++  java
  • 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的变换。

  • 相关阅读:
    HDU1251 统计难题
    字典树模板
    HDU5536 Chip Factory(01字典树)
    函数的返回值
    函数的使用原则
    文件修改
    函数
    文件内指针移动
    文件操作模式
    字符编码
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7041343.html
Copyright © 2011-2022 走看看