转载 Ogre骨骼例程——创建模型、行走、转动

1 参考了下面这篇博客(这个博客很不错的啊有大量对源文件的注释哈哈)
1) 找到OgreDemo1的头文件,在OgreDemo1类的createScene函数中添加代码
 
mSceneMgr->setAmbientLight(ColourValue(1,1,1));//设置环境光    
Entity *ent1 = mSceneMgr->createEntity("Robot", "robot.mesh");//创建一个物体  
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");//创建该物体对应的场景节点
node1->attachObject(ent1);//将该物体和场景节点关联起来 
很轻易就得到了机器人(这个ROBO好像是GUNDAM0079里的勇士?),想比之前配置的辛苦,这下真是轻松愉快;

2 robot行走(参考了这篇博文http://hi.baidu.com/andyhebear/blog/item/b560b6347d7515205ab5f530.html,还   是参考了sample的SkeletalAnimation)
  直接贴代码好了主要是在头文件里对类进行操作,由于继承了监听器,故OgreDemo1类里要重载虚函       数createFrameListener,创建OgreDemo1类自己的监听器。
 
#ifndef _TutorialApplication_  
#define _TutorialApplication_  
#include "ExampleApplication.h"  
AnimationState* mAnimState;
class SkeletalAnimationFrameListener : public ExampleFrameListener
{
protected:
public:
SkeletalAnimationFrameListener(RenderWindow* win, Camera* cam, const std::string &debugText)
: ExampleFrameListener(win, cam)
{
mDebugText = debugText;
}
  //listener的事件每渲染一帧就执行一次
bool frameRenderingQueued(const FrameEvent& evt)
{
if( ExampleFrameListener::frameRenderingQueued(evt) == false )//1.6.5用frameRenderingQueued取代了之前的framestart
return false;
//每一帧前增加一帧的时间,从而可以定位到动画应该是什么样的场面
     mAnimState->addTime(evt.timeSinceLastFrame);
 
return true;
}
};
class OgreDemo1 : public ExampleApplication  
{  
protected:  
std::string mDebugText;
public:  
OgreDemo1()  
{  
}  
~OgreDemo1()   
{  
}  
protected:  
void createScene(void)  
//设置环境光
mSceneMgr->setAmbientLight(ColourValue(1,1,1));
//创建一个物体
Entity *ent1 = mSceneMgr->createEntity("Robot", "robot.mesh"); 
//创建该物体对应的场景节点 
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");
//将该物体和场景节点关联起来 
node1->attachObject(ent1);
// 设置关键帧之间的插值方法为样条插值
Animation::setDefaultInterpolationMode(Animation::IM_SPLINE);
// 得到实体“走”动作的AnimationState类对象
mAnimState = ent1->getAnimationState("Walk");
// “Enable”(起始)该动作
mAnimState->setEnabled(true);
}
// Create new frame listener
void createFrameListener(void)
{
mFrameListener= new SkeletalAnimationFrameListener(mWindow, mCamera, mDebugText);
mRoot->addFrameListener(mFrameListener);
}
};  
#endif 
 
3 骨骼方面(这个图是机器人的,每个模型不一样
  robot.skeleton中骨骼名称为”Joint1 ~ Joint18″,分别代表途中的18块骨,他们的分布和从属关系如下图。

robot模型共有5个动作:Die、Idle、Shoot、Slump、Walk;

控制方法:

利用Joint10,yaw()一个角度,robot角色上半身会转动一个角度,但下半身不动。

这个从属关系有意思,像一个orz的姿势

 

4 骨骼运动

 不需要一个动画,故上面行走的代码可以删除

  step1:全局变量Bone *manuallyControlledBone = NULL;

  step2:在frameRenderingQueued里添加 manuallyControlledBone->yaw(Degree(evt.timeSinceLastFrame*100)); 

 step3:在creatscene里添加 SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("RobotNode");

SkeletonInstance *skel = ent1->getSkeleton();

manuallyControlledBone = skel->getBone("Joint10");

manuallyControlledBone->setManuallyControlled(true);


5 OGRE和OPENNI的联动

  出现内存读写异常一般是kinect没连好!

6 摄像机视口的调整

  在exampleapplication.h的createcamera的createcamera()后中增加代码:

mCamera->setPosition(Vector3(500,10,0));//设置摄像机位置

mCamera->lookAt(Vector3(0,0,0));//摄像机看向原点

这样将摄影机正向对着机器人

posted @ 2012-07-27 09:26  吖頭p  阅读(160)  评论(0)    收藏  举报