4 Sample_CelShading:主要是多维纹理的应用
关键代码
Entity *ent = mSceneMgr->createEntity("Head", "ogrehead.mesh");
ent->setMaterialName("Examples/CelShading");
mSceneMgr->getRootSceneNode()->attachObject(ent);
SubEntity* sub;
sub = ent->getSubEntity(0); // eyes
sub->setCustomParameter(SP_SHININESS, Vector4(35, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Vector4(1, 0.3, 0.3, 1));
sub->setCustomParameter(SP_SPECULAR, Vector4(1, 0.6, 0.6, 1));
sub = ent->getSubEntity(1); // skin
sub->setCustomParameter(SP_SHININESS, Vector4(10, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Vector4(0, 0.5, 0, 1));
sub->setCustomParameter(SP_SPECULAR, Vector4(0.3, 0.5, 0.3, 1));
sub = ent->getSubEntity(2); // earring
sub->setCustomParameter(SP_SHININESS, Vector4(25, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Vector4(1, 1, 0, 1));
sub->setCustomParameter(SP_SPECULAR, Vector4(1, 1, 0.7, 1));
sub = ent->getSubEntity(3); // teeth
sub->setCustomParameter(SP_SHININESS, Vector4(20, 0, 0, 0));
sub->setCustomParameter(SP_DIFFUSE, Vector4(1, 1, 0.7, 1));
sub->setCustomParameter(SP_SPECULAR, Vector4(1, 1, 1, 1));
自己在3dmax中创建一个4X4X4的 box 然后转化为可编辑多变形 选若干面片作为分组1,类似添加分组2,3,4 可以在3dmax中创建多维材质赋予对象观察效果
用ogre max导出对象 替换ogrehead 运行例子能看到自己的box现实出来了,这里主要是获得一个entity的subentity
5 Sample_Character 例子控制一个NPC的移动 跳跃,对应的资源文件是media pack下sinbad.zip 里边tga文件对应人物贴图 mesh文件对应模型 skeleton文件对应骨骼动画 meterial对应材质 这些文件都可以通过3dmax创建并通过maxogre导出,自己试了一下不知道为什么skeleton没导出来,其他都能导出来,可能哪里设置不对 在zip包里还有一个blend文件 这个文件不太明白是做什么的,可能是其他别的引擎对应的文件 通过ogremax winviewer可以预览这些文件的最终效果 包括动画效果
对应核心代码:
// create a floor mesh resource 创建地板 设置投影false
MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Plane(Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z);
// create a floor entity, give it a material, and place it at the origin
Entity* floor = mSceneMgr->createEntity("Floor", "floor");
floor->setMaterialName("Examples/Rockwall");
floor->setCastShadows(false);
mSceneMgr->getRootSceneNode()->attachObject(floor);
// create main model 创建人物模型 并绑定武器到骨骼
mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT);
mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh");
mBodyNode->attachObject(mBodyEnt);
// create swords and attach to sheath
LogManager::getSingleton().logMessage("Creating swords");
mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh");
mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh");
mBodyEnt->attachObjectToBone("Sheath.L", mSword1);
mBodyEnt->attachObjectToBone("Sheath.R", mSword2);
//创建武器尾部的特效
NameValuePairList params;
params["numberOfChains"] = "2";
params["maxElements"] = "80";
mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", ¶ms);
mSwordTrail->setMaterialName("Examples/LightRibbonTrail");
mSwordTrail->setTrailLength(20);
mSwordTrail->setVisible(false);
sceneMgr->getRootSceneNode()->attachObject(mSwordTrail);
for (int i = 0; i < 2; i++)
{
mSwordTrail->setInitialColour(i, 1, 0.8, 0);
mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25);
mSwordTrail->setWidthChange(i, 1);
mSwordTrail->setInitialWidth(i, 0.5);
}
//从skeleton中创建动画
// this is very important due to the nature of the exported animations
mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE);
String animNames[] =
{"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords",
"SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"};
// populate our animation list
for (int i = 0; i < NUM_ANIMS; i++)
{
mAnims[i] = mBodyEnt->getAnimationState(animNames[i]);
mAnims[i]->setLoop(true);
mFadingIn[i] = false;
mFadingOut[i] = false;
}
//更新动画效果 首先是抽刀效果 之后武器的尾部特效 后边省略..
void updateAnimations(Real deltaTime)
{
Real baseAnimSpeed = 1;
Real topAnimSpeed = 1;
mTimer += deltaTime;
if (mTopAnimID == ANIM_DRAW_SWORDS)
{
// flip the draw swords animation if we need to put it back
topAnimSpeed = mSwordsDrawn ? -1 : 1;
// half-way through the animation is when the hand grasps the handles...
if (mTimer >= mAnims[mTopAnimID]->getLength() / 2 &&
mTimer - deltaTime < mAnims[mTopAnimID]->getLength() / 2)
{
// so transfer the swords from the sheaths to the hands
mBodyEnt->detachAllObjectsFromBone();
mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.L" : "Handle.L", mSword1);
mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.R" : "Handle.R", mSword2);
// change the hand state to grab or let go
mAnims[ANIM_HANDS_CLOSED]->setEnabled(!mSwordsDrawn);
mAnims[ANIM_HANDS_RELAXED]->setEnabled(mSwordsDrawn);
// toggle sword trails
if (mSwordsDrawn)
{
mSwordTrail->setVisible(false);
mSwordTrail->removeNode(mSword1->getParentNode());
mSwordTrail->removeNode(mSword2->getParentNode());
}
else
{
mSwordTrail->setVisible(true);
mSwordTrail->addNode(mSword1->getParentNode());
mSwordTrail->addNode(mSword2->getParentNode());
}
}
.....//其他的动画控制 通过setBaseAnimation setTopAnimation 设置fading in-out,animationstate,weight值来控制 特别如果是reset则设置time position值为0
// increment the current base and top animation times 注mAnims类型是ogre animotionstate的数组
if (mBaseAnimID != ANIM_NONE) mAnims[mBaseAnimID]->addTime(deltaTime * baseAnimSpeed);
if (mTopAnimID != ANIM_NONE) mAnims[mTopAnimID]->addTime(deltaTime * topAnimSpeed);
// apply smooth transitioning between our animations
fadeAnimations(deltaTime);
}
void fadeAnimations(Real deltaTime)
{
for (int i = 0; i < NUM_ANIMS; i++)
{
if (mFadingIn[i])
{
// slowly fade this animation in until it has full weight
Real newWeight = mAnims[i]->getWeight() + deltaTime * ANIM_FADE_SPEED;
mAnims[i]->setWeight(Math::Clamp<Real>(newWeight, 0, 1));
if (newWeight >= 1) mFadingIn[i] = false;
}
else if (mFadingOut[i])
{
// slowly fade this animation out until it has no weight, and then disable it
Real newWeight = mAnims[i]->getWeight() - deltaTime * ANIM_FADE_SPEED;
mAnims[i]->setWeight(Math::Clamp<Real>(newWeight, 0, 1));
if (newWeight <= 0)
{
mAnims[i]->setEnabled(false);
mFadingOut[i] = false;
}
}
}
}