};
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include “windows.h”
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
// Create application object
MoveDemoApplication app;
try {
app.go();
} catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has
occured!",
MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, “An exception has occured: %s\n”,
e.getFullDescription().c_str());
#endif
}
return 0;
}
稍加解释一下框架代码:
在MoveDemoApplication中预先定义的三个变量。
Entity *mEntity; // The entity of the object we are animating
SceneNode *mNode; // The SceneNode of the object we are moving
std::deque mWalkList; // A deque containing the waypoints
我们创建的entity实例保存在变量mEntity中。
我们创建的node实例保存在mNode中。
mWalkList包含了所有我们希望对象行走到的节点,他是deque类型,你可以把它想象成是一种双向链表的结构。书中解释为deque对象是一个高效的双端对列。他的基本使用函数有:
1、push_front和push_back方法分别将对象放入队列的前端和后端。
2、front和back方法分别返回当前队列前端和后端的元素
(注意:这里最好有判空的习惯,用if( empty() ) )pop_front和pop_back两个方法分别从队列两端移除对象。最后,empty方法返回该队列是否为空。
一、创建场景(createScene()函数中添加代码)
// Set the default lighting.创建环境光很亮,能够看到所有物体
mSceneMgr->setAmbientLight( ColourValue( 1.0f, 1.0f, 1.0f ) );
// Create the entity创建实体
mEntity = mSceneMgr->createEntity( “Robot”, “robot.mesh” );
// Create the scene node创建场景节点
mNode = mSceneMgr->getRootSceneNode( )->
createChildSceneNode( “RobotNode”, Vector3( 0.0f, 0.0f, 25.0f ) );
mNode->attachObject( mEntity );
// Create the walking list创建总动路线上的关键点放到高效的两端队列里
mWalkList.push_back( Vector3( 550.0f, 0.0f, 50.0f ) );
mWalkList.push_back( Vector3(-100.0f, 0.0f, -200.0f ) );
// Create objects so we can see movement创建关键点的标记物
Entity *ent;
SceneNode *node;
ent = mSceneMgr->createEntity( “Knot1”, “knot.mesh” );
node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( “Knot1Node”,
Vector3( 0.0f, -10.0f, 25.0f ) );
node->attachObject( ent );
node->setScale( 0.1f, 0.1f, 0.1f );
ent = mSceneMgr->createEntity( “Knot2”, “knot.mesh” );
node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( “Knot2Node”,
Vector3( 550.0f, -10.0f, 50.0f ) );
node->attachObject( ent );
node->setScale( 0.1f, 0.1f, 0.1f );
ent = mSceneMgr->createEntity( “Knot3”, “knot.mesh” );
node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( “Knot3Node”,
Vector3(-100.0f, -10.0f,-200.0f ) );
node->attachObject( ent );
node->setScale( 0.1f, 0.1f, 0.1f );
// Set the camera to look at our handywork创建摄像机
mCamera->setPosition( 90.0f, 280.0f, 535.0f );
mCamera->pitch( Degree(-30.0f) );
mCamera->yaw( Degree(-15.0f) );
至此你可以运行一下,看看基本的环境。
二、动画制作
1、你需要从实体对象里获取AnimationState。
2、设置它的选项,并激活它。
3、你还必须在每一帧后给它添加时间,才能让动画动起来。
MoveDemoListener的构造函数中添加代码(这只是个小练习,之后会删除这些代码)
// Set idle animation
mAnimationState = ent->getAnimationState(“Idle”);
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
第二行从实体中获取到了AnimationState。
第三行我们调用setLoop( true ),让动画不停地循环。
第四行才把这个动画真正激活。
但是,Idle是从哪里来的呢?每个mesh都有它们自己定义的动画集。为了能够查看某个mesh的全部动画,你需要下载OgreMeshViewer才能看到,我们可以在maya中将这些动作定义好,导出的时候,给相应的clip起好名字就可以了。
最后,还需要在每一帧里根据时间来更新这个动画的状态。找到MoveDemoListener::frameStarted方法,在方法的开头添加这一行:
mAnimationState->addTime(evt.timeSinceLastFrame);
根据Idle这个动作,机器人至此已经可以原地踏步了!
——————————————————————————-————————————————
三、移动机器人
变量说明
机器人移动的方向保存到mDirection里面。
当前机器人前往的目的地保存在mDestination里。
mDistance保存机器人离目的地的距离。
mWalkSpeed里保存机器人的移动速度。
MoveDemoListener中添加代码:
先清空MoveDemoListener构造器(第二步的代码只是想让我们知道如何调用基本的动画的流程)
速度设为每秒35个单位,把mDirection设成零向量,因为后面会用它来判断机器人是否正在行走。
// Set default values for variables
mWalkSpeed = 35.0f;
mDirection = Vector3::ZERO;
MoveDemoListener::frameStarted()中add之前添加代码:
if (mDirection == Vector3::ZERO)
{
if (nextLocation())
{
// Set walking animation
mAnimationState = mEntity->getAnimationState(“Walk”);
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}
}
else //mDirection != Vector3::ZERO
{
Real move = mWalkSpeed * evt.timeSinceLastFrame;
mDistance -= move;//路程=速度*时间
//检测是否“走过”了目标地点。如果现在mDistance小于0,则“跳”到这点上并设置移动到下一个地点
//把mDirection设置成零向量。如果nextLocation方法不改变mDirection(即没有其它地方可去)
//则不再四处移动了
if (mDistance <= 0.0f)
{
mNode->setPosition(mDestination);
mDirection = Vector3::ZERO;
// Set animation based on if the robot has another point to walk to.
if (! nextLocation())
{
// Set Idle animation
mAnimationState = mEntity->getAnimationState(“Idle”);
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}
else
{
// Rotation Code will go here later
}//如果queue里已经没有更多的地点要走的话,我们没有必要再次设置行走动画。
//既然机器人已经在行走了,没有必要再告诉他这么做。
//如果机器人还要走向另一个地点,我们就要把它旋转以面对那个地点。
//现在,我们在else括号旁边留下注释占位符;记住这个地点,后面还要回来。
}
else
{
mNode->translate(mDirection * move);
} // else
} // if
MoveDemoListener::nextLocation()添加代码return语句之前:
//如果我们用完了所有的地点,它返回false。
if (mWalkList.empty())
return false;
mDestination = mWalkList.front(); // this gets the front of the deque
mWalkList.pop_front(); // this removes the front of the deque
mDirection = mDestination - mNode->getPosition();
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/55c3ec59d01534c48d63b7d6fb711977.jpeg)
技术学习总结
学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。
最后面试分享
大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/55c3ec59d01534c48d63b7d6fb711977.jpeg)
技术学习总结
学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。
[外链图片转存中…(img-ftFoKa1V-1712657885549)]
[外链图片转存中…(img-j3MFP38L-1712657885550)]
[外链图片转存中…(img-X71fCL6V-1712657885550)]
最后面试分享
大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!
[外链图片转存中…(img-UMo47ML4-1712657885550)]
[外链图片转存中…(img-XEKX2817-1712657885550)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!