📄 etsample.cpp
字号:
#include <OgreNoMemoryMacros.h>
#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>
#include "ExampleApplication.h"
#include "ETTerrainManager.h"
#include "ETTerrainInfo.h"
#include "ETBrush.h"
#include "ETSplattingManager.h"
using namespace std;
using Ogre::uint;
class DemoListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener
{
public:
DemoListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer, ET::TerrainManager* terrainMgr, ET::SplattingManager* splatMgr)
: ExampleFrameListener(win, cam, true, true), mGUIRenderer(renderer), mTerrainMgr(terrainMgr), mTerrainInfo(&terrainMgr->getTerrainInfo()), mSplatMgr(splatMgr)
{
// Setup default variables
mPointer = NULL;
mLMouseDown = false;
mRMouseDown = false;
mMMouseDown = false;
mSceneMgr = sceneManager;
// Reduce move speed
mMoveSpeed = 320;
mRotateSpeed *= 0.008;
// Register this so that we get events.
mMouse->setEventCallback( this );
mKeyboard->setEventCallback(this);
// Create RaySceneQuery
mRaySceneQuery = mSceneMgr->createRayQuery( Ray() );
// Create a "pointer" for use on the terrain
Entity* pointer = mSceneMgr->createEntity("Pointer", "ogrehead.mesh");
mPointer = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mPointer->attachObject(pointer);
// initialise CEGUI mouse cursor position
CEGUI::MouseCursor::getSingleton().setPosition(CEGUI::Point(CEGUI::Vector2(0,0)));
createEditBrush();
mDeform = true;
mChosenTexture = 0;
mDirection = Vector3::ZERO;
mContinue = true;
mCamNode = mCamera->getParentSceneNode();
}
~DemoListener( )
{
delete mRaySceneQuery;
}
void createEditBrush()
{
// load the edit brush for terrain editing
Image image;
image.load("brush.png", "ET");
image.resize(16, 16);
mEditBrush = ET::loadBrushFromImage(image);
}
bool frameStarted(const FrameEvent &evt)
{
if (!ExampleFrameListener::frameStarted( evt ))
return false;
// handle movement
mCamNode->translate(mCamera->getOrientation()*mDirection*mMoveSpeed*evt.timeSinceLastFrame);
// Ensure we stay above terrain (somehow buggy still, doesn't work reliably)
Vector3 camPos = mCamNode->getPosition( );
// get terrain height at camPos
float terrainHeight = mTerrainInfo->getHeightAt(camPos.x, camPos.z);
if ((terrainHeight + 30.0f) > camPos.y) //如果摄像机低于地形高度+30.0f,调整摄像机高度
mCamNode->setPosition(camPos.x, terrainHeight+30.0f, camPos.z);
if (mLMouseDown || mRMouseDown)
{
// deform or paint terrain on mouse down
// left button raises, right button lowers
if (mDeform)
{
// choose a brush intensity, this determines
// how extreme our brush works on the terrain
float brushIntensity = evt.timeSinceLastFrame * 0.4 * (mLMouseDown? 1 : -1);
// translate our cursor position to vertex indexes
Vector3 deformPos = mPointer->getPosition();
int x = mTerrainInfo->posToVertexX(deformPos.x);
int z = mTerrainInfo->posToVertexZ(deformPos.z);
// now tell the ETM to deform the terrain
mTerrainMgr->deform(x, z, mEditBrush, brushIntensity);
}
else
{
// need to set our brush intensity larger for painting.
// for painting, all texture channels are only 1 byte
// large, so with a small intensity you won't get any
// effect at all.
float brushIntensity = evt.timeSinceLastFrame * 5.0 * (mLMouseDown? 1 : -1);
// retrieve edit points
Vector3 paintPos = mPointer->getPosition();
int x = mTerrainInfo->posToVertexX(paintPos.x);
int z = mTerrainInfo->posToVertexZ(paintPos.z);
// now use the splatting manager to update the coverage maps
mSplatMgr->paint(mChosenTexture, x, z, mEditBrush, brushIntensity);
}
}
return mContinue;
}
virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
// Left mouse button down
if ( id == OIS::MB_Left )
{
mLMouseDown = true;
}
// Middle mouse button down
else if ( id == OIS::MB_Middle )
{
CEGUI::MouseCursor::getSingleton().hide( );
mMMouseDown = true;
}
else if (id == OIS::MB_Right)
{
mRMouseDown = true;
}
return true;
}
virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
// Left mouse button up
if ( id == OIS::MB_Left )
{
mLMouseDown = false;
// after completed deformation steps, recalculate the lightmap
if (mDeform)
updateLightmap();
}
// Middle mouse button up
else if ( id == OIS::MB_Middle )
{
CEGUI::MouseCursor::getSingleton().show( );
mMMouseDown = false;
}
else if (id == OIS::MB_Right)
{
mRMouseDown = false;
// after completed deformation steps, recalculate the lightmap
if (mDeform)
updateLightmap();
}
return true;
}
virtual bool mouseMoved( const OIS::MouseEvent &arg )
{
// Update CEGUI with the mouse motion
CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
// whenever the mouse is moved, we update the position on the
// terrain to which the mouse is currently pointing
Ray mouseRay = mCamera->getCameraToViewportRay(arg.state.X.abs/float(arg.state.width), arg.state.Y.abs/float(arg.state.height));
// since ETM is no longer a scene manager, we don't use a ray scene query,
// but instead query the terrain info directly
std::pair<bool, Vector3> result = mTerrainInfo->rayIntersects(mouseRay);
if (result.first)
{
// update pointer's position
mPointer->setPosition(result.second);
}
// If we are dragging the middle mouse button.
if ( mMMouseDown )
{
mCamera->yaw( Degree(-arg.state.X.rel * mRotateSpeed) );
mCamera->pitch( Degree(-arg.state.Y.rel * mRotateSpeed) );
}
return true;
}
virtual bool keyPressed(const OIS::KeyEvent& arg)
{
// we'll use the keys 1, 2, 3, 4 and E to switch between
// edit modes and select a paint texture
// WSAD is used for movement
// O will save the changes to disk
switch (arg.key)
{
case OIS::KC_1:
mDeform = false;
mChosenTexture = 0;
return true;
case OIS::KC_2:
mDeform = false;
mChosenTexture = 1;
return true;
case OIS::KC_3:
mDeform = false;
mChosenTexture = 2;
return true;
case OIS::KC_4:
mDeform = false;
mChosenTexture = 3;
return true;
case OIS::KC_5:
mDeform = false;
mChosenTexture = 4;
return true;
case OIS::KC_6:
mDeform = false;
mChosenTexture = 5;
return true;
case OIS::KC_E:
mDeform = true;
return true;
case OIS::KC_W:
mDirection.z += -1;
return true;
case OIS::KC_S:
mDirection.z += 1;
return true;
case OIS::KC_A:
mDirection.x += -1;
return true;
case OIS::KC_D:
mDirection.x += 1;
return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -