流逝的时光
总有一天我们都会离去 email: zzxhang@gmail.com
posts - 21,comments - 111,trackbacks - 0

换装系统是每款网游中都必须实现的东西,原理说白了也很简单,就是把装备(通常是Mesh)挂接到人物的骨骼上,根据角色需要可选择不同的装备替换,Ogre中的骨骼动画系统中可以直接把一个Object挂接到骨骼上,但问题是Ogre中一个Object只能挂到一块骨骼上去,对于一些覆盖面广的装备(如衣服)则不那么适用,所以Ogre中不能通过这种直接的方式实现换装,目前一般用以下几种方法实现.

一.对于可选装备比较少的游戏,用这种方式实现非常简单实用:一开始做人物模型的时候就把所有可能的装备都跟人物一起导出为一个模型(所有装备的骨骼权重都已调好),然后就可以通过SubEntity::setVisible函数设置需要的装备可见,不需要的装备则隐去,这样就实现了换装的效果,这种方式对于装备少的游戏比较适用,需要做的事情也很少,但如果你有成百上千的装备要替换,这显然不是个好办法.

二.如果你装备很多,那你就该考虑这种方法了:首先你必须把装备导出为一个独立的模型,这个模型还必须带有骨骼,然后你就可以在代码中通过调用Entity::shareSkeletonInstanceWith(Entity* entity)函数与人物共享骨骼,这里有几个需要注意的地方,首先调用shareSkeletonInstanceWith函数要求共享骨骼的两个Entity有相同的Skeleton,否则会抛出异常,也就是每个装备都必须有一副跟主角一样的骨骼,我们当然不可能要求美工为每个装备模型都做一副骨骼,所以只能在程序中手动设置装备的Skeleton跟主角的一样,Ogre中提供了这个函数:void  Mesh::_notifySkeleton(SkeletonPtr& pSkel)可完成此操作,之后就可以调用shareSkeletonInstanceWith函数了.然后第二点需要注意的是装备顶点权重问题,我们必须具体指定此装备跟哪几根骨骼有关,以及权重的分布,由于装备拥有跟主角一样的一套完整骨骼,因此不能影响到此装备骨骼的权重必须设为0,否则装备会散架,设置顶点权重可以调用void SubMesh::addBoneAssignment(const VertexBoneAssignment& vertBoneAssign)函数.

似乎还有种方法是通过删除人物带的想更换的装备SubMesh的iterator,之后再换上新的装备SubMesh并重建SubEntityList来实现换装的方法,但个人不推荐这种方法,太暴力了,而且频繁的删除重建操作也会造成效率低下.

通过共享骨骼的方式实现,下面的盒子跟人物肩膀处的两跟骨骼有关




2010.6.1 补充:本人对阅读本文引起的任何直接或间接的后果概不负责,觉得不对可以不看,任何疑问请自行解决,也别找我要代码,因为我也没有了
posted on 2008-07-23 16:39 清風 阅读(7070) 评论(16)  编辑 收藏 引用 所属分类: 图形

FeedBack:
# re: Ogre中实现换装系统
2008-07-23 19:12 | LOGOS
原来shareSkeletonInstanceWith可以这么用
单一装备套上整个骨架,然后把无关骨头权重设置为0
cool  回复  更多评论
  
# re: Ogre中实现换装系统
2008-07-23 19:34 | 键盘的咏叹调
MMO中的换装还是很简单的。
真正复杂的是像舞蹈类游戏中的换装。  回复  更多评论
  
# re: Ogre中实现换装系统
2008-08-13 17:08 | se
最后一步设置骨骼权重,能不能详细一点。最好有代码。谢谢!  回复  更多评论
  
# re: Ogre中实现换装系统[未登录]
2008-08-14 23:21 | 清风徐来
@se
我觉得上面我已经把方法说得很详细了,为什么还要代码呢?这种代码要来除了增加你复制粘贴的操作外毫无价值,你应该自己动手实现,设置顶点权重用
void SubMesh::addBoneAssignment(const VertexBoneAssignment& vertBoneAssign),把模型的每个SubMesh的顶点的骨骼权重分布都设置为只跟你需要关联的那几块骨骼有关,关于此函数的具体用法请查阅Ogre文档  回复  更多评论
  
# re: Ogre中实现换装系统
2008-09-01 09:21 | syerboxer
作者您好,我是一个初学者,能否请您把这个DEMO的代码和用到的模型发给我一份学习啊,多谢.
syerboxer@163.com  回复  更多评论
  
# re: Ogre中实现换装系统
2010-01-07 17:49 | Mars2020
Entity* ninja = mSceneMgr->createEntity("ninja", "ninja.mesh");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ninja);

Entity* robot = mSceneMgr->createEntity("robot", "robot.mesh");
SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100.0f, 0.0f, 0.0f), Quaternion(Radian(Math::PI / 2), Vector3::UNIT_Y));
node->attachObject(robot);

robot->getMesh()->_notifySkeleton(const_cast<SkeletonPtr&>(ninja->getMesh()->getSkeleton()));
robot->shareSkeletonInstanceWith(ninja);

VertexBoneAssignment vba;
size_t vertexCount, i;
Bone* bone;
SubMesh* submesh;
Skeleton::BoneIterator it = ninja->getSkeleton()->getBoneIterator();
while (it.hasMoreElements())
{
bone = it.getNext();
if (bone->getName() == "Joint1")
{
Mesh::SubMeshIterator smit = robot->getMesh()->getSubMeshIterator();
while (smit.hasMoreElements())
{
submesh = smit.getNext();
vertexCount = submesh->vertexData->vertexCount;
for (i = 0; i < vertexCount; i++)
{
vba.vertexIndex = i;
vba.boneIndex = bone->getHandle();
vba.weight = 1.0f;
submesh->addBoneAssignment(vba);
}
//submesh->_compileBoneAssignments();
}
break;
}
}
robot散架。不太明白如何设置骨骼的权重,即使我遍历所有顶点,把每根骨头对此顶点的权重都设置为0,依然散架。望赐教。  回复  更多评论
  
# re: Ogre中实现换装系统[未登录]
2010-01-09 00:00 | 清风
@Mars2020
这篇文章是我很早之前写的了,细节我也已记不清,你上面给的代码我没看出什么问题,不过为什么你把所有顶点weight都设为1呢?一般来说,骨骼动画模型会散掉就是因为顶点权重或者骨骼矩阵不对  回复  更多评论
  
# re: Ogre中实现换装系统
2010-05-18 05:58 | yezi
这篇文章误人子弟,存在明显前后矛盾  回复  更多评论
  
# re: Ogre中实现换装系统[未登录]
2010-05-18 14:18 | 清风
@yezi
请不吝指教,详细点,谢谢  回复  更多评论
  
# re: Ogre中实现换装系统
2010-06-01 11:41 | ZealKing
@清风
我觉得他写的似乎不对

我尝试用你的方法来做换装系统

但是_notifySkeleton 只会通知mesh的骨骼变化 不会使entity的骨骼mSkeletonInstance 发生变化

那么下来的做法 shareSkeletonInstanceWith 就无法正确的使骨骼共享  回复  更多评论
  
# re: Ogre中实现换装系统
2010-06-01 15:55 | ZealKing
再来回一贴

楼主你似乎写错了..

装备也需要有1个骨骼 不然不能共享骨骼 有兴趣的话去看下代码

我说错了的话 就指点下..
  回复  更多评论
  
# re: Ogre中实现换装系统[未登录]
2010-06-01 19:58 | 清风
@ZealKing
请认真看文章  回复  更多评论
  
# re: Ogre中实现换装系统[未登录]
2010-09-09 14:47 | alex
@Mars2020
注掉
if (bone->getName() == "Joint1")


break;
robot 就不会散架了  回复  更多评论
  
# re: Ogre中实现换装系统
2010-12-22 15:16 | 诺水寒
有兴趣的可以讨论讨论。。QQ 279899294
欢迎高手来指导。  回复  更多评论
  
# re: Ogre中实现换装系统
2011-04-01 11:07 | #
权重纯属扯淡  回复  更多评论
  
# re: Ogre中实现换装系统
2011-06-04 16:54 | wtf?
_notifySkeleton纯属扯淡。
This is only here for unusual situation where you want to manually set up a Skeleton. Best to let OGRE deal with this, don't call it yourself unless you really know what you're doing.  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理