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的变换。
cocos2d的armature绑定到其它armature骨骼上的bug的更多相关文章
- 把多个JavaScript函数绑定到onload事件处理函数上
为了让函数只在页面加载完毕后才得到执行,我们会把函数绑定到onload事件上: window.onload = userFunction 但如果有两个函数:firstFunction() 和 seco ...
- 使用MethodType函数将方法绑定到类或实例上
在开始正文之前,需要了解下Python的绑定方法(bound method)和非绑定方法. 简单做个测试: 定义一个类,类中由实例方法.静态方法和类方法. class ClassA: def inst ...
- linux 将进程或者线程绑定到指定的cpu上
基本概念 cpu亲和性(affinity) CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,也称为CPU关联性:再简单的点的描述就将指定的进程或线程绑定到相应的 ...
- jQ给下拉框绑定事件,为什么要绑定在框(select标签)上,而不是绑定在选项(option标签)上
这是我在学习锋利的 jquery 书中 5.1.4 的代码时遇到的一个小问题,源代码如下: <head> <style type="text/css"> * ...
- 外部配置属性值是如何被绑定到XxxProperties类属性上的?--SpringBoot源码(五)
注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 SpringBoot是如何实现自动配置的?--SpringBoot源码(四) 温故而知新,我们来简单回顾一下上 ...
- 利刃 MVVMLight 5:绑定在表单验证上的应用
表单验证是MVVM体系中的重要一块.而绑定除了推动 Model-View-ViewModel (MVVM) 模式松散耦合 逻辑.数据 和 UI定义 的关系之外,还为业务数据验证方案提供强大而灵活的支持 ...
- asp.net core mvc中如何把二级域名绑定到特定的控制器上
由于公司的工作安排,一直在研究其他技术,所以一直没时间更新博客,今天终于可以停下手头的事情,写一些新内容了. 应用场景:企业门户网站会根据内容不同,设置不同的板块,如新浪有体育,娱乐频道,等等.有的情 ...
- 获得touch事件,jquery绑定事件监听器,ios设备上打开touch状态以响应focus,active等伪类
2. 默认的监听方式 document.addEventListener('touchstart', function(){ alert('hello'); }, false); 使用jquery时 ...
- 如何在双向绑定的Image控件上绘制自定义标记(wpf)
我们的需求是什么? 答:需要在图片上增加一些自定义标记,例如:2个图片对比时,对相同区域进行高亮. 先上效果图: 设计思路 1.概述 1.通过TargeUpdated事件,重新绘制图片进行替换. 2. ...
随机推荐
- 【Python-2.7】大小写转换函数
字母大小写是编程过程中经常遇到的问题,如下函数可以灵活的进行大小写转换: title():把单词首字母转换为大写: upper():把每个字母转换为大写: lower():把每个字母转换为小写. 示例 ...
- Angular——内置过滤器
基本介绍 在AngularJS中使用过滤器格式化展示数据,在“{{}}”中使用“|”来调用过滤器,使用“:”传递参数. 基本使用 过滤器可以串起来使用,只要用 | 来衔接就行了,可以将上次返回的 ...
- Java 基础入门随笔(7) JavaSE版——面向对象定义、特征:封装、构造函数
面向对象 面向过程:对于面向过程思想,强调的是过程(动作). 面向对象:对于面向对象思想,强调的是对象(实体). 特点: 1,面向对象就是一种常见的思想.符合人们的思考习惯.2,面向对象的出现,将复杂 ...
- Shell基础笔记一
由于工作需要,开始学习Shell编程,都是一些简单的基础知识,现整理收集分享出来,希望对大家有帮助 -------------------------------------------------- ...
- HDU_3172_带权并查集
Virtual Friends Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- POJ_3041_Asteroids
参考自: http://user.qzone.qq.com/289065406/blog/1299322465 解题思路: 把方阵看做一个特殊的二分图(以行列分别作为两个顶点集V1.V2,其中| V1 ...
- Stack frame
http://en.citizendium.org/wiki/Stack_frame In computer science, a stack frame is a memory management ...
- [Algorithm] 10. Reverse Integer
Description Given a 32-bit signed integer, reverse digits of an integer. Example Example 1: Input: 1 ...
- UVA - 208 Firetruck(并查集+dfs)
题目: 给出一个结点d和一个无向图中所有的边,按字典序输出这个无向图中所有从1到d的路径. 思路: 1.看到紫书上的提示,如果不预先判断结点1是否能直接到达结点d,上来就直接dfs搜索的话会超时,于是 ...
- Java垃圾回收简介
Java关键术语 JavaAPI:一系列帮助开发者创建Java应用程序的封装好的库. Java 开发工具包 (JDK):一系列工具帮助开发者创建Java应用程序.JDK包含工具编译.运行.打包.分发和 ...