From 3eb556ff8ac7bf756ae5c2e2b5a6c4e5d2b6622a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 11 Nov 2014 19:40:04 +1100 Subject: [PATCH] Enhanced snap functionality for pathgrid points. --- apps/opencs/view/render/mousestate.cpp | 31 ++++------ apps/opencs/view/world/physicssystem.cpp | 73 ++++-------------------- apps/opencs/view/world/physicssystem.hpp | 4 +- 3 files changed, 25 insertions(+), 83 deletions(-) diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp index 8f254f08d4..c9fcdbc867 100644 --- a/apps/opencs/view/render/mousestate.cpp +++ b/apps/opencs/view/render/mousestate.cpp @@ -236,29 +236,22 @@ namespace CSVRender // FIXME: move pathgrid point, but don't save yet (need pathgrid // table feature & its data structure to be completed) // Also need to signal PathgridPoint object of change - std::pair result = - anyUnderCursor(event->x(), event->y()); + std::pair result = + mPhysics->distToClosest(pos, getCamera(), 600); // snap std::string refId = mPhysics->sceneNodeToRefId(result.first); + if(result.first != "" && // don't allow pathgrid points under the cursor !QString(refId.c_str()).contains(QRegExp("^Pathgrid"))) { - // snap (defaults to 300 or less) - // FIXME: sticks to the underside of the object if snapping up - std::pair res = - mPhysics->distToClosest(pos, getCamera(), 500); - if(res.first != "") - { - pos.z -= res.second; - // FIXME: rather than just updating at the end, should - // consider providing visual feedback of terrain height - // 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(); + pos.z -= result.second; + pos.z += 2; // arbitrary number, lift up slightly (maybe change the nif?) + // FIXME: rather than just updating at the end, should + // consider providing visual feedback of terrain height + // 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(); // FIXME: does not allow editing if terrain not visible diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index 358bb90ca0..9ff945829a 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -282,16 +282,17 @@ namespace CSVWorld } std::pair PhysicsSystem::distToGround(const Ogre::Vector3 &position, - Ogre::Camera *camera) + Ogre::Camera *camera, const float limit, bool ignorePgPoint) { btVector3 _from, _to; _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(); bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); 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 result = std::make_pair("", -1); short mask = OEngine::Physic::CollisionType_Raycasting; @@ -315,73 +316,21 @@ namespace CSVWorld if(result.first == "") return std::make_pair("", -1); 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 PhysicsSystem::distToClosest(const Ogre::Vector3 &position, Ogre::Camera *camera, const float limit) { - uint32_t visibilityMask = camera->getViewport()->getVisibilityMask(); - bool ignoreHeightMap = !(visibilityMask & (uint32_t)CSVRender::Element_Terrain); - bool ignoreObjects = !(visibilityMask & (uint32_t)CSVRender::Element_Reference); - bool ignorePathgrid = !(visibilityMask & (uint32_t)CSVRender::Element_Pathgrid); + const float thickness = 50; // arbitrary number - short mask = OEngine::Physic::CollisionType_Raycasting; - - btVector3 _from, _to; - _from = btVector3(position.x, position.y, position.z); - _to = btVector3(position.x, position.y, position.z-limit); - - std::pair resDown = std::make_pair("", -1); - std::vector > objectsDown = mEngine->rayTest2(_from, _to, mask); - - for (std::vector >::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 resUp = std::make_pair("", -1); - std::vector > objectsUp = mEngine->rayTest2(_from, _to, mask); - - for (std::vector >::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; - } + std::pair resDown = + distToGround(Ogre::Vector3(position.x, position.y, position.z+thickness), + camera, limit+thickness, true); if(resDown.first != "") - { - 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); + return std::make_pair(resDown.first, resDown.second-thickness); else return std::make_pair("", -1); } diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index 6436b87431..589dca9c5b 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -74,10 +74,10 @@ namespace CSVWorld float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera); std::pair distToGround(const Ogre::Vector3 &position, - Ogre::Camera *camera); + Ogre::Camera *camera, const float limit = 300000, bool ignorePgPoint = false); std::pair 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);