笔者介绍:姜雪伟。IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术具体解释》电子工业出版社等。

Avatar换装系统又称为纸娃娃系统。在游戏开发中是使用很广泛的技术。特别是在MMOARPG或者是MMORPG等网络游戏中,玩家创建的3D角色都具有Avatar换装功能,在游戏开发中常常须要对角色更换装备。比方角色在战斗过程中获取到新的盔甲要穿戴在身上或者新的武器要更换等等。

要实现该技术所使用的引擎都必须具有支持Avatar换装系统的骨骼挂节点,比方市面上的Unity引擎,UE4引擎等都提供了这样的挂接骨骼方法。获取到骨骼挂节点后,能够直接将武器挂接到须要绑定的骨骼上。实现的效果例如以下图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvanh3MTY3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

场景中的三个角色採用了Avatar换装技术。它们採用的是同一套骨架,将须要更换的各个Mesh模型都挂接到相应的骨架上,从而形成了Avatar换装系统。而本书介绍的Cocos2d-x引擎也不例外,该引擎也提供了支持Avatar技术的功能,实现该功能的类是AttachNode。

以下介绍实现挂接结点的步骤,不论是挂接Mesh还是在角色身上挂接武器都须要依据骨骼挂接。这就要用到AttachNode类实现的功能。实现的函数例如以下所看到的:

AttachNode* AttachNode::create(Bone3D* attachBone)
{
auto attachnode = new (std::nothrow) AttachNode();
attachnode->_attachBone = attachBone;
attachnode->autorelease();
return attachnode;
}

首先是创建须要挂接的骨骼,骨骼动画是须要矩阵支撑的。骨骼动画它在世界坐标系中的变换都须要转换到世界变换矩阵,这些实现过程也须要引擎提供,以下把接口的函数给读者展演示样例如以下:

Mat4 AttachNode::getWorldToNodeTransform() const
{
static Mat4 mat;
mat.setIdentity();
auto parent = getParent();
if (parent)
{
mat=parent->getWorldToNodeTransform() * _attachBone->getWorldMat() * Node::getNodeToParentTransform();
}
else
{
mat=_attachBone->getWorldMat() * Node::getNodeToParentTransform();
}
return mat;
}

getWorldToNodeTransform函数的实现原理是把模型挂接到骨骼上,该骨骼是须要挂接模型的父结点,父结点运动会带动所绑的模型运动,从而保证挂接到骨骼结点的武器能够与骨骼动画一致。这个实现过程是与矩阵相关的,通过案例把实现的代码片段给读者展演示样例如以下:

//Girl.c3b里保存了女角色所运行动画的全部零件(姑且这么叫吧)包含衣服,鞋子等等
std::string fileName = "Sprite3DTest/Girl.c3b";
auto sprite = Sprite3D::create(fileName);
sprite->setScale(4);
sprite->setRotation3D(Vec3(0,0,0));
addChild(sprite);
sprite->setPosition( Vec2( p.x, p.y-60) );
auto animation = Animation3D::create(fileName);
if (animation)
{
auto animate = Animate3D::create(animation);
sprite->runAction(RepeatForever::create(animate));
}
_sprite = sprite; _curSkin[SkinType::UPPER_BODY] = "Girl_UpperBody01";
_curSkin[SkinType::PANTS] = "Girl_LowerBody01";
_curSkin[SkinType::SHOES] = "Girl_Shoes01";
_curSkin[SkinType::HAIR] = "Girl_Hair01";
_curSkin[SkinType::FACE] = "Girl_Face01";
_curSkin[SkinType::HAND] = "Girl_Hand01";
_curSkin[SkinType::GLASSES] = "";

上面的代码片段是针对一个模型进行换装操作,首先实现的是对换装的部位进行初始化操作。以下開始遍历获取到骨骼动画挂接的数量,对于挂接的模型,假设是多个通过显示和隐藏将其显示出来。

以下的代码片段函数是ApplySkin,函数内容片段例如以下所看到的:

//函数getMeshCount获取动画全部零件数目  
    for (ssize_t i = 0; i < _sprite->getMeshCount(); i++) {  
        auto mesh = _sprite->getMeshByIndex(static_cast<int>(i));  
        bool isVisible = false;  
        for (auto& it : _curSkin) {  
            if (mesh->getName() == it.second)  
            {  
                isVisible = true;  
                break;  
            }  
        }  
        //通过索引来获取零件并设置可见性  
        _sprite->getMeshByIndex(static_cast<int>(i))->setVisible(isVisible);  
    }  

以下给大家展示应用案例代码例如以下所看到的:

std::string str = _curSkin[SkinType::HAIR];  
    if (str == "Girl_Hair01")  
        _curSkin[SkinType::HAIR] = "Girl_Hair02";  
    else  
        _curSkin[SkinType::HAIR] = "Girl_Hair01"; 

同一时候要调用ApplySkin函数就能够完毕换装的要求。实现效果例如以下图:

场景中的角色裤子、头发、鞋子都发生了改变。完毕换装。

关于换装。笔者在CSDN学院出版一个免费的视频讲座《游戏Avatar换装系统》。供开发人员參考。

Cocos2d-x 3.x 图形学渲染系列十一的更多相关文章

  1. Cocos2d-x 3.x 图形学渲染系列十五

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家.特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  2. SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案

    原文:SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Serv ...

  3. java基础解析系列(十一)---equals、==和hashcode方法

    java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...

  4. 新书《Cocos2dx 3.x 3D图形学渲染技术讲解》问世

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  5. struts2官方 中文教程 系列十一:使用XML进行表单验证

    在本教程中,我们将讨论如何使用Struts 2的XML验证方法来验证表单字段中用户的输入.在前面的教程中,我们讨论了在Action类中使用validate方法验证用户的输入.使用单独的XML验证文件让 ...

  6. 爬虫系列(十一) 用requests和xpath爬取豆瓣电影评论

    这篇文章,我们继续利用 requests 和 xpath 爬取豆瓣电影的短评,下面还是先贴上效果图: 1.网页分析 (1)翻页 我们还是使用 Chrome 浏览器打开豆瓣电影中某一部电影的评论进行分析 ...

  7. JBoss 系列十一:JBoss Cluster Framework Demo 介绍

    内容概要 JBoss Cluster Framework Demo包括JGruops.JBossCache.Infinispan,我们在随后的系列中会使用和运行这些示例来说明JGroups.JBoss ...

  8. BootStrap 智能表单系列 十一 级联下拉的支持

    像省市县选择的这种,但凡是个人肯定都见过,实现方式有很多种 1.有在第一级选择的时候去加载或者从本地对象中拿第一级对应的数据源显示到列表中,第二级以此类推 2.也有将所有的项都加载到select中,然 ...

  9. Alamofire源码解读系列(十一)之多表单(MultipartFormData)

    本篇讲解跟上传数据相关的多表单 前言 我相信应该有不少的开发者不明白多表单是怎么一回事,然而事实上,多表单确实很简单.试想一下,如果有多个不同类型的文件(png/txt/mp3/pdf等等)需要上传给 ...

随机推荐

  1. Storm概念学习系列之storm的可靠性

    这个概念,对于理解storm很有必要. 1.worker进程死掉 worker是真实存在的.可以jps查看. 正是因为有了storm的可靠性,所以storm会重新启动一个新的worker进程. 2.s ...

  2. log4j2异步日志解读(二)AsyncLogger

    前文已经讲了log4j2的AsyncAppender的实现[log4j2异步日志解读(一)AsyncAppender],今天我们看看AsyncLogger的实现. 看了这个图,应该很清楚AsyncLo ...

  3. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

  4. Farseer.net轻量级开源框架 中级篇:执行SQL语句

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 事务的使用 下一篇:Farseer.net轻量级开源框架 中级篇: DbFacto ...

  5. 6.11 将分割数据转换为多值IN列表

    问题 已经有了分隔数据,想要将其转换为WHERE子句IN列表中的项目.考虑下面的字符串: 7654,7698,7782,7788 要将该字符串用在WHERE子句中,但是下面的SQL语句是错误的,因为E ...

  6. 15年第六届蓝桥杯第七题_(string)

    手链样式 小明有3颗红珊瑚,4颗白珊瑚,5颗黄玛瑙.他想用它们串成一圈作为手链,送给女朋友.现在小明想知道:如果考虑手链可以随意转动或翻转,一共可以有多少不同的组合样式呢? 请你提交该整数.不要填写任 ...

  7. CSS 类名的问题

    以下以数字开头的 CSS 类名不会生效: .1st{ color: red; } 一个合法的 CSS 类名必需以下面其中之一作为开头: 下划线 _ 短横线 - 字母 a-z 然后紧跟其他 _,- 数字 ...

  8. 让浏览器不再显示 https 页面中的 http 请求警报<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" ...

  9. c# Dictionary 扩展方法

    主要用于接口请求,数据转换 #region Dictionary 扩展方法 public static string getString(this Dictionary<string, stri ...

  10. mysql服务无法启动(1067错误)时数据备份的经验

    mysql服务无法启动(1067错误)时数据备份的经验 背景 方法 背景 在已安装MySQL5.5的情况下,再次安装 MySQL5.7时,因为MySQL5.7是压缩文件安装的方式,复制MySQL5.5 ...