From 9337d6533aa57dbc0130a3c163bce26479cd1251 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 25 Oct 2014 22:09:19 +1100 Subject: [PATCH] Add terrain collision. Support visibility mask for objects and terrain. --- apps/opencs/view/render/cell.cpp | 10 ++++++ .../view/render/pagedworldspacewidget.cpp | 32 ++++++++++++------- apps/opencs/view/world/physicssystem.cpp | 11 +++++-- apps/opencs/view/world/physicssystem.hpp | 6 +++- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 9ff24780c..d414498db 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -5,10 +5,12 @@ #include #include +#include #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" +#include "../world/physicssystem.hpp" #include "elements.hpp" #include "terrainstorage.hpp" @@ -81,6 +83,14 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const ESM::Land* esmLand = land.getRecord(mId).get().mLand.get(); mTerrain->loadCell(esmLand->mX, esmLand->mY); + + if(esmLand) + { + float verts = ESM::Land::LAND_SIZE; + float worldsize = ESM::Land::REAL_SIZE; + CSVWorld::PhysicsSystem::instance()->addHeightField( + esmLand->mLandData->mHeights, esmLand->mX, esmLand->mY, 0, worldsize / (verts-1), verts); + } } } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 2bb95912b..c48358ce1 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -187,29 +187,36 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) } } - CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); - bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false; - if(!debug) - return; - // mouse picking // FIXME: need to virtualise mouse buttons + CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); + bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false; + if(!debug || !getCamera()->getViewport()) + return; + + if(!((uint32_t)getCamera()->getViewport()->getVisibilityMask() & (uint32_t)CSVRender::Element_Reference)) + return; + int viewportWidth = getCamera()->getViewport()->getActualWidth(); int viewportHeight = getCamera()->getViewport()->getActualHeight(); float mouseX = (float) event->x()/viewportWidth; 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 CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); - std::pair result = - CSVWorld::PhysicsSystem::instance()->castRay(mouseX, mouseY, NULL, NULL, getCamera()); + std::pair result = CSVWorld::PhysicsSystem::instance()->castRay( + mouseX, mouseY, NULL, NULL, getCamera(), ignoreHeightMap); if(result.first) { std::cout << "ReferenceId: " << result.second << std::endl; const CSMWorld::CellRef& cellref = mDocument.getData().getReferences().getRecord (result.second).get(); - //std::cout << "CellRef mId: " << cellref.mId << std::endl; // Same as ReferenceId - std::cout << "CellRef mCell: " << cellref.mCell << std::endl; + //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.second); @@ -248,8 +255,11 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event if(!debug) return; - // Need to set scene manager each time in case there are multiple subviews - CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); + // FIXME: OEngine::PhysicEngine creates only one child scene node for the + // debug drawer. Hence only the first subview that creates the debug drawer + // can view the debug lines. Will need to keep a map in OEngine if multiple + // subviews are to be supported. + //CSVWorld::PhysicsSystem::instance()->setSceneManager(getSceneManager()); CSVWorld::PhysicsSystem::instance()->toggleDebugRendering(); flagAsModified(); } diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index 6db38dd87..f5f82c033 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -146,6 +146,12 @@ namespace CSVWorld mEngine->deleteRigidBody(name); } + void PhysicsSystem::addHeightField(float* heights, int x, int y, float yoffset, + float triSize, float sqrtVerts) + { + mEngine->addHeightField(heights, x, y, yoffset, triSize, sqrtVerts); + } + void PhysicsSystem::toggleDebugRendering() { CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); @@ -158,7 +164,7 @@ namespace CSVWorld } std::pair PhysicsSystem::castRay(float mouseX, float mouseY, - Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera) + Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera, bool ignoreHeightMap) { CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); bool debug = userSettings.setting ("debug/mouse-picking", QString("false")) == "true" ? true : false; @@ -179,8 +185,7 @@ namespace CSVWorld _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - bool raycastingObjectOnly = true; - bool ignoreHeightMap = false; + bool raycastingObjectOnly = true; // FIXME Ogre::Vector3 norm; std::pair result = mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm); diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index 045b7e1d5..2ae17b5e3 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -50,10 +50,14 @@ namespace CSVWorld void removeObject(const std::string &name); + void addHeightField(float* heights, int x, int y, float yoffset, + float triSize, float sqrtVerts); + void toggleDebugRendering(); std::pair castRay(float mouseX, float mouseY, - Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera); + Ogre::Vector3* normal, std::string* hit, + Ogre::Camera *camera, bool ignoreHeightMap); }; }