diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index e2e5aa2e5..828584452 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -68,7 +68,7 @@ opencs_units (view/world opencs_units_noqt (view/world subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate - scripthighlighter idvalidator dialoguecreator + scripthighlighter idvalidator dialoguecreator physicssystem ) opencs_units (view/widget @@ -165,7 +165,7 @@ qt4_wrap_ui(OPENCS_UI_HDR ${OPENCS_UI}) qt4_wrap_cpp(OPENCS_MOC_SRC ${OPENCS_HDR_QT}) qt4_add_resources(OPENCS_RES_SRC ${OPENCS_RES}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${BULLET_INCLUDE_DIRS}) if(APPLE) set (OPENCS_MAC_ICON ${CMAKE_SOURCE_DIR}/files/mac/opencs.icns) @@ -175,6 +175,7 @@ endif(APPLE) add_executable(opencs MACOSX_BUNDLE + ${OENGINE_BULLET} ${OPENCS_SRC} ${OPENCS_UI_HDR} ${OPENCS_MOC_SRC} @@ -203,6 +204,7 @@ target_link_libraries(opencs ${OGRE_STATIC_PLUGINS} ${SHINY_LIBRARIES} ${Boost_LIBRARIES} + ${BULLET_LIBRARIES} ${QT_LIBRARIES} components ) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 9ff24780c..0b24da1ba 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -10,6 +10,8 @@ #include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" +#include "../world/physicssystem.hpp" + #include "elements.hpp" #include "terrainstorage.hpp" @@ -49,7 +51,7 @@ bool CSVRender::Cell::addObjects (int start, int end) std::string id = Misc::StringUtils::lowerCase (references.data ( references.index (i, idColumn)).toString().toUtf8().constData()); - mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false))); + mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false, mPhysics))); modified = true; } } @@ -58,8 +60,8 @@ bool CSVRender::Cell::addObjects (int start, int end) } CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, - const std::string& id, const Ogre::Vector3& origin) -: mData (data), mId (Misc::StringUtils::lowerCase (id)) + const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin) +: mData (data), mId (Misc::StringUtils::lowerCase (id)), mPhysics(physics) { mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode(); mCellNode->setPosition (origin); @@ -82,6 +84,9 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, mTerrain->loadCell(esmLand->mX, esmLand->mY); } + std::cout << "cell pos" + std::to_string(mCellNode->getPosition().x) + + ", " + std::to_string(mCellNode->getPosition().y) + + ", " + std::to_string(mCellNode->getPosition().z) << std::endl; } CSVRender::Cell::~Cell() diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 98056c354..5872cc752 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -23,6 +23,11 @@ namespace CSMWorld class Data; } +namespace CSVWorld +{ + class PhysicsSystem; +} + namespace CSVRender { class Cell @@ -32,6 +37,7 @@ namespace CSVRender Ogre::SceneNode *mCellNode; std::map mObjects; std::auto_ptr mTerrain; + CSVWorld::PhysicsSystem *mPhysics; /// Ignored if cell does not have an object with the given ID. /// @@ -46,7 +52,8 @@ namespace CSVRender public: Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, - const std::string& id, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); + const std::string& id, CSVWorld::PhysicsSystem *physics, + const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0)); ~Cell(); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 359392d81..ede73da16 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -9,6 +9,8 @@ #include "../../model/world/ref.hpp" #include "../../model/world/refidcollection.hpp" +#include "../world/physicssystem.hpp" + #include "elements.hpp" void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node) @@ -73,6 +75,12 @@ void CSVRender::Object::update() { mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model); mObject->setVisibilityFlags (Element_Reference); + + bool placeable = true; // FIXME + mPhysics->addObject("meshes\\" + model, mBase->getName(), /*scale*/1, + mBase->getPosition(), mBase->getOrientation(), 0, 0, false, placeable); + mPhysics->addObject("meshes\\" + model, mBase->getName(), /*scale*/1, + mBase->getPosition(), mBase->getOrientation(), 0, 0, true, placeable); // FIXME: why again with raycasting? } } @@ -110,8 +118,9 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const } CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, - const std::string& id, bool referenceable, bool forceBaseToZero) -: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero) + const std::string& id, bool referenceable, CSVWorld::PhysicsSystem* physics, + bool forceBaseToZero) +: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics) { mBase = cellNode->createChildSceneNode(); @@ -214,4 +223,4 @@ std::string CSVRender::Object::getReferenceId() const std::string CSVRender::Object::getReferenceableId() const { return mReferenceableId; -} \ No newline at end of file +} diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index df39d7393..eba2dc814 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -16,6 +16,11 @@ namespace CSMWorld class CellRef; } +namespace CSVWorld +{ + class PhysicsSystem; +} + namespace CSVRender { class Object @@ -26,6 +31,7 @@ namespace CSVRender Ogre::SceneNode *mBase; NifOgre::ObjectScenePtr mObject; bool mForceBaseToZero; + CSVWorld::PhysicsSystem *mPhysics; /// Not implemented Object (const Object&); @@ -51,7 +57,8 @@ namespace CSVRender public: Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode, - const std::string& id, bool referenceable, bool forceBaseToZero = false); + const std::string& id, bool referenceable, + CSVWorld::PhysicsSystem *physics = NULL, bool forceBaseToZero = false); /// \param forceBaseToZero If this is a reference ignore the coordinates and place /// it at 0, 0, 0 instead. @@ -77,4 +84,4 @@ namespace CSVRender }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 8b143e93f..28c8192a4 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -21,6 +21,7 @@ #include "../../model/world/idtable.hpp" #include "../widget/scenetooltoggle.hpp" +#include "../world/physicssystem.hpp" #include "elements.hpp" @@ -108,7 +109,8 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && mCells.find (*iter)==mCells.end()) { - Cell *cell = new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)); + Cell *cell = new Cell (mDocument.getData(), getSceneManager(), + iter->getId (mWorldspace), getPhysics()); mCells.insert (std::make_pair (*iter, cell)); float height = cell->getTerrainHeightAt(Ogre::Vector3( @@ -191,6 +193,7 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event if(event->button() == Qt::RightButton) { std::cout << "double clicked" << std::endl; + getPhysics()->toggleDebugRendering(); } } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 75b4e9396..eed07f5b6 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -10,7 +10,7 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent) : SceneWidget (parent), mData (data), - mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, true) + mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, getPhysics(), true) { setNavigation (&mOrbit); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 3171e0496..9ab061ca4 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -13,6 +13,8 @@ #include #include +#include "../world/physicssystem.hpp" + #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" @@ -64,6 +66,8 @@ namespace CSVRender mOverlaySystem = OverlaySystem::instance().get(); mSceneMgr->addRenderQueueListener(mOverlaySystem); + mPhysics = new CSVWorld::PhysicsSystem(mSceneMgr); + QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), this, SLOT (update())); @@ -171,6 +175,7 @@ namespace CSVRender if (mSceneMgr) Ogre::Root::getSingleton().destroySceneManager (mSceneMgr); + delete mPhysics; } void SceneWidget::setVisibilityMask (unsigned int mask) @@ -206,6 +211,11 @@ namespace CSVRender return mViewport; } + CSVWorld::PhysicsSystem *SceneWidget::getPhysics() + { + return mPhysics; + } + Ogre::SceneManager *SceneWidget::getSceneManager() { return mSceneMgr; diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 1adbf3f17..a3dd9cc80 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -25,6 +25,11 @@ namespace CSVWidget class SceneToolbar; } +namespace CSVWorld +{ + class PhysicsSystem; +} + namespace CSVRender { class Navigation; @@ -58,6 +63,8 @@ namespace CSVRender Ogre::Viewport *getViewport(); + CSVWorld::PhysicsSystem *getPhysics(); + Ogre::SceneManager *getSceneManager(); Ogre::Camera *getCamera(); @@ -98,6 +105,7 @@ namespace CSVRender Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; Ogre::OverlaySystem *mOverlaySystem; + CSVWorld::PhysicsSystem *mPhysics; Navigation *mNavigation; Lighting *mLighting; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index aab3791fc..8012b1b24 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -56,7 +56,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& update(); - mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId)); + mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, getPhysics())); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, @@ -98,7 +98,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorgetId(); - mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId)); + mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getPhysics())); update(); emit cellChanged(*data.begin()); diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp new file mode 100644 index 000000000..c9f788899 --- /dev/null +++ b/apps/opencs/view/world/physicssystem.cpp @@ -0,0 +1,64 @@ +#include "physicssystem.hpp" + +#include +//#include +//#include + +#include + +namespace CSVWorld +{ + PhysicsSystem::PhysicsSystem(Ogre::SceneManager *sceneMgr) + { + // Create physics. shapeLoader is deleted by the physic engine + NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); + mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); + + mEngine->setSceneManager(sceneMgr); // needed for toggleDebugRendering() + } + + PhysicsSystem::~PhysicsSystem() + { + delete mEngine; + } + + // OpenMW | OpenCS + // Ptr | ? + // ptr.getClass().getModel(ptr) | ? // see Object::update() + // ptr.getRefData().getBaseNode() | ? + // ptr.getCellRef().getScale() | ? + // + // getModel() returns the mesh; each class has its own implementation + // + //void PhysicsSystem::addObject (const Ptr& ptr, bool placeable) + void PhysicsSystem::addObject(const std::string &mesh, + const std::string &name, + float scale, + const Ogre::Vector3 &position, + const Ogre::Quaternion &rotation, + Ogre::Vector3* scaledBoxTranslation, + Ogre::Quaternion* boxRotation, + bool raycasting, + bool placeable) + { +#if 0 + std::string mesh = ptr.getClass().getModel(ptr); + Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); + handleToMesh[node->getName()] = mesh; + mEngine->createAndAdjustRigidBody( + mesh, node->getName(), ptr.getCellRef().getScale(), node->getPosition(), node->getOrientation(), 0, 0, false, placeable); + mEngine->createAndAdjustRigidBody( + mesh, node->getName(), ptr.getCellRef().getScale(), node->getPosition(), node->getOrientation(), 0, 0, true, placeable); +#endif + mEngine->createAndAdjustRigidBody(mesh, name, scale, position, rotation, + 0, 0, false, placeable); + mEngine->createAndAdjustRigidBody(mesh, name, scale, position, rotation, + 0, 0, true, placeable); + } + + void PhysicsSystem::toggleDebugRendering() + { + //mEngine->toggleDebugRendering(); + mEngine->setDebugRenderingMode(1); + } +} diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp new file mode 100644 index 000000000..f96724e1d --- /dev/null +++ b/apps/opencs/view/world/physicssystem.hpp @@ -0,0 +1,48 @@ +#ifndef CSV_WORLD_PHYSICSSYSTEM_H +#define CSV_WORLD_PHYSICSSYSTEM_H + +#include + +namespace Ogre +{ + class Vector3; + class Quaternion; + class SceneManager; +} + +namespace OEngine +{ + namespace Physic + { + class PhysicEngine; + } +} + +namespace CSVWorld +{ + class PhysicsSystem + { + std::map handleToMesh; + OEngine::Physic::PhysicEngine* mEngine; + //Ogre::SceneManager *mSceneMgr; + + public: + + PhysicsSystem(Ogre::SceneManager *sceneMgr); + ~PhysicsSystem(); + + void addObject(const std::string &mesh, + const std::string &name, + float scale, + const Ogre::Vector3 &position, + const Ogre::Quaternion &rotation, + Ogre::Vector3* scaledBoxTranslation = 0, + Ogre::Quaternion* boxRotation = 0, + bool raycasting=false, + bool placeable=false); + + void toggleDebugRendering(); + }; +} + +#endif // CSV_WORLD_PHYSICSSYSTEM_H