diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index c48358ce12..631b9be8a9 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -194,52 +194,60 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) if(!debug || !getCamera()->getViewport()) return; - if(!((uint32_t)getCamera()->getViewport()->getVisibilityMask() & (uint32_t)CSVRender::Element_Reference)) - return; - int viewportWidth = getCamera()->getViewport()->getActualWidth(); int viewportHeight = getCamera()->getViewport()->getActualHeight(); float mouseX = (float) event->x()/viewportWidth; float mouseY = (float) event->y()/viewportHeight; - bool ignoreHeightMap = true; - if(((uint32_t)getCamera()->getViewport()->getVisibilityMask() & (uint32_t)CSVRender::Element_Terrain)) - ignoreHeightMap = false; - // Need to set scene manager each time in case there are multiple subviews CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); - std::pair result = CSVWorld::PhysicsSystem::instance()->castRay( - mouseX, mouseY, NULL, NULL, getCamera(), ignoreHeightMap); - if(result.first) + std::pair result = CSVWorld::PhysicsSystem::instance()->castRay( + mouseX, mouseY, NULL, NULL, getCamera()); + if(result.first != "") { - std::cout << "ReferenceId: " << result.second << std::endl; - const CSMWorld::CellRef& cellref = mDocument.getData().getReferences().getRecord (result.second).get(); - //std::cout << "CellRef.mId: " << cellref.mId << std::endl; // Same as ReferenceId - std::cout << "CellRef.mCell: " << cellref.mCell << std::endl; - - const CSMWorld::RefCollection& references = mDocument.getData().getReferences(); - int index = references.searchId(result.second); - if (index != -1) + // FIXME: is there a better way to distinguish terrain from objects? + QString name = QString(result.first.c_str()); + if(name.contains(QRegExp("^HeightField"))) { - int columnIndex = - references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId); + // terrain + std::cout << "terrain: " << result.first << std::endl; + std::cout << " hit pos "+ QString::number(result.second.x).toStdString() + + ", " + QString::number(result.second.y).toStdString() + + ", " + QString::number(result.second.z).toStdString() + << std::endl; - std::cout << "index: " + QString::number(index).toStdString() - +", column index: " + QString::number(columnIndex).toStdString() << std::endl; } - - std::map::iterator iter (mCells.begin()); - while (iter!=mCells.end()) + else { - if(iter->first.getId("dummy") == cellref.mCell) + std::cout << "ReferenceId: " << result.first << std::endl; + const CSMWorld::CellRef& cellref = mDocument.getData().getReferences().getRecord (result.first).get(); + //std::cout << "CellRef.mId: " << cellref.mId << std::endl; // Same as ReferenceId + std::cout << " CellRef.mCell: " << cellref.mCell << std::endl; + + const CSMWorld::RefCollection& references = mDocument.getData().getReferences(); + int index = references.searchId(result.first); + if (index != -1) { - //std::cout << "Cell found" << std::endl; - break; + int columnIndex = + references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId); + + std::cout << " index: " + QString::number(index).toStdString() + +", column index: " + QString::number(columnIndex).toStdString() << std::endl; } - ++iter; + + std::map::iterator iter (mCells.begin()); + while (iter!=mCells.end()) + { + if(iter->first.getId("dummy") == cellref.mCell) + { + //std::cout << "Cell found" << std::endl; + break; + } + ++iter; + } + flagAsModified(); } - flagAsModified(); } } } diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index fa43a57a45..bdd7e77fad 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -13,6 +13,7 @@ #include #include #include "../../model/settings/usersettings.hpp" +#include "../render/elements.hpp" namespace { @@ -174,16 +175,17 @@ namespace CSVWorld return; // FIXME: add a warning message mEngine->toggleDebugRendering(); - mEngine->stepSimulation(0.0167); // FIXME: DebugDrawer::step() not accessible + mEngine->stepSimulation(0.0167); // DebugDrawer::step() not directly accessible } - std::pair PhysicsSystem::castRay(float mouseX, float mouseY, - Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera, bool ignoreHeightMap) + // FIXME: this method needs a cleanup/refactoring + std::pair PhysicsSystem::castRay(float mouseX, float mouseY, + Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera) { CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false; - if(!mSceneMgr) - return std::make_pair(false, ""); // FIXME: add a warning message + if(!mSceneMgr || !camera || !camera->getViewport()) + return std::make_pair("", Ogre::Vector3(0,0,0)); // FIXME: add a warning message // using a really small value seems to mess up with the projections float nearClipDistance = camera->getNearClipDistance(); @@ -199,17 +201,19 @@ namespace CSVWorld _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - bool raycastingObjectOnly = true; // FIXME + uint32_t visibilityMask = camera->getViewport()->getVisibilityMask(); + bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); + bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); + Ogre::Vector3 norm; std::pair result = - mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm); + mEngine->rayTest(_from, _to, !ignoreObjects, ignoreHeightMap, &norm); - std::string sceneNode; - if(result.first != "") - sceneNode = mRefToSceneNode[result.first]; - if ((result.first == "") || !mSceneMgr->hasSceneNode(sceneNode)) - return std::make_pair(false, ""); - else + if(result.first == "") + return std::make_pair("", Ogre::Vector3(0,0,0)); + + std::string sceneNode = mRefToSceneNode[result.first]; + if(!ignoreObjects && mSceneMgr->hasSceneNode(sceneNode)) { //TODO: Try http://www.ogre3d.org/tikiwiki/Create+outline+around+a+character Ogre::SceneNode *scene = mSceneMgr->getSceneNode(sceneNode); @@ -275,7 +279,12 @@ namespace CSVWorld showHitPoint(mSceneMgr, sceneNode, ray.getPoint(farClipDist*result.second)); } - return std::make_pair(true, result.first); + return std::make_pair(result.first, ray.getPoint(farClipDist*result.second)); + } + else + { + // terrain + return std::make_pair(result.first, ray.getPoint(farClipDist*result.second)); } } } diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index c2115bc0fc..351d9535be 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -57,9 +57,8 @@ namespace CSVWorld void toggleDebugRendering(); - std::pair castRay(float mouseX, float mouseY, - Ogre::Vector3* normal, std::string* hit, - Ogre::Camera *camera, bool ignoreHeightMap); + std::pair castRay(float mouseX, float mouseY, + Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera); }; }