From 48ecea71036d92752f7a228a21e1c4b93f2d7394 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 10 Nov 2014 22:38:29 +1100 Subject: [PATCH] Simplistic drop-to-ground functionality for pathgrid points. --- apps/opencs/view/render/mousestate.cpp | 17 +++++++---- apps/opencs/view/world/physicssystem.cpp | 37 ++++++++++++++++++++++++ apps/opencs/view/world/physicssystem.hpp | 2 ++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp index 989dbdb912..01f16c3397 100644 --- a/apps/opencs/view/render/mousestate.cpp +++ b/apps/opencs/view/render/mousestate.cpp @@ -236,12 +236,17 @@ namespace CSVRender // move pathgrid point, but don't save yet (need pathgrid // table feature & its data structure to be completed) // FIXME: need to signal PathgridPoint object of change - //std::pair result = - //anyUnderCursor(event->x(), event->y()); - //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"))) + std::pair result = + anyUnderCursor(event->x(), event->y()); + 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"))) { + // drop (does not work if placed below the object/terrain) + // maybe look for closest object/terrain in both directions? + std::pair res = mPhysics->distToGround(pos, getCamera()); + 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 @@ -250,6 +255,8 @@ namespace CSVRender placeObject(mGrabbedSceneNode, pos); // result.second mParent->pathgridMoved(referenceId, pos); // result.second } + else + cancelDrag(); } else { diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index cae5563e6f..55da2e2210 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -281,6 +281,43 @@ namespace CSVWorld } } + std::pair PhysicsSystem::distToGround(Ogre::Vector3 &position, + Ogre::Camera *camera) + { + btVector3 _from, _to; + _from = btVector3(position.x, position.y, position.z); + _to = btVector3(position.x, position.y, position.z-300000); + + 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); + + std::pair result = std::make_pair("", -1); + short mask = OEngine::Physic::CollisionType_Raycasting; + std::vector > objects = mEngine->rayTest2(_from, _to, mask); + + for (std::vector >::iterator it = objects.begin(); + it != objects.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; + + result = std::make_pair((*it).second, (*it).first); + break; + } + + // result.first is the object's referenceId + if(result.first == "") + return std::make_pair("", -1); + else + return std::make_pair(result.first, 300000*result.second); + } + std::string PhysicsSystem::refIdToSceneNode(std::string referenceId, Ogre::SceneManager *sceneMgr) { return mRefIdToSceneNode[referenceId][sceneMgr]; diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index 0036bf769d..f28272532d 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -73,6 +73,8 @@ namespace CSVWorld std::pair castRay(float mouseX, float mouseY, Ogre::SceneManager *sceneMgr, Ogre::Camera *camera); + std::pair distToGround(Ogre::Vector3 &position, Ogre::Camera *camera); + std::string sceneNodeToRefId(std::string sceneNodeName); // for multi-scene manager per physics engine