mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-25 05:39:45 +00:00
Enhanced snap functionality for pathgrid points.
This commit is contained in:
parent
407edc770c
commit
3eb556ff8a
3 changed files with 25 additions and 83 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue