1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-25 08:39:41 +00:00

Enhanced snap functionality for pathgrid points.

This commit is contained in:
cc9cii 2014-11-11 19:40:04 +11:00
parent 407edc770c
commit 3eb556ff8a
3 changed files with 25 additions and 83 deletions

View file

@ -236,29 +236,22 @@ namespace CSVRender
// FIXME: move pathgrid point, but don't save yet (need pathgrid // FIXME: move pathgrid point, but don't save yet (need pathgrid
// table feature & its data structure to be completed) // table feature & its data structure to be completed)
// Also need to signal PathgridPoint object of change // Also need to signal PathgridPoint object of change
std::pair<std::string, Ogre::Vector3> result = std::pair<std::string, float> result =
anyUnderCursor(event->x(), event->y()); mPhysics->distToClosest(pos, getCamera(), 600); // snap
std::string refId = mPhysics->sceneNodeToRefId(result.first); std::string refId = mPhysics->sceneNodeToRefId(result.first);
if(result.first != "" && // don't allow pathgrid points under the cursor if(result.first != "" && // don't allow pathgrid points under the cursor
!QString(refId.c_str()).contains(QRegExp("^Pathgrid"))) !QString(refId.c_str()).contains(QRegExp("^Pathgrid")))
{ {
// snap (defaults to 300 or less) pos.z -= result.second;
// FIXME: sticks to the underside of the object if snapping up pos.z += 2; // arbitrary number, lift up slightly (maybe change the nif?)
std::pair<std::string, float> res = // FIXME: rather than just updating at the end, should
mPhysics->distToClosest(pos, getCamera(), 500); // consider providing visual feedback of terrain height
if(res.first != "") // while dragging the pathgrid point (maybe check whether
{ // the object is a pathgrid point at the begging and set
pos.z -= res.second; // a flag?)
// FIXME: rather than just updating at the end, should placeObject(mGrabbedSceneNode, pos); // result.second
// consider providing visual feedback of terrain height mParent->pathgridMoved(referenceId, pos); // result.second
// while dragging the pathgrid point (maybe check whether
// the object is a pathgrid point at the begging and set
// a flag?)
placeObject(mGrabbedSceneNode, pos); // result.second
mParent->pathgridMoved(referenceId, pos); // result.second
}
else
cancelDrag();
} }
else else
cancelDrag(); // FIXME: does not allow editing if terrain not visible cancelDrag(); // FIXME: does not allow editing if terrain not visible

View file

@ -282,16 +282,17 @@ namespace CSVWorld
} }
std::pair<std::string, float> PhysicsSystem::distToGround(const Ogre::Vector3 &position, std::pair<std::string, float> PhysicsSystem::distToGround(const Ogre::Vector3 &position,
Ogre::Camera *camera) Ogre::Camera *camera, const float limit, bool ignorePgPoint)
{ {
btVector3 _from, _to; btVector3 _from, _to;
_from = btVector3(position.x, position.y, position.z); _from = btVector3(position.x, position.y, position.z);
_to = btVector3(position.x, position.y, position.z-300000); _to = btVector3(position.x, position.y, position.z-limit);
uint32_t visibilityMask = camera->getViewport()->getVisibilityMask(); uint32_t visibilityMask = camera->getViewport()->getVisibilityMask();
bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain);
bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference);
bool ignorePathgrid = !(visibilityMask & (uint32_t)CSVRender::Element_Pathgrid); bool ignorePathgrid = ignorePgPoint ||
!(visibilityMask & (uint32_t)CSVRender::Element_Pathgrid);
std::pair<std::string, float> result = std::make_pair("", -1); std::pair<std::string, float> result = std::make_pair("", -1);
short mask = OEngine::Physic::CollisionType_Raycasting; short mask = OEngine::Physic::CollisionType_Raycasting;
@ -315,73 +316,21 @@ namespace CSVWorld
if(result.first == "") if(result.first == "")
return std::make_pair("", -1); return std::make_pair("", -1);
else else
return std::make_pair(result.first, 300000*result.second); return std::make_pair(result.first, limit*result.second);
} }
// FIXME: remove code duplication // tries to find the distance to the "top" of the closest object
std::pair<std::string, float> PhysicsSystem::distToClosest(const Ogre::Vector3 &position, std::pair<std::string, float> PhysicsSystem::distToClosest(const Ogre::Vector3 &position,
Ogre::Camera *camera, const float limit) Ogre::Camera *camera, const float limit)
{ {
uint32_t visibilityMask = camera->getViewport()->getVisibilityMask(); const float thickness = 50; // arbitrary number
bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain);
bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference);
bool ignorePathgrid = !(visibilityMask & (uint32_t)CSVRender::Element_Pathgrid);
short mask = OEngine::Physic::CollisionType_Raycasting; std::pair<std::string, float> resDown =
distToGround(Ogre::Vector3(position.x, position.y, position.z+thickness),
btVector3 _from, _to; camera, limit+thickness, true);
_from = btVector3(position.x, position.y, position.z);
_to = btVector3(position.x, position.y, position.z-limit);
std::pair<std::string, float> resDown = std::make_pair("", -1);
std::vector<std::pair<float, std::string> > objectsDown = mEngine->rayTest2(_from, _to, mask);
for (std::vector<std::pair<float, std::string> >::iterator it = objectsDown.begin();
it != objectsDown.end(); ++it)
{
if(ignorePathgrid && QString((*it).second.c_str()).contains(QRegExp("^Pathgrid")))
continue;
else if(ignoreObjects && QString((*it).second.c_str()).contains(QRegExp("^ref#")))
continue;
else if(ignoreHeightMap && QString((*it).second.c_str()).contains(QRegExp("^Height")))
continue;
resDown = std::make_pair((*it).second, (*it).first);
break;
}
_to = btVector3(position.x, position.y, position.z+limit);
std::pair<std::string, float> resUp = std::make_pair("", -1);
std::vector<std::pair<float, std::string> > objectsUp = mEngine->rayTest2(_from, _to, mask);
for (std::vector<std::pair<float, std::string> >::iterator it = objectsDown.begin();
it != objectsDown.end(); ++it)
{
if(ignorePathgrid && QString((*it).second.c_str()).contains(QRegExp("^Pathgrid")))
continue;
else if(ignoreObjects && QString((*it).second.c_str()).contains(QRegExp("^ref#")))
continue;
else if(ignoreHeightMap && QString((*it).second.c_str()).contains(QRegExp("^Height")))
continue;
resUp = std::make_pair((*it).second, (*it).first);
break;
}
if(resDown.first != "") if(resDown.first != "")
{ return std::make_pair(resDown.first, resDown.second-thickness);
if(resUp.first != "")
{
if(fabs(resUp.second) < fabs(resDown.second))
return std::make_pair(resUp.first, -limit*resUp.second);
else
return std::make_pair(resDown.first, limit*resDown.second);
}
else
return std::make_pair(resDown.first, limit*resDown.second);
}
else if(resUp.first != "")
return std::make_pair(resUp.first, -limit*resUp.second);
else else
return std::make_pair("", -1); return std::make_pair("", -1);
} }

View file

@ -74,10 +74,10 @@ namespace CSVWorld
float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera); float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera);
std::pair<std::string, float> distToGround(const Ogre::Vector3 &position, std::pair<std::string, float> distToGround(const Ogre::Vector3 &position,
Ogre::Camera *camera); Ogre::Camera *camera, const float limit = 300000, bool ignorePgPoint = false);
std::pair<std::string, float> distToClosest(const Ogre::Vector3 &position, std::pair<std::string, float> distToClosest(const Ogre::Vector3 &position,
Ogre::Camera *camera, const float limit = 300.0f); Ogre::Camera *camera, const float limit = 100.0f);
std::string sceneNodeToRefId(std::string sceneNodeName); std::string sceneNodeToRefId(std::string sceneNodeName);