diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 0bde541bf..c9245ca9f 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -35,7 +35,7 @@ opencs_hdrs_noqt (model/world opencs_units (model/tools - tools reportmodel mergeoperation + tools reportmodel mergeoperation ) opencs_units_noqt (model/tools @@ -90,7 +90,7 @@ opencs_units (view/render opencs_units_noqt (view/render lighting lightingday lightingnight - lightingbright object cell terrainstorage tagbase cellarrow + lightingbright object cell terrainstorage tagbase cellarrow cellmarker ) opencs_hdrs_noqt (view/render @@ -192,6 +192,7 @@ endif(APPLE) target_link_libraries(openmw-cs ${OSG_LIBRARIES} ${OPENTHREADS_LIBRARIES} + ${OSGTEXT_LIBRARIES} ${OSGUTIL_LIBRARIES} ${OSGVIEWER_LIBRARIES} ${OSGGA_LIBRARIES} diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index bd85c8a14..e7b135891 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -70,6 +70,8 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellNode = new osg::Group; rootNode->addChild(mCellNode); + setCellMarker(); + if (!mDeleted) { CSMWorld::IdTable& references = dynamic_cast ( @@ -303,6 +305,17 @@ void CSVRender::Cell::setCellArrows (int mask) } } +void CSVRender::Cell::setCellMarker() +{ + bool cellExists = false; + int cellIndex = mData.getCells().searchId(mId); + if (cellIndex > -1) + { + cellExists = !mData.getCells().getRecord(cellIndex).isDeleted(); + } + mCellMarker.reset(new CellMarker(mCellNode, mCoordinates, cellExists)); +} + CSMWorld::CellCoordinates CSVRender::Cell::getCoordinates() const { return mCoordinates; diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 85b9bf21b..22f9872e3 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -15,6 +15,7 @@ #include "object.hpp" #include "cellarrow.hpp" +#include "cellmarker.hpp" class QModelIndex; @@ -42,6 +43,7 @@ namespace CSVRender std::auto_ptr mTerrain; CSMWorld::CellCoordinates mCoordinates; std::auto_ptr mCellArrows[4]; + std::auto_ptr mCellMarker; bool mDeleted; /// Ignored if cell does not have an object with the given ID. @@ -105,6 +107,9 @@ namespace CSVRender void setCellArrows (int mask); + /// \brief Set marker for this cell. + void setCellMarker(); + /// Returns 0, 0 in case of an unpaged cell. CSMWorld::CellCoordinates getCoordinates() const; diff --git a/apps/opencs/view/render/cellmarker.cpp b/apps/opencs/view/render/cellmarker.cpp new file mode 100644 index 000000000..e0d270f85 --- /dev/null +++ b/apps/opencs/view/render/cellmarker.cpp @@ -0,0 +1,91 @@ +#include "cellmarker.hpp" + +#include + +#include +#include +#include +#include + +#include "mask.hpp" + +CSVRender::CellMarkerTag::CellMarkerTag(CellMarker *marker) +: TagBase(Mask_CellMarker), mMarker(marker) +{} + +CSVRender::CellMarker *CSVRender::CellMarkerTag::getCellMarker() const +{ + return mMarker; +} + +void CSVRender::CellMarker::buildMarker() +{ + const int characterSize = 20; + + // Set up attributes of marker text. + osg::ref_ptr markerText (new osgText::Text); + markerText->setLayout(osgText::Text::LEFT_TO_RIGHT); + markerText->setCharacterSize(characterSize); + markerText->setAlignment(osgText::Text::CENTER_CENTER); + markerText->setDrawMode(osgText::Text::TEXT | osgText::Text::FILLEDBOUNDINGBOX); + + // If cell exists then show black bounding box otherwise show red. + if (mExists) + { + markerText->setBoundingBoxColor(osg::Vec4f(0.0f, 0.0f, 0.0f, 1.0f)); + } + else + { + markerText->setBoundingBoxColor(osg::Vec4f(1.0f, 0.0f, 0.0f, 1.0f)); + } + + // Add text containing cell's coordinates. + std::string coordinatesText = + boost::lexical_cast(mCoordinates.getX()) + "," + + boost::lexical_cast(mCoordinates.getY()); + markerText->setText(coordinatesText); + + // Add text to marker node. + osg::ref_ptr geode (new osg::Geode); + geode->addDrawable(markerText); + mMarkerNode->addChild(geode); +} + +void CSVRender::CellMarker::positionMarker() +{ + const int cellSize = 8192; + const int markerHeight = 0; + + // Move marker to center of cell. + int x = (mCoordinates.getX() * cellSize) + (cellSize / 2); + int y = (mCoordinates.getY() * cellSize) + (cellSize / 2); + mMarkerNode->setPosition(osg::Vec3f(x, y, markerHeight)); +} + +CSVRender::CellMarker::CellMarker( + osg::Group *cellNode, + const CSMWorld::CellCoordinates& coordinates, + const bool cellExists +) : mCellNode(cellNode), + mCoordinates(coordinates), + mExists(cellExists) +{ + // Set up node for cell marker. + mMarkerNode = new osg::AutoTransform(); + mMarkerNode->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN); + mMarkerNode->setAutoScaleToScreen(true); + mMarkerNode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + + mMarkerNode->setUserData(new CellMarkerTag(this)); + mMarkerNode->setNodeMask(Mask_CellMarker); + + mCellNode->addChild(mMarkerNode); + + buildMarker(); + positionMarker(); +} + +CSVRender::CellMarker::~CellMarker() +{ + mCellNode->removeChild(mMarkerNode); +} diff --git a/apps/opencs/view/render/cellmarker.hpp b/apps/opencs/view/render/cellmarker.hpp new file mode 100644 index 000000000..4246b20b8 --- /dev/null +++ b/apps/opencs/view/render/cellmarker.hpp @@ -0,0 +1,68 @@ +#ifndef OPENCS_VIEW_CELLMARKER_H +#define OPENCS_VIEW_CELLMARKER_H + +#include "tagbase.hpp" + +#include + +#include "../../model/world/cellcoordinates.hpp" + +namespace osg +{ + class AutoTransform; + class Group; +} + +namespace CSVRender +{ + class CellMarker; + + class CellMarkerTag : public TagBase + { + private: + + CellMarker *mMarker; + + public: + + CellMarkerTag(CellMarker *marker); + + CellMarker *getCellMarker() const; + }; + + /// \brief Marker to display cell coordinates. + class CellMarker + { + private: + + osg::Group* mCellNode; + osg::ref_ptr mMarkerNode; + CSMWorld::CellCoordinates mCoordinates; + bool mExists; + + // Not implemented. + CellMarker(const CellMarker&); + CellMarker& operator=(const CellMarker&); + + /// \brief Build marker containing cell's coordinates. + void buildMarker(); + + /// \brief Position marker at center of cell. + void positionMarker(); + + public: + + /// \brief Constructor. + /// \param cellNode Cell to create marker for. + /// \param coordinates Coordinates of cell. + /// \param cellExists Whether or not cell exists. + CellMarker( + osg::Group *cellNode, + const CSMWorld::CellCoordinates& coordinates, + const bool cellExists); + + ~CellMarker(); + }; +} + +#endif