mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 17:45:34 +00:00
Report terrain position on cursor position.
This commit is contained in:
parent
8b0dc88db8
commit
fb0f85c8db
3 changed files with 63 additions and 47 deletions
|
@ -194,52 +194,60 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event)
|
||||||
if(!debug || !getCamera()->getViewport())
|
if(!debug || !getCamera()->getViewport())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!((uint32_t)getCamera()->getViewport()->getVisibilityMask() & (uint32_t)CSVRender::Element_Reference))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int viewportWidth = getCamera()->getViewport()->getActualWidth();
|
int viewportWidth = getCamera()->getViewport()->getActualWidth();
|
||||||
int viewportHeight = getCamera()->getViewport()->getActualHeight();
|
int viewportHeight = getCamera()->getViewport()->getActualHeight();
|
||||||
|
|
||||||
float mouseX = (float) event->x()/viewportWidth;
|
float mouseX = (float) event->x()/viewportWidth;
|
||||||
float mouseY = (float) event->y()/viewportHeight;
|
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
|
// Need to set scene manager each time in case there are multiple subviews
|
||||||
CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager());
|
CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager());
|
||||||
std::pair<bool, std::string> result = CSVWorld::PhysicsSystem::instance()->castRay(
|
std::pair<std::string, Ogre::Vector3> result = CSVWorld::PhysicsSystem::instance()->castRay(
|
||||||
mouseX, mouseY, NULL, NULL, getCamera(), ignoreHeightMap);
|
mouseX, mouseY, NULL, NULL, getCamera());
|
||||||
if(result.first)
|
if(result.first != "")
|
||||||
{
|
{
|
||||||
std::cout << "ReferenceId: " << result.second << std::endl;
|
// FIXME: is there a better way to distinguish terrain from objects?
|
||||||
const CSMWorld::CellRef& cellref = mDocument.getData().getReferences().getRecord (result.second).get();
|
QString name = QString(result.first.c_str());
|
||||||
//std::cout << "CellRef.mId: " << cellref.mId << std::endl; // Same as ReferenceId
|
if(name.contains(QRegExp("^HeightField")))
|
||||||
std::cout << "CellRef.mCell: " << cellref.mCell << std::endl;
|
|
||||||
|
|
||||||
const CSMWorld::RefCollection& references = mDocument.getData().getReferences();
|
|
||||||
int index = references.searchId(result.second);
|
|
||||||
if (index != -1)
|
|
||||||
{
|
{
|
||||||
int columnIndex =
|
// terrain
|
||||||
references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId);
|
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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
|
||||||
while (iter!=mCells.end())
|
|
||||||
{
|
{
|
||||||
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;
|
int columnIndex =
|
||||||
break;
|
references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||||
|
|
||||||
|
std::cout << " index: " + QString::number(index).toStdString()
|
||||||
|
+", column index: " + QString::number(columnIndex).toStdString() << std::endl;
|
||||||
}
|
}
|
||||||
++iter;
|
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell *>::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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
#include <components/nifbullet/bulletnifloader.hpp>
|
#include <components/nifbullet/bulletnifloader.hpp>
|
||||||
#include "../../model/settings/usersettings.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
#include "../render/elements.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -174,16 +175,17 @@ namespace CSVWorld
|
||||||
return; // FIXME: add a warning message
|
return; // FIXME: add a warning message
|
||||||
|
|
||||||
mEngine->toggleDebugRendering();
|
mEngine->toggleDebugRendering();
|
||||||
mEngine->stepSimulation(0.0167); // FIXME: DebugDrawer::step() not accessible
|
mEngine->stepSimulation(0.0167); // DebugDrawer::step() not directly accessible
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, std::string> PhysicsSystem::castRay(float mouseX, float mouseY,
|
// FIXME: this method needs a cleanup/refactoring
|
||||||
Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera, bool ignoreHeightMap)
|
std::pair<std::string, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY,
|
||||||
|
Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera)
|
||||||
{
|
{
|
||||||
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
||||||
bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false;
|
bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false;
|
||||||
if(!mSceneMgr)
|
if(!mSceneMgr || !camera || !camera->getViewport())
|
||||||
return std::make_pair(false, ""); // FIXME: add a warning message
|
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
|
// using a really small value seems to mess up with the projections
|
||||||
float nearClipDistance = camera->getNearClipDistance();
|
float nearClipDistance = camera->getNearClipDistance();
|
||||||
|
@ -199,17 +201,19 @@ namespace CSVWorld
|
||||||
_from = btVector3(from.x, from.y, from.z);
|
_from = btVector3(from.x, from.y, from.z);
|
||||||
_to = btVector3(to.x, to.y, to.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;
|
Ogre::Vector3 norm;
|
||||||
std::pair<std::string, float> result =
|
std::pair<std::string, float> result =
|
||||||
mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm);
|
mEngine->rayTest(_from, _to, !ignoreObjects, ignoreHeightMap, &norm);
|
||||||
|
|
||||||
std::string sceneNode;
|
if(result.first == "")
|
||||||
if(result.first != "")
|
return std::make_pair("", Ogre::Vector3(0,0,0));
|
||||||
sceneNode = mRefToSceneNode[result.first];
|
|
||||||
if ((result.first == "") || !mSceneMgr->hasSceneNode(sceneNode))
|
std::string sceneNode = mRefToSceneNode[result.first];
|
||||||
return std::make_pair(false, "");
|
if(!ignoreObjects && mSceneMgr->hasSceneNode(sceneNode))
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//TODO: Try http://www.ogre3d.org/tikiwiki/Create+outline+around+a+character
|
//TODO: Try http://www.ogre3d.org/tikiwiki/Create+outline+around+a+character
|
||||||
Ogre::SceneNode *scene = mSceneMgr->getSceneNode(sceneNode);
|
Ogre::SceneNode *scene = mSceneMgr->getSceneNode(sceneNode);
|
||||||
|
@ -275,7 +279,12 @@ namespace CSVWorld
|
||||||
showHitPoint(mSceneMgr, sceneNode, ray.getPoint(farClipDist*result.second));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,8 @@ namespace CSVWorld
|
||||||
|
|
||||||
void toggleDebugRendering();
|
void toggleDebugRendering();
|
||||||
|
|
||||||
std::pair<bool, std::string> castRay(float mouseX, float mouseY,
|
std::pair<std::string, Ogre::Vector3> castRay(float mouseX, float mouseY,
|
||||||
Ogre::Vector3* normal, std::string* hit,
|
Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera);
|
||||||
Ogre::Camera *camera, bool ignoreHeightMap);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue