您的位置:首页 > 编程语言

源代码:中级教程2:射线场景查询及基础鼠标用法

2010-06-30 22:51 393 查看
win32控制台项目

需要的lib有
OgreMain_d.lib
OIS_d.lib
OgreGUIRenderer_d.lib
CEGUIBase_d.lib

源代码如下:
]#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>

#include "ExampleApplication.h"

//1.首先,我们想要将鼠标右键绑定到“鼠标观察”模式。不能使用鼠标四下看看是相当郁闷的,
//  所以我们首先对程序增加鼠标控制(尽管只是在我们保持鼠标右键按下时)。
//2.我们想要让镜头不会穿过地表。这会使它更接近我们期望的样子。
//3.我们想要在地表上用鼠标左键点击一下,就在那里增加一个实体。
//4.最后,我们想要能“拖拽”实体。即选中我们想要看到的实体,按住鼠标左键不放,将它移动
//  到我们想要放置的地方。松开鼠标左键,就又会将它锁定在原地。
class MouseQueryListener : public ExampleFrameListener, public OIS::MouseListener
{
public:

MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
: ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer)
{   //由于地形相当小,所以我们也要减少移动和旋转速度
mCount = 0;
mCurrentObject = NULL;
mLMouseDown = false;
mRMouseDown = false;
mSceneMgr = sceneManager;

// Reduce move speed
mMoveSpeed = 50;
mRotateSpeed /= 500;

//为了MouseQueryListener能收到鼠标事件,我们必须把它注册为一个鼠标监听器

mMouse->setEventCallback(this);

//最后在构造函数中我们需要创建一个RaySceneQuery对象。用场景管理器的一个调用创建

mRaySceneQuery = mSceneMgr->createRayQuery(Ray());

} // MouseQueryListener

~MouseQueryListener()
{
// We created the query, and we are also responsible for deleting it.
mSceneMgr->destroyQuery(mRaySceneQuery);

}

bool frameStarted(const FrameEvent &evt)
{
// Process the base frame listener code.  Since we are going to be
// manipulating the translate vector, we need this to happen first.
if (!ExampleFrameListener::frameStarted(evt))
return false;

// Setup the scene query
Vector3 camPos = mCamera->getPosition();
Ray cameraRay(Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y);
mRaySceneQuery->setRay(cameraRay);

// Perform the scene query
RaySceneQueryResult &result = mRaySceneQuery->execute();
RaySceneQueryResult::iterator itr = result.begin();

// Get the results, set the camera height
if (itr != result.end() && itr->worldFragment)
{
Real terrainHeight = itr->worldFragment->singleIntersection.y;
if ((terrainHeight + 10.0f) > camPos.y)
mCamera->setPosition( camPos.x, terrainHeight + 10.0f, camPos.z );
}

return true;

//	return ExampleFrameListener::frameStarted(evt);
}

/* MouseListener callbacks.
当鼠标被移动时,更新CEGUI(以便光标也移动)
当鼠标右键被按下时,设置mRMouseButton为true. 当鼠标右键被松开时,设置mRMouseButton为false 当鼠标被“拖拽”时,改变视图
当鼠标被“拖拽”时,隐藏鼠标光标 找到MouseQueryListener::mouseMoved方法。*/
bool mouseMoved(const OIS::MouseEvent &arg)
{
// Update CEGUI with the mouse motion
CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);

if (mLMouseDown)
{
CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width),mousePos.d_y/float(arg.state.height));
mRaySceneQuery->setRay(mouseRay);

RaySceneQueryResult &result = mRaySceneQuery->execute();
RaySceneQueryResult::iterator itr = result.begin();

if (itr != result.end() && itr->worldFragment)
mCurrentObject->setPosition(itr->worldFragment->singleIntersection);
} // if

// If we are dragging the right mouse button.
else if (mRMouseDown)
{
mCamera->yaw(Degree(-arg.state.X.rel * mRotateSpeed));
mCamera->pitch(Degree(-arg.state.Y.rel * mRotateSpeed));
} // else if

return true;
}

bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{

// Left mouse button down
if (id == OIS::MB_Left)
{
// Setup the ray scene query, use CEGUI's mouse position
CEGUI::Point mousePos = CEGUI::MouseCursor::getSingleton().getPosition();
Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width), mousePos.d_y/float(arg.state.height));
mRaySceneQuery->setRay(mouseRay);
// Execute query
RaySceneQueryResult &result = mRaySceneQuery->execute();
RaySceneQueryResult::iterator itr = result.begin( );

// Get results, create a node/entity on the position
if (itr != result.end() && itr->worldFragment)
{
char name[16];
sprintf( name, "Robot%d", mCount++ );
Entity *ent = mSceneMgr->createEntity(name, "robot.mesh");
mCurrentObject = mSceneMgr->getRootSceneNode()->createChildSceneNode(String(name) + "Node", itr->worldFragment->singleIntersection);
mCurrentObject->attachObject(ent);
mCurrentObject->setScale(0.1f, 0.1f, 0.1f);
} // if

mLMouseDown = true;
} // if
// Right mouse button down
else if (id == OIS::MB_Right)
{
CEGUI::MouseCursor::getSingleton().hide();
mRMouseDown = true;
} // else if

return true;
}

bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
{      // Left mouse button up
if (id == OIS::MB_Left)
{
mLMouseDown = false;
} // if

// Right mouse button up
else if (id == OIS::MB_Right)
{
CEGUI::MouseCursor::getSingleton().show();
mRMouseDown = false;
} // else if

return true;
}

protected:

RaySceneQuery *mRaySceneQuery;      // 射线场景查询指针  ---->  握有RaySceneQuery的一个拷贝,我们会它来寻找地面上的坐标。
bool mLMouseDown, mRMouseDown;     // 如果按下鼠标按钮,返回True ---->会追踪我们是否按下鼠标键
int mCount;                        // 屏幕上机器人的数量
SceneManager *mSceneMgr;           // 指向场景管理器的指针  ---->(我们将用这个“拖拽”实体)
SceneNode *mCurrentObject;         // 新创建的物休
CEGUI::Renderer *mGUIRenderer;     // CEGUI渲染器    ---->握有指向CEGUI Renderer的指针,我们将用它更新CEGUI

};

class MouseQueryApplication : public ExampleApplication
{
protected:
CEGUI::OgreCEGUIRenderer *mGUIRenderer;
CEGUI::System *mGUISystem;         // cegui system
public:
MouseQueryApplication()
{
}

~MouseQueryApplication()
{
}
protected:
void chooseSceneManager(void)
{
// Use the terrain scene manager.
mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
}

void createScene(void)
{

// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

// World geometry
mSceneMgr->setWorldGeometry("terrain.cfg");

// Set camera look point
mCamera->setPosition(40, 100, 580);
mCamera->pitch(Degree(-30));
mCamera->yaw(Degree(-45));

// CEGUI setup
mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
mGUISystem = new CEGUI::System(mGUIRenderer);
// Mouse
CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");
CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");

}

void createFrameListener(void)
{
mFrameListener = new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
mFrameListener->showDebugOverlay(true);
mRoot->addFrameListener(mFrameListener);
}

};
//////////////////////////////////////////
//////////////////////////////////////////

#include "windows.h"

int main(int argc, char **argv)
{
// Create application object
MouseQueryApplication app;

try {
app.go();
} catch( Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: