当前位置: 首页 > 工具软件 > OGRE > 使用案例 >

OGRE(五)

柯阳曦
2023-12-01
#include "Ogre\ExampleApplication.h"


class Example34FrameListener : public Ogre::FrameListener
{
private:
	Ogre::SceneNode* _node;	//储存传来的场景节点

	Ogre::Camera* _Cam;
	Ogre::PolygonMode _PolyMode;  //绘制模式
	OIS::InputManager* _man;	//输入管理器
	OIS::Keyboard* _key;	//键盘
	OIS::Mouse* _mouse;		//鼠标
	bool _pressedBefore;
	float _movementspeed;

	float _WalkingSpeed;	//控制走路的速度
	float _rotation;	//控制旋转

	Ogre::Entity* _ent;	//想要运动的实体
	Ogre::AnimationState* _aniState;	//运动状态指针
	Ogre::AnimationState* _aniStateTop;
	Ogre::AnimationState* _aniStateIdle;
	Ogre::AnimationState* _aniStateSword;

public:

	Example34FrameListener(Ogre::SceneNode* node,Ogre::Entity* ent,RenderWindow* win,Ogre::Camera* cam)
	{	//场景节点指针 .实体指针 ,渲染窗口指针, 摄像机指针
		_node = node;

		_Cam = cam;

		_pressedBefore = false;

		_movementspeed = 10.0f;
		_PolyMode = Ogre::PolygonMode::PM_SOLID;

		size_t windowHnd = 0;
		std::stringstream windowHndStr;

		win->getCustomAttribute("WINDOW", &windowHnd);
		windowHndStr << windowHnd;

		OIS::ParamList pl;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

		_man = OIS::InputManager::createInputSystem( pl );
		_key = static_cast<OIS::Keyboard*>(_man->createInputObject( OIS::OISKeyboard, false ));
		_mouse = static_cast<OIS::Mouse*>(_man->createInputObject( OIS::OISMouse, false ));

		//两个动作都显示先设置的那个
		_ent = ent;		//赋给帧监听中的实体指针
		_aniStateIdle = _ent->getAnimationState("IdleTop");
		_aniStateIdle->setEnabled(true);
		_aniStateIdle->setLoop(true);
		_aniState = _ent->getAnimationState("RunBase");	//从实体中获取动作指针
		_aniState->setEnabled(false);	//是否可用
		_aniState->setLoop(false);		//是否循环
		_aniStateTop = ent->getAnimationState("RunTop");
		_aniStateTop->setEnabled(false);
		_aniStateTop->setLoop(false);
		_aniStateSword = _ent->getAnimationState("DrawSwords");
		_aniStateSword->setLoop(false);


		_WalkingSpeed = 50.0f;
		_rotation = 0.0f;

	}

	bool frameStarted(const Ogre::FrameEvent  &evt)
	{
		bool walked = false;
		Ogre::Vector3 SinbadTranslate(0,0,0);

		Ogre::Vector3 translate(0,0,0);

		_key->capture();
		_mouse->capture();
		if(_key->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}
		if(_key->isKeyDown(OIS::KC_W))
		{
			translate += Ogre::Vector3(0,0,-1);
		}
		if(_key->isKeyDown(OIS::KC_S))
		{
			translate += Ogre::Vector3(0,0,1);
		}
		if(_key->isKeyDown(OIS::KC_A))
		{
			translate += Ogre::Vector3(-1,0,0);
		}
		if(_key->isKeyDown(OIS::KC_D))
		{
			translate += Ogre::Vector3(1,0,0);
		}

		if(_key->isKeyDown(OIS::KC_R) && !_pressedBefore)
		{
			_pressedBefore = true;
			if(_PolyMode == PM_SOLID) 
			{
				_PolyMode = Ogre::PolygonMode::PM_WIREFRAME;
			} 
			else if(_PolyMode == PM_WIREFRAME) 
			{
				_PolyMode = Ogre::PolygonMode::PM_POINTS;
			} 
			else if(_PolyMode == PM_POINTS) 
			{
				_PolyMode = Ogre::PolygonMode::PM_SOLID;
			} 
			_Cam->setPolygonMode(_PolyMode);
		}
		if(!_key->isKeyDown(OIS::KC_R))
		{
			_pressedBefore = false;
		}

		if(_key->isKeyDown(OIS::KC_UP))
		{
			SinbadTranslate += Ogre::Vector3(0,0,-1);
			_rotation = 3.14f;
			walked = true;
		}
		if(_key->isKeyDown(OIS::KC_DOWN))
		{
			SinbadTranslate += Ogre::Vector3(0,0,1);
			_rotation = 0.0f;
			walked = true;
		}
		if(_key->isKeyDown(OIS::KC_LEFT))
		{
			SinbadTranslate += Ogre::Vector3(-1,0,0);
			_rotation = -1.57f;
			walked = true;
		}
		if(_key->isKeyDown(OIS::KC_RIGHT))
		{
			SinbadTranslate += Ogre::Vector3(1,0,0);
			_rotation = 1.57f;
			walked = true;
		}

		//行走检测
		if (walked)
		{
			_aniState->setEnabled(true);
			_aniStateTop->setEnabled(true);
			_aniStateIdle->setEnabled(false);
			if (_aniState->hasEnded())
			{
				_aniState->setTimePosition(0.0f);
			}
			if (_aniStateTop->hasEnded())
			{
				_aniStateTop->setTimePosition(0.0f);
			}
		}
		else
		{
			_aniState->setEnabled(false);
			_aniStateTop->setEnabled(false);
			_aniStateIdle->setEnabled(true);
			_aniState->setTimePosition(0.0f);
			_aniStateTop->setTimePosition(0.0f);
		}
		
		if (_mouse->getMouseState().buttonDown(OIS::MB_Left))
		{
			_aniStateSword->setEnabled(true);
			if (_aniStateSword->hasEnded())		//关闭动作循环再加上这个,终于只挥一次刀了
			{
				_aniStateSword->setTimePosition(0.0f);
			}
		}
		
		
		

		if (_key->isKeyDown(OIS::KC_LSHIFT))
		{
			_movementspeed = 100.0f;
		}

		float rotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame* -1;
		float rotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;


		_Cam->yaw(Ogre::Radian(rotX));
		_Cam->pitch(Ogre::Radian(rotY));
		_Cam->moveRelative(translate*evt.timeSinceLastFrame * _movementspeed);

		_aniState->addTime(evt.timeSinceLastFrame);		//运动自从上一次更新到现在已经过去多长时间
		_aniStateTop->addTime(evt.timeSinceLastFrame);	//不使用这个函数的话,动作是不会播放的
		_aniStateIdle->addTime(evt.timeSinceLastFrame);
		_aniStateSword->addTime(evt.timeSinceLastFrame);

		_node->translate(SinbadTranslate * evt.timeSinceLastFrame * _WalkingSpeed);
		_node->resetOrientation();		//重置旋转,因为我们要的是绝对的旋转而不是相对的旋转
		_node->yaw(Ogre::Radian(_rotation));

		return true;
	}
};


class Example34 : public ExampleApplication
{
private:
	Ogre::SceneNode* _SinbadNode;
	Ogre::Entity* _SinbadEnt;	//用指针来保存需要做动作的实体
public:
	//创建场景
	void createScene()
	{	//定义平面
		Ogre::Plane plane(Vector3::UNIT_Y, -10);
		Ogre::MeshManager::getSingleton().createPlane("plane",
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
			1500,1500,200,200,true,1,5,5,Vector3::UNIT_Z);

		//平面实体化,并作为场景根节点的子节点
		Ogre::Entity* ent = mSceneMgr->createEntity("LightPlaneEntity", "plane");
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
		ent->setMaterialName("Examples/BeachStones");


		Ogre::SceneNode* node = mSceneMgr->createSceneNode("Node1");
		mSceneMgr->getRootSceneNode()->addChild(node);


		//创建并设置灯光
		Ogre::Light* light = mSceneMgr->createLight("Light1");
		light->setType(Ogre::Light::LT_DIRECTIONAL);
		light->setDirection(Ogre::Vector3(1,-1,0));

		//初始化Sinbad 并加入Sinbad节点
		_SinbadEnt = mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
		_SinbadNode = node->createChildSceneNode("SinbadNode");
		_SinbadNode->setScale(3.0f,3.0f,3.0f);
		_SinbadNode->setPosition(Ogre::Vector3(0.0f,4.0f,0.0f));
		_SinbadNode->attachObject(_SinbadEnt);
		//添加阴影
		mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);	

		//添加双刀
		Ogre::Entity* sword1 = mSceneMgr->createEntity("Sword1", "Sword.mesh");
		Ogre::Entity* sword2 = mSceneMgr->createEntity("Sword2", "Sword.mesh");
		_SinbadEnt->attachObjectToBone("Handle.L", sword1);
		_SinbadEnt->attachObjectToBone("Handle.R", sword2);

		//获取所有动作
		Ogre::AnimationStateSet* set = _SinbadEnt->getAllAnimationStates();
		Ogre::AnimationStateIterator iter = set->getAnimationStateIterator();
		while(iter.hasMoreElements())
		{
			std::cout << iter.getNext()->getAnimationName() << std::endl;
		}
	}
	//创建摄像机
	void createCamera()
	{

		mCamera = mSceneMgr->createCamera("MyCamera1");
		mCamera->setNearClipDistance(5);
		mCamera->setPosition(0,100,200);



	}
	//创建帧监听
	void createFrameListener()
	{
		Ogre::FrameListener* FrameListener = new Example34FrameListener(_SinbadNode,_SinbadEnt,mWindow,mCamera);
		mRoot->addFrameListener(FrameListener);
	}
};

int main (void)
{
	Example34 app;
	app.go();
	return 0;
}

 类似资料: