PDA

View Full Version : Ogre+qt mouse event (add object with mouse problem)



rimie23
18th April 2012, 10:45
Hi
i integrate ogre with qt
i have now this code


#include <QtDebug>

#include "ogrewidget.h"

OgreWidget::OgreWidget(QWidget *parent)
:QWidget(parent),
ogreRoot(0), ogreSceneManager(0), ogreRenderWindow(0), ogreViewport(0),
ogreCamera(0)
{
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_PaintOnScreen);
setMinimumSize(240,240);
setFocusPolicy(Qt::ClickFocus);
}

OgreWidget::~OgreWidget()
{
if(ogreRenderWindow)
{
ogreRenderWindow->removeAllViewports();
}

if(ogreRoot)
{
ogreRoot->detachRenderTarget(ogreRenderWindow);

if(ogreSceneManager)
{
ogreRoot->destroySceneManager(ogreSceneManager);
}
}

delete ogreRoot;
}

void OgreWidget::setBackgroundColor(QColor c)
{
if(ogreViewport)
{
Ogre::ColourValue ogreColour;
ogreColour.setAsARGB(c.rgba());
ogreViewport->setBackgroundColour(ogreColour);
}
}

void OgreWidget::setCameraPosition(const Ogre::Vector3 &pos)
{
ogreCamera->setPosition(pos);
ogreCamera->lookAt(0,50,0);
update();
emit cameraPositionChanged(pos);
}

void OgreWidget::keyPressEvent(QKeyEvent *e)
{
static QMap<int, Ogre::Vector3> keyCoordModificationMapping;
static bool mappingInitialised = false;

if(!mappingInitialised)
{
keyCoordModificationMapping[Qt::Key_Z] = Ogre::Vector3(0, 0, -5);
keyCoordModificationMapping[Qt::Key_S] = Ogre::Vector3(0, 0, 5);
keyCoordModificationMapping[Qt::Key_Q] = Ogre::Vector3(-5, 0, 0);
keyCoordModificationMapping[Qt::Key_D] = Ogre::Vector3( 5, 0, 0);
keyCoordModificationMapping[Qt::Key_PageUp] = Ogre::Vector3(0, 5, 0);
keyCoordModificationMapping[Qt::Key_PageDown] = Ogre::Vector3(0, -5, 0);

mappingInitialised = true;
}

QMap<int, Ogre::Vector3>::iterator keyPressed =
keyCoordModificationMapping.find(e->key());
if(keyPressed != keyCoordModificationMapping.end() && ogreCamera)
{
const Ogre::Vector3 &actualCamPos = ogreCamera->getPosition();
setCameraPosition(actualCamPos + keyPressed.value());

e->accept();
}
else
{
QWidget::keyPressEvent(e);
}
}

void OgreWidget::moveEvent(QMoveEvent *e)
{
QWidget::moveEvent(e);

if(e->isAccepted() && ogreRenderWindow)
{
ogreRenderWindow->windowMovedOrResized();
update();
}
}

void OgreWidget::paintEvent(QPaintEvent *e)
{
ogreRoot->_fireFrameStarted();
ogreRenderWindow->update();
ogreRoot->_fireFrameEnded();

e->accept();
}

void OgreWidget::resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);

if(e->isAccepted())
{
const QSize &newSize = e->size();
if(ogreRenderWindow)
{
ogreRenderWindow->resize(newSize.width(), newSize.height());
ogreRenderWindow->windowMovedOrResized();
}
if(ogreCamera)
{
Ogre::Real aspectRatio = Ogre::Real(newSize.width()) / Ogre::Real(newSize.height());
ogreCamera->setAspectRatio(aspectRatio);
}
}
}

void OgreWidget::showEvent(QShowEvent *e)
{
if(!ogreRoot)
{
initOgreSystem();
}

QWidget::showEvent(e);
}
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
void OgreWidget::initOgreSystem()
{
//ogreRoot = new Ogre::Root();

/* Ogre::Root**/ ogreRoot=new Ogre::Root("plugins_d.cfg");

//Ogre::RenderSystem *renderSystem = ogreRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
// Ogre::ResourceGroupManager::getSingleton().initial iseAllResourceGroups();


ogreRoot->loadPlugin("RenderSystem_GL_d");
Ogre::RenderSystem* rs = ogreRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
if(!(rs->getName() == "OpenGL Rendering Subsystem"))
{
printf("no susystem"); //No RenderSystem found
}
//Ogre::RenderSystem *renderSystem = ogreRoot->getRenderSystemByName("ogre_pluginsRenderSystem_GL_d");
ogreRoot->setRenderSystem(/*renderSystem*/rs);
ogreRoot->initialise(false);

ogreSceneManager = ogreRoot->createSceneManager(Ogre::ST_GENERIC);

Ogre::NameValuePairList viewConfig;
Ogre::String widgetHandle;
#ifdef Q_WS_WIN
widgetHandle = Ogre::StringConverter::toString((size_t)((HWND)win Id()));
#else
QWidget *q_parent = dynamic_cast <QWidget *> (parent());
QX11Info xInfo = x11Info();

widgetHandle = Ogre::StringConverter::toString ((unsigned long)xInfo.display()) +
":" + Ogre::StringConverter::toString ((unsigned int)xInfo.screen()) +
":" + Ogre::StringConverter::toString ((unsigned long)q_parent->winId());
#endif
viewConfig["externalWindowHandle"] = widgetHandle;
ogreRenderWindow = ogreRoot->createRenderWindow("Ogre rendering window",
width(), height(), false, &viewConfig);

ogreCamera = ogreSceneManager->createCamera("myCamera");
Ogre::Vector3 camPos(0, 50,150);
ogreCamera->setPosition(camPos);
ogreCamera->lookAt(0,50,0);
emit cameraPositionChanged(camPos);

ogreViewport = ogreRenderWindow->addViewport(ogreCamera);
ogreViewport->setBackgroundColour(Ogre::ColourValue(0,0,0));
ogreCamera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));

setupNLoadResources();
createScene();
}


void OgreWidget::setupNLoadResources()
{
// Load resource paths from config file
// Load resource paths from config file
Ogre::ConfigFile cf;
cf.load("resources_d.cfg");

// Go through all sections & settings in the file
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();

Ogre::String secName, typeName, archName;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
Ogre::ResourceGroupManager::getSingleton().addReso urceLocation(
archName, typeName, secName);
}
}
// Initialise, parse scripts etc
Ogre::ResourceGroupManager::getSingleton().initial iseAllResourceGroups();
}

void OgreWidget::createScene()
{
ogreSceneManager->setAmbientLight(Ogre::ColourValue(1,1,1));

Ogre::Entity *robotEntity = ogreSceneManager->createEntity("Robot","robot.mesh");
Ogre::SceneNode *robotNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode("RobotNode");
robotNode->attachObject(robotEntity);
robotNode->yaw(Ogre::Radian(Ogre::Degree(-90)));
}



my problem now is i want add object with mouse in the windows i do not know how i do that

when i was work only with ogre i make it like that



bool BaseApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
MarkerNode= mSceneMgr->getRootSceneNode()->createChildSceneNode();
if (mTrayMgr->injectMouseDown(arg, id)) return true;
//mCameraMan->injectMouseDown(arg, id);
switch(id) {
case OIS::MB_Left:
/*Ogre::Entity**/ ent_marker = mSceneMgr->createEntity( Ogre::SceneManager:: PT_SPHERE);

//createNode(ent_marker);
MarkerNode->attachObject(ent_marker);
MarkerNode->setScale(0.1f, 0.1f, 0.1f);
Ogre::Real screenWidth = Ogre::Root::getSingleton().getAutoCreatedWindow()->getWidth();
Ogre::Real screenHeight = Ogre::Root::getSingleton().getAutoCreatedWindow()->getHeight();

// convert to 0-1 offset
Ogre::Real offsetX = arg.state.X.abs / screenWidth;
Ogre::Real offsetY = arg.state.Y.abs / screenHeight;

// set up the ray
Ogre::Ray mouseRay = mCamera1->getCameraToViewportRay(offsetX, offsetY);

// check if the ray intersects our cube
// intersects() will return whether it intersects or not (the bool value) and
// what distance (the Real value) along the ray the intersection is
std::pair<bool, Ogre::Real> result = mouseRay.intersects(CubeNode->getAttachedObject (0) ->getBoundingBox());


if(result.first) {
// if the ray intersect the plane, we have a distance value
// telling us how far from the ray origin the intersection occurred.
// the last thing we need is the point of the intersection.
// Ray provides us getPoint() function which returns a point
// along the ray, supplying it with a distance value.

// get the point where the intersection is
Ogre:: Vector3 point = mouseRay.getPoint(result.second);

// position our sphere
/* Ogre::Entity**/ //ent_marker->setPosition(point);
//MarkerNode->setPosition(point);


MarkerNode->setPosition(point);


//break;
}
}


and i initialyse OIS like that


Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;

mWindow->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

mInputManager = OIS::InputManager::createInputSystem( pl );

mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));*/

mRoot->addFrameListener(this);

rimie23
18th April 2012, 14:53
i can now add oject ut if i clic another time i can't add (it add one object )


void OgreWidget::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton)
{

MarkerNode= ogreSceneManager->getRootSceneNode()->createChildSceneNode();


ent_marker = ogreSceneManager->createEntity( Ogre::SceneManager:: PT_SPHERE);

//createNode(ent_marker);
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("green", "General");
material->getTechnique( 0 )->getPass( 0 )->setAmbient(1, 0, 0);
ent_marker->setMaterial(material);
MarkerNode->attachObject(ent_marker);
MarkerNode->setScale(0.1f, 0.1f, 0.1f);

// convert to 0-1 offset

Ogre::Real offsetX =(double)e->pos().x()/(double)width();
Ogre::Real offsetY=(double) e->pos().y()/(double)height();

// set up the ray
Ogre::Ray mouseRay = ogreCamera->getCameraToViewportRay(offsetX, offsetY);

// check if the ray intersects our cube
// intersects() will return whether it intersects or not (the bool value) and
// what distance (the Real value) along the ray the intersection is
std::pair<bool, Ogre::Real> result1 = mouseRay.intersects(CubeNode->getAttachedObject (0) ->getBoundingBox());

mRayScnQuery->setRay(mouseRay);
// Execute query

Ogre::RaySceneQueryResult &result =mRayScnQuery->execute();
Ogre::RaySceneQueryResult::iterator itr;
for(itr = result.begin() ;itr != result.end();++itr)
{
if(itr->movable)
{

MarkerNode->_setDerivedPosition(mouseRay.getPoint(itr->distance));

MarkerNode->setScale(0.1f, 0.1f, 0.1f);
}
}
}
}

it dos not make update??

Spitfire
20th April 2012, 09:32
Theoretically, this should work:


bool OgreWidget::mousePressEvent( QMouseEvent* e )
{
MarkerNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
//if (mTrayMgr->injectMouseDown(arg, id)) return true; //do you need that for something???
if( e->button() == Qt::LeftButton )
{
ent_marker = mSceneMgr->createEntity( Ogre::SceneManager:: PT_SPHERE);
MarkerNode->attachObject(ent_marker);
MarkerNode->setScale(0.1f, 0.1f, 0.1f);
Ogre::Real screenWidth = Ogre::Root::getSingleton().getAutoCreatedWindow()->getWidth();
Ogre::Real screenHeight = Ogre::Root::getSingleton().getAutoCreatedWindow()->getHeight();

Ogre::Real offsetX = e->posF().x() / this->width();
Ogre::Real offsetY = e->posF().y() / this->height();
Ogre::Ray mouseRay = mCamera1->getCameraToViewportRay(offsetX, offsetY);
std::pair<bool, Ogre::Real> result = mouseRay.intersects(CubeNode->getAttachedObject (0) ->getBoundingBox());

if(result.first)
{
Ogre:: Vector3 point = mouseRay.getPoint(result.second);
MarkerNode->setPosition(point);
}
break;
}

QWidget::mousePressEvent( e );
}

rimie23
23rd April 2012, 12:46
No it dos not work

when i clic another time i do not see another oject ut if i resize the xindow i see it , if i clic another time i can't see the oject ut if i resize the windows i see it
that mean it make update just when i resize the window

Spitfire
23rd April 2012, 15:18
then call this->update() at the end of the mousePressEvent(), this will trigger repaint of the whole widget and you should see new content.

rimie23
23rd April 2012, 19:43
it dos not work
when i clic the cube hide but when i resize the window i see the cube and the object how is adde

Spitfire
24th April 2012, 09:18
Ok, I'm not too familiar with OGRE, but you should see where I'm going with it.

Resizing a window triggers repaint of the scene. If repainting of the widget doesn't help, try updating the ogre scene somehow, maybe mSceneMgr->redraw() or some_ogre_view->repaint().

rimie23
24th April 2012, 10:49
Ah ok i will do that
thanks