From 4dee9604bbac2bb79019a9ae0013d4415444bb75 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 06:29:56 -0400 Subject: [PATCH 01/13] Pathgrid rendering v2 --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/cell.cpp | 46 ++ apps/opencs/view/render/cell.hpp | 14 + .../view/render/pagedworldspacewidget.cpp | 91 ++++ .../view/render/pagedworldspacewidget.hpp | 6 + apps/opencs/view/render/pathgrid.cpp | 474 ++++++++++++++++++ apps/opencs/view/render/pathgrid.hpp | 74 +++ .../view/render/unpagedworldspacewidget.cpp | 77 ++- .../view/render/unpagedworldspacewidget.hpp | 7 + apps/opencs/view/render/worldspacewidget.cpp | 9 + apps/opencs/view/render/worldspacewidget.hpp | 6 + 11 files changed, 804 insertions(+), 2 deletions(-) create mode 100644 apps/opencs/view/render/pathgrid.cpp create mode 100644 apps/opencs/view/render/pathgrid.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 816b8d732..1c04a1263 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -91,7 +91,7 @@ opencs_units (view/render opencs_units_noqt (view/render lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase - cellarrow cellmarker cellborder cameracontroller + cellarrow cellmarker cellborder cameracontroller pathgrid ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 9a352ffad..35f08f836 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -14,6 +14,7 @@ #include "mask.hpp" #include "terrainstorage.hpp" +#include "pathgrid.hpp" bool CSVRender::Cell::removeObject (const std::string& id) { @@ -104,6 +105,11 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellBorder->buildShape(esmLand); } } + + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + mPathgrid.reset(new Pathgrid(mCellNode, pathgrids.getRecord(pathgridIndex).get(), mCoordinates)); } } @@ -254,6 +260,46 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int return addObjects (start, end); } +void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid) +{ + mPathgrid.reset(new Pathgrid(mCellNode, pathgrid, mCoordinates)); +} + +void CSVRender::Cell::pathgridRemoved() +{ + mPathgrid.reset(); +} + +bool CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + if (mPathgrid.get() != 0) + { + return mPathgrid->dataChanged(topLeft, bottomRight); + } + + return false; +} + +bool CSVRender::Cell::pathgridRowAboutToBeRemoved(const QModelIndex& parent, int start, int end) +{ + if (mPathgrid.get() != 0) + { + return mPathgrid->rowAboutToBeRemoved(parent, start, end); + } + + return false; +} + +bool CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end) +{ + if (mPathgrid.get() != 0) + { + return mPathgrid->rowAdded(parent, start, end); + } + + return false; +} + void CSVRender::Cell::setSelection (int elementMask, Selection mode) { if (elementMask & Mask_Reference) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 631df24aa..5f6d33e4a 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -29,12 +29,15 @@ namespace CSMWorld { class Data; class CellCoordinates; + class Pathgrid; } namespace CSVRender { class TagBase; + class Pathgrid; + class Cell { CSMWorld::Data& mData; @@ -46,6 +49,7 @@ namespace CSVRender std::auto_ptr mCellArrows[4]; std::auto_ptr mCellMarker; std::auto_ptr mCellBorder; + std::auto_ptr mPathgrid; bool mDeleted; int mSubMode; unsigned int mSubModeElementMask; @@ -103,6 +107,16 @@ namespace CSVRender /// this cell? bool referenceAdded (const QModelIndex& parent, int start, int end); + void pathgridAdded(const CSMWorld::Pathgrid& pathgrid); + + void pathgridRemoved(); + + bool pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + + bool pathgridRowAboutToBeRemoved(const QModelIndex& parent, int start, int end); + + bool pathgridRowAdded(const QModelIndex& parent, int start, int end); + void setSelection (int elementMask, Selection mode); // Select everything that references the same ID as at least one of the elements diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 22b0e3805..08c6e4f68 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -275,6 +275,97 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } +void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (topLeft.parent().isValid()) + { + int row = topLeft.parent().row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end() && searchResult->second->pathgridDataChanged(topLeft, bottomRight)) + flagAsModified(); + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid going to be deleted + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRemoved(); + flagAsModified(); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRowAboutToBeRemoved(parent, start, end); + flagAsModified(); + } + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid added theoretically, unable to test until it is possible to add pathgrids + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridAdded(pathgrid); + flagAsModified(); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRowAdded(parent, start, end); + flagAsModified(); + } + } +} + std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() { osg::Vec3d eye, center, up; diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 4bdaa3820..1a6db7cbd 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -52,6 +52,12 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + virtual std::string getStartupInstruction(); /// \note Does not update the view or any cell marker diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp new file mode 100644 index 000000000..80f02c4e1 --- /dev/null +++ b/apps/opencs/view/render/pathgrid.cpp @@ -0,0 +1,474 @@ +#include "pathgrid.hpp" + +#include + +#include +#include +#include +#include +#include + +#include + +#include "../../model/world/cellcoordinates.hpp" +#include "../../model/world/idcollection.hpp" +#include "../../model/world/pathgrid.hpp" + +#include "mask.hpp" + +namespace CSVRender +{ + const float Pathgrid::PointShapeSize = 50.f; + + Pathgrid::Pathgrid(osg::Group* parent, const CSMWorld::Pathgrid& pathgrid, const CSMWorld::CellCoordinates& coords) + : mPathgridData(pathgrid) + , mParentNode(parent) + , mBaseNode(new osg::PositionAttitudeTransform()) + , mPointGeometry(new osg::Geometry()) + , mEdgeNode(new osg::Geode()) + { + const int CoordScalar = ESM::Land::REAL_SIZE; + + mParentNode->addChild(mBaseNode); + mBaseNode->setPosition(osg::Vec3(coords.getX() * CoordScalar, coords.getY() * CoordScalar, 0)); + mBaseNode->setNodeMask(Mask_Pathgrid); + mBaseNode->addChild(mEdgeNode); + + constructPointShape(); + buildGrid(); + } + + Pathgrid::~Pathgrid() + { + destroyGrid(); + mBaseNode->removeChild(mEdgeNode); + mParentNode->removeChild(mBaseNode); + } + + bool Pathgrid::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) + { + const int PointColumn = 3; + const int EdgeColumn = 4; + + if (topLeft.parent().isValid()) + { + int start = topLeft.row(); + int end = bottomRight.row(); + + if (topLeft.parent().column() == PointColumn) + { + std::set changedEdges; + + for (int row = start; row <= end; ++row) + { + // Recreate point + destroyEdges(row); + destroyPoint(row); + + buildPoint(row); + changedEdges.insert(row); + + // Correct affected edges + for (unsigned short i = 0; i < mPointData.size(); ++i) + { + PointData& data = mPointData[i]; + for (std::vector::iterator edge = data.edgeList.begin(); + edge != data.edgeList.end(); ++edge) + { + if (*edge == row) + changedEdges.insert(i); + } + } + } + + // Reconstruct edges + for (std::set::iterator index = changedEdges.begin(); + index != changedEdges.end(); ++index) + { + destroyEdges(*index); + buildEdges(*index); + } + + return true; + } + else if (topLeft.parent().column() == EdgeColumn) + { + const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); + const size_t NumEdges = mPathgridData.mEdges.size(); + + std::set changedEdges; + + // Clear edge lists + for (int row = start; row <= end; ++row) + { + mPointData[row].edgeList.clear(); + } + + // Recreate edge lists + for (size_t i = 0; i < NumEdges; ++i) + { + const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; + unsigned short v0 = static_cast(edge.mV0); + unsigned short v1 = static_cast(edge.mV1); + + if ((v0 >= start && v0 <= end) && (v0 != v1 && v0 < NumPoints && v1 < NumPoints)) + mPointData[v0].edgeList.push_back(v1); + } + + // Reconstruct edges + for (int row = start; row <= end; ++row) + { + destroyEdges(row); + buildEdges(row); + } + + return true; + } + } + + return false; + } + + bool Pathgrid::rowAboutToBeRemoved(const QModelIndex& parent, int start, int end) + { + const int PointColumn = 3; + const int EdgeColumn = 4; + + if (!parent.parent().isValid()) + { + if (parent.column() == PointColumn) + { + // Dangling edges will be removed and edges past start decremented + for (size_t i = 0; i < mPointData.size(); ++i) + { + PointData& data = mPointData[i]; + + // They are getting removed anyway + if (i >= (size_t) start && i <= (size_t) end) + continue; + + bool modified = false; + + for (std::vector::iterator edge = data.edgeList.begin(); + edge != data.edgeList.end();) + { + if (*edge >= start && *edge <= end) + { + edge = data.edgeList.erase(edge); + modified = true; + } + else + { + ++edge; + } + } + + // Need to do this before modifying the rest + if (modified) + { + destroyEdges(i); + buildEdges(i); + } + + for (std::vector::iterator edge = data.edgeList.begin(); + edge != data.edgeList.end(); ++edge) + { + if (*edge > end) + --(*edge); + } + } + + // Remove points + for (int i = start; i <= end; ++i) + { + destroyEdges(static_cast(start)); + destroyPoint(static_cast(start)); + mPointData.erase(mPointData.begin() + start); + } + + return true; + } + else if (parent.column() == EdgeColumn) + { + std::set changedEdges; + + // Remove affected edges + for (int i = start; i <= end; ++i) + { + const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; + unsigned short v0 = static_cast(edge.mV0); + unsigned short v1 = static_cast(edge.mV1); + + // Only remove one + for (std::vector::iterator it = mPointData[v0].edgeList.begin(); + it != mPointData[v1].edgeList.end(); ++it) + { + if (*it == v1) + { + mPointData[v0].edgeList.erase(it); + changedEdges.insert(v0); + break; + } + } + } + + // Reconstruct edges + for (std::set::iterator index = changedEdges.begin(); + index != changedEdges.end(); ++index) + { + destroyEdges(*index); + buildEdges(*index); + } + } + } + + return false; + } + + bool Pathgrid::rowAdded(const QModelIndex& parent, int start, int end) + { + const int PointColumn = 3; + const int EdgeColumn = 4; + + if (!parent.parent().isValid()) + { + if (parent.column() == PointColumn) + { + // Edges at and beyond start point have been incremented + for (std::vector::iterator point = mPointData.begin(); point != mPointData.end(); ++point) + { + for (std::vector::iterator edge = point->edgeList.begin(); + edge != point->edgeList.end(); ++edge) + { + if (*edge >= start) + *edge += end - start + 1; + } + } + + // Add points + mPointData.insert(mPointData.begin() + start, end - start + 1, PointData()); + for (int row = start; row <= end; ++row) + buildPoint(static_cast(row)); + + return true; + } + else if (parent.column() == EdgeColumn) + { + const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); + + std::set changedEdges; + + // Add edges + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[row]; + unsigned short v0 = static_cast(edge.mV0); + unsigned short v1 = static_cast(edge.mV1); + + if (v0 != v1 && v0 < NumPoints && v1 < NumPoints) + { + mPointData[v0].edgeList.push_back(v1); + changedEdges.insert(v0); + } + } + + // Reconstruct edges + for (std::set::iterator index = changedEdges.begin(); + index != changedEdges.end(); ++index) + { + destroyEdges(*index); + buildEdges(*index); + } + } + } + + return false; + } + + void Pathgrid::constructPointShape() + { + // Construct a diamond + const unsigned short VertexCount = 24; + + const osg::Vec3f ShapePoints[6] = + { + osg::Vec3f( 0.f, 0.f, PointShapeSize), + osg::Vec3f(-PointShapeSize/2, -PointShapeSize/2, 0.f), + osg::Vec3f(-PointShapeSize/2, PointShapeSize/2, 0.f), + osg::Vec3f( PointShapeSize/2, -PointShapeSize/2, 0.f), + osg::Vec3f( PointShapeSize/2, PointShapeSize/2, 0.f), + osg::Vec3f( 0.f, 0.f, -PointShapeSize) + }; + + const unsigned short ShapeIndices[VertexCount] = + { + 0, 2, 1, + 0, 1, 3, + 0, 3, 4, + 0, 4, 2, + 5, 1, 2, + 5, 3, 1, + 5, 4, 3, + 5, 2, 4 + }; + + osg::ref_ptr vertexArray = new osg::Vec3Array(); + osg::ref_ptr normalArray = new osg::Vec3Array(); + osg::ref_ptr colorArray = new osg::Vec4Array(); + osg::ref_ptr indexArray = new osg::DrawElementsUShort( + osg::PrimitiveSet::TRIANGLES, 24); + + for (unsigned short i = 0; i < VertexCount; ++i) + { + vertexArray->push_back(ShapePoints[ShapeIndices[i]]); + indexArray->setElement(i, i); + } + + for (unsigned short i = 0; i < VertexCount; i += 3) + { + osg::Vec3f v1 = vertexArray->at(i+1) - vertexArray->at(i); + osg::Vec3f v2 = vertexArray->at(i+2) - vertexArray->at(i); + osg::Vec3f normal = v1 ^ v2; + + normalArray->push_back(normal); + normalArray->push_back(normal); + normalArray->push_back(normal); + } + + colorArray->push_back(osg::Vec4f(1.f, 0.f, 0.f, 1.f)); + + mPointGeometry->setVertexArray(vertexArray); + mPointGeometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); + mPointGeometry->setColorArray(colorArray, osg::Array::BIND_OVERALL); + mPointGeometry->addPrimitiveSet(indexArray); + } + + void Pathgrid::buildGrid() + { + // Note: the number of pathgrid points is limited to the capacity of a signed short + const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); + const size_t NumEdges = mPathgridData.mEdges.size(); + + // Make points + mPointData.resize(NumPoints); + for (unsigned short i = 0; i < NumPoints; ++i) + buildPoint(i); + + // Add edges to list + for (size_t i = 0; i < NumEdges; ++i) + { + const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; + unsigned short v0 = static_cast(edge.mV0); + unsigned short v1 = static_cast(edge.mV1); + + if (v0 != v1 && v0 < NumPoints && v1 < NumPoints) + mPointData[v0].edgeList.push_back(v1); + } + + // Make edges + for (unsigned short i = 0; i < NumPoints; ++i) + buildEdges(i); + } + + void Pathgrid::destroyGrid() + { + const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); + + for (unsigned short i = 0; i < NumPoints; ++i) + { + destroyEdges(i); + destroyPoint(i); + } + + mPointData.clear(); + } + + void Pathgrid::buildPoint(unsigned short index) + { + const CSMWorld::Pathgrid::Point& source = mPathgridData.mPoints[index]; + PointData& data = mPointData[index]; + + data.posNode = new osg::PositionAttitudeTransform(); + data.posNode->setPosition(osg::Vec3f(source.mX, source.mY, source.mZ)); + mBaseNode->addChild(data.posNode); + + osg::ref_ptr pointNode = new osg::Geode(); + pointNode->addDrawable(mPointGeometry); + data.posNode->addChild(pointNode); + + data.edgeGeometry = new osg::Geometry(); + mEdgeNode->addDrawable(data.edgeGeometry); + } + + void Pathgrid::destroyPoint(unsigned short index) + { + PointData& data = mPointData[index]; + + mBaseNode->removeChild(data.posNode); + data.posNode = 0; + + mEdgeNode->removeDrawable(data.edgeGeometry); + data.edgeGeometry = 0; + } + + void Pathgrid::buildEdges(unsigned short index) + { + // Note: the number of edges per point is limited to the capacity of an unsigned char + const unsigned short VertexCount = static_cast(mPointData[index].edgeList.size() * 2); + const osg::Quat DefaultRotation = osg::Quat(osg::PI / 2.f, osg::Vec3f(0.f, 0.f, 1.f)); + const osg::Vec3f DefaultDirection = osg::Vec3f(0.f, 1.f, 0.f); + const osg::Vec3f Offset = osg::Vec3f(0.f, 0.f, 10.f); + const osg::Vec4f StartColor = osg::Vec4f(1.f, 0.f, 0.f, 1.f); + const osg::Vec4f EndColor = osg::Vec4f(1.f, 0.5f, 0.f, 1.f); + + if (VertexCount == 0) + return; + + // Construct geometry + osg::ref_ptr vertexArray = new osg::Vec3Array(); + osg::ref_ptr colorArray = new osg::Vec4Array(); + osg::ref_ptr indexArray = new osg::DrawElementsUShort( + osg::PrimitiveSet::LINES, VertexCount); + + for (unsigned short i = 0; i < VertexCount; i += 2) + { + const std::vector& edges = mPointData[index].edgeList; + + const CSMWorld::Pathgrid::Point& originPoint = mPathgridData.mPoints[index]; + const CSMWorld::Pathgrid::Point& destPoint = mPathgridData.mPoints[edges[i / 2]]; + + osg::Vec3f origin = osg::Vec3f(originPoint.mX, originPoint.mY, originPoint.mZ); + osg::Vec3f destination = osg::Vec3f(destPoint.mX, destPoint.mY, destPoint.mZ); + osg::Vec3f direction = destination - origin; + + direction.z() = 0; + direction.normalize(); + + // In case the x,y coordinates are too similar + if (direction.isNaN()) + direction = DefaultDirection; + + vertexArray->push_back(origin + Offset + DefaultRotation.inverse() * direction * 0.33f * PointShapeSize); + vertexArray->push_back(destination+ Offset - DefaultRotation * direction * 0.33f * PointShapeSize); + colorArray->push_back(StartColor); + colorArray->push_back(EndColor); + indexArray->setElement(i, i); + indexArray->setElement(i + 1, i + 1); + } + + osg::ref_ptr edgeGeometry = mPointData[index].edgeGeometry; + edgeGeometry->setVertexArray(vertexArray); + edgeGeometry->setColorArray(colorArray, osg::Array::BIND_PER_VERTEX); + edgeGeometry->addPrimitiveSet(indexArray); + edgeGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + } + + void Pathgrid::destroyEdges(unsigned short index) + { + PointData& data = mPointData[index]; + + data.edgeGeometry->setVertexArray(0); + data.edgeGeometry->setColorArray(0); + data.edgeGeometry->getPrimitiveSetList().clear(); + } +} diff --git a/apps/opencs/view/render/pathgrid.hpp b/apps/opencs/view/render/pathgrid.hpp new file mode 100644 index 000000000..589614a8f --- /dev/null +++ b/apps/opencs/view/render/pathgrid.hpp @@ -0,0 +1,74 @@ +#ifndef OPENCS_VIEW_PATHGRID_H +#define OPENCS_VIEW_PATHGRID_H + +#include + +#include +#include + +namespace osg +{ + class Geode; + class Geometry; + class Group; + class PositionAttitudeTransform; +} + +namespace CSMWorld +{ + struct Pathgrid; + class CellCoordinates; +} + +namespace CSVRender +{ + class Pathgrid + { + public: + + Pathgrid(osg::Group* parent, const CSMWorld::Pathgrid& pathgrid, const CSMWorld::CellCoordinates& coords); + ~Pathgrid(); + + bool dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + + bool rowAboutToBeRemoved(const QModelIndex& parent, int start, int end); + + bool rowAdded(const QModelIndex& parent, int start, int end); + + private: + + struct PointData + { + osg::ref_ptr posNode; + std::vector edgeList; + osg::ref_ptr edgeGeometry; + }; + + static const float PointShapeSize; + + const CSMWorld::Pathgrid& mPathgridData; + std::vector mPointData; + + osg::ref_ptr mParentNode; + osg::ref_ptr mBaseNode; + osg::ref_ptr mPointGeometry; + osg::ref_ptr mEdgeNode; + + void constructPointShape(); + + void buildGrid(); + void destroyGrid(); + + void buildPoint(unsigned short index); + void destroyPoint(unsigned short index); + + void buildEdges(unsigned short index); + void destroyEdges(unsigned short index); + + // Not implemented + Pathgrid(const Pathgrid&); + Pathgrid& operator=(const Pathgrid&); + }; +} + +#endif diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 79ffd4fb0..c7e875c18 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -32,7 +32,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() } CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent) -: WorldspaceWidget (document, parent), mCellId (cellId) +: WorldspaceWidget (document, parent), mDocument(document), mCellId (cellId) { mCellsModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); @@ -197,6 +197,81 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare flagAsModified(); } +void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (topLeft.parent().isValid()) + { + int row = topLeft.parent().row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId && mCell->pathgridDataChanged(topLeft, bottomRight)) + flagAsModified(); + } +} + +void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid going to be deleted + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRemoved(); + flagAsModified(); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRowAboutToBeRemoved(parent, start, end); + flagAsModified(); + } + } +} + +void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid added theoretically, unable to test until it is possible to add pathgrids + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridAdded(pathgrid); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRowAdded(parent, start, end); + flagAsModified(); + } + } +} + void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons ( CSVWidget::SceneToolToggle2 *tool) { diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index c5bfd22e6..24b511c4c 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -25,6 +25,7 @@ namespace CSVRender { Q_OBJECT + CSMDoc::Document& mDocument; std::string mCellId; CSMWorld::IdTable *mCellsModel; CSMWorld::IdTable *mReferenceablesModel; @@ -83,6 +84,12 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + virtual std::string getStartupInstruction(); protected: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 927ce545f..fa5fd0bee 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -59,6 +59,15 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (referenceAdded (const QModelIndex&, int, int))); + QAbstractItemModel *pathgrids = document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrids); + + connect (pathgrids, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (pathgridDataChanged (const QModelIndex&, const QModelIndex&))); + connect (pathgrids, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (pathgridAboutToBeRemoved (const QModelIndex&, int, int))); + connect (pathgrids, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (pathgridAdded (const QModelIndex&, int, int))); + QAbstractItemModel *debugProfiles = document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index b18123944..bc528f52d 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -228,6 +228,12 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0; + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end) = 0; + virtual void runRequest (const std::string& profile); void debugProfileDataChanged (const QModelIndex& topLeft, From 933504dbd03a9a134adeb160eec43e9d8e97c003 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 15:37:08 -0400 Subject: [PATCH 02/13] Revert "Pathgrid rendering v2" This reverts commit 4dee9604bbac2bb79019a9ae0013d4415444bb75. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/cell.cpp | 46 -- apps/opencs/view/render/cell.hpp | 14 - .../view/render/pagedworldspacewidget.cpp | 91 ---- .../view/render/pagedworldspacewidget.hpp | 6 - apps/opencs/view/render/pathgrid.cpp | 474 ------------------ apps/opencs/view/render/pathgrid.hpp | 74 --- .../view/render/unpagedworldspacewidget.cpp | 77 +-- .../view/render/unpagedworldspacewidget.hpp | 7 - apps/opencs/view/render/worldspacewidget.cpp | 9 - apps/opencs/view/render/worldspacewidget.hpp | 6 - 11 files changed, 2 insertions(+), 804 deletions(-) delete mode 100644 apps/opencs/view/render/pathgrid.cpp delete mode 100644 apps/opencs/view/render/pathgrid.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1c04a1263..816b8d732 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -91,7 +91,7 @@ opencs_units (view/render opencs_units_noqt (view/render lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase - cellarrow cellmarker cellborder cameracontroller pathgrid + cellarrow cellmarker cellborder cameracontroller ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 35f08f836..9a352ffad 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -14,7 +14,6 @@ #include "mask.hpp" #include "terrainstorage.hpp" -#include "pathgrid.hpp" bool CSVRender::Cell::removeObject (const std::string& id) { @@ -105,11 +104,6 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellBorder->buildShape(esmLand); } } - - const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); - int pathgridIndex = pathgrids.searchId(mId); - if (pathgridIndex != -1) - mPathgrid.reset(new Pathgrid(mCellNode, pathgrids.getRecord(pathgridIndex).get(), mCoordinates)); } } @@ -260,46 +254,6 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int return addObjects (start, end); } -void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid) -{ - mPathgrid.reset(new Pathgrid(mCellNode, pathgrid, mCoordinates)); -} - -void CSVRender::Cell::pathgridRemoved() -{ - mPathgrid.reset(); -} - -bool CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) -{ - if (mPathgrid.get() != 0) - { - return mPathgrid->dataChanged(topLeft, bottomRight); - } - - return false; -} - -bool CSVRender::Cell::pathgridRowAboutToBeRemoved(const QModelIndex& parent, int start, int end) -{ - if (mPathgrid.get() != 0) - { - return mPathgrid->rowAboutToBeRemoved(parent, start, end); - } - - return false; -} - -bool CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end) -{ - if (mPathgrid.get() != 0) - { - return mPathgrid->rowAdded(parent, start, end); - } - - return false; -} - void CSVRender::Cell::setSelection (int elementMask, Selection mode) { if (elementMask & Mask_Reference) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 5f6d33e4a..631df24aa 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -29,15 +29,12 @@ namespace CSMWorld { class Data; class CellCoordinates; - class Pathgrid; } namespace CSVRender { class TagBase; - class Pathgrid; - class Cell { CSMWorld::Data& mData; @@ -49,7 +46,6 @@ namespace CSVRender std::auto_ptr mCellArrows[4]; std::auto_ptr mCellMarker; std::auto_ptr mCellBorder; - std::auto_ptr mPathgrid; bool mDeleted; int mSubMode; unsigned int mSubModeElementMask; @@ -107,16 +103,6 @@ namespace CSVRender /// this cell? bool referenceAdded (const QModelIndex& parent, int start, int end); - void pathgridAdded(const CSMWorld::Pathgrid& pathgrid); - - void pathgridRemoved(); - - bool pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - - bool pathgridRowAboutToBeRemoved(const QModelIndex& parent, int start, int end); - - bool pathgridRowAdded(const QModelIndex& parent, int start, int end); - void setSelection (int elementMask, Selection mode); // Select everything that references the same ID as at least one of the elements diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 08c6e4f68..22b0e3805 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -275,97 +275,6 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (topLeft.parent().isValid()) - { - int row = topLeft.parent().row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); - - std::map::iterator searchResult = mCells.find(coords); - if (searchResult != mCells.end() && searchResult->second->pathgridDataChanged(topLeft, bottomRight)) - flagAsModified(); - } -} - -void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (!parent.isValid()) - { - // Pathgrid going to be deleted - for (int row = start; row <= end; ++row) - { - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); - - std::map::iterator searchResult = mCells.find(coords); - if (searchResult != mCells.end()) - { - searchResult->second->pathgridRemoved(); - flagAsModified(); - } - } - } - else - { - // Pathgrid data was modified - int row = parent.row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); - - std::map::iterator searchResult = mCells.find(coords); - if (searchResult != mCells.end()) - { - searchResult->second->pathgridRowAboutToBeRemoved(parent, start, end); - flagAsModified(); - } - } -} - -void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (!parent.isValid()) - { - // Pathgrid added theoretically, unable to test until it is possible to add pathgrids - for (int row = start; row <= end; ++row) - { - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); - - std::map::iterator searchResult = mCells.find(coords); - if (searchResult != mCells.end()) - { - searchResult->second->pathgridAdded(pathgrid); - flagAsModified(); - } - } - } - else - { - // Pathgrid data was modified - int row = parent.row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); - - std::map::iterator searchResult = mCells.find(coords); - if (searchResult != mCells.end()) - { - searchResult->second->pathgridRowAdded(parent, start, end); - flagAsModified(); - } - } -} - std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() { osg::Vec3d eye, center, up; diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 1a6db7cbd..4bdaa3820 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -52,12 +52,6 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); - - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); - - virtual void pathgridAdded (const QModelIndex& parent, int start, int end); - virtual std::string getStartupInstruction(); /// \note Does not update the view or any cell marker diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp deleted file mode 100644 index 80f02c4e1..000000000 --- a/apps/opencs/view/render/pathgrid.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include "pathgrid.hpp" - -#include - -#include -#include -#include -#include -#include - -#include - -#include "../../model/world/cellcoordinates.hpp" -#include "../../model/world/idcollection.hpp" -#include "../../model/world/pathgrid.hpp" - -#include "mask.hpp" - -namespace CSVRender -{ - const float Pathgrid::PointShapeSize = 50.f; - - Pathgrid::Pathgrid(osg::Group* parent, const CSMWorld::Pathgrid& pathgrid, const CSMWorld::CellCoordinates& coords) - : mPathgridData(pathgrid) - , mParentNode(parent) - , mBaseNode(new osg::PositionAttitudeTransform()) - , mPointGeometry(new osg::Geometry()) - , mEdgeNode(new osg::Geode()) - { - const int CoordScalar = ESM::Land::REAL_SIZE; - - mParentNode->addChild(mBaseNode); - mBaseNode->setPosition(osg::Vec3(coords.getX() * CoordScalar, coords.getY() * CoordScalar, 0)); - mBaseNode->setNodeMask(Mask_Pathgrid); - mBaseNode->addChild(mEdgeNode); - - constructPointShape(); - buildGrid(); - } - - Pathgrid::~Pathgrid() - { - destroyGrid(); - mBaseNode->removeChild(mEdgeNode); - mParentNode->removeChild(mBaseNode); - } - - bool Pathgrid::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) - { - const int PointColumn = 3; - const int EdgeColumn = 4; - - if (topLeft.parent().isValid()) - { - int start = topLeft.row(); - int end = bottomRight.row(); - - if (topLeft.parent().column() == PointColumn) - { - std::set changedEdges; - - for (int row = start; row <= end; ++row) - { - // Recreate point - destroyEdges(row); - destroyPoint(row); - - buildPoint(row); - changedEdges.insert(row); - - // Correct affected edges - for (unsigned short i = 0; i < mPointData.size(); ++i) - { - PointData& data = mPointData[i]; - for (std::vector::iterator edge = data.edgeList.begin(); - edge != data.edgeList.end(); ++edge) - { - if (*edge == row) - changedEdges.insert(i); - } - } - } - - // Reconstruct edges - for (std::set::iterator index = changedEdges.begin(); - index != changedEdges.end(); ++index) - { - destroyEdges(*index); - buildEdges(*index); - } - - return true; - } - else if (topLeft.parent().column() == EdgeColumn) - { - const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); - const size_t NumEdges = mPathgridData.mEdges.size(); - - std::set changedEdges; - - // Clear edge lists - for (int row = start; row <= end; ++row) - { - mPointData[row].edgeList.clear(); - } - - // Recreate edge lists - for (size_t i = 0; i < NumEdges; ++i) - { - const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; - unsigned short v0 = static_cast(edge.mV0); - unsigned short v1 = static_cast(edge.mV1); - - if ((v0 >= start && v0 <= end) && (v0 != v1 && v0 < NumPoints && v1 < NumPoints)) - mPointData[v0].edgeList.push_back(v1); - } - - // Reconstruct edges - for (int row = start; row <= end; ++row) - { - destroyEdges(row); - buildEdges(row); - } - - return true; - } - } - - return false; - } - - bool Pathgrid::rowAboutToBeRemoved(const QModelIndex& parent, int start, int end) - { - const int PointColumn = 3; - const int EdgeColumn = 4; - - if (!parent.parent().isValid()) - { - if (parent.column() == PointColumn) - { - // Dangling edges will be removed and edges past start decremented - for (size_t i = 0; i < mPointData.size(); ++i) - { - PointData& data = mPointData[i]; - - // They are getting removed anyway - if (i >= (size_t) start && i <= (size_t) end) - continue; - - bool modified = false; - - for (std::vector::iterator edge = data.edgeList.begin(); - edge != data.edgeList.end();) - { - if (*edge >= start && *edge <= end) - { - edge = data.edgeList.erase(edge); - modified = true; - } - else - { - ++edge; - } - } - - // Need to do this before modifying the rest - if (modified) - { - destroyEdges(i); - buildEdges(i); - } - - for (std::vector::iterator edge = data.edgeList.begin(); - edge != data.edgeList.end(); ++edge) - { - if (*edge > end) - --(*edge); - } - } - - // Remove points - for (int i = start; i <= end; ++i) - { - destroyEdges(static_cast(start)); - destroyPoint(static_cast(start)); - mPointData.erase(mPointData.begin() + start); - } - - return true; - } - else if (parent.column() == EdgeColumn) - { - std::set changedEdges; - - // Remove affected edges - for (int i = start; i <= end; ++i) - { - const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; - unsigned short v0 = static_cast(edge.mV0); - unsigned short v1 = static_cast(edge.mV1); - - // Only remove one - for (std::vector::iterator it = mPointData[v0].edgeList.begin(); - it != mPointData[v1].edgeList.end(); ++it) - { - if (*it == v1) - { - mPointData[v0].edgeList.erase(it); - changedEdges.insert(v0); - break; - } - } - } - - // Reconstruct edges - for (std::set::iterator index = changedEdges.begin(); - index != changedEdges.end(); ++index) - { - destroyEdges(*index); - buildEdges(*index); - } - } - } - - return false; - } - - bool Pathgrid::rowAdded(const QModelIndex& parent, int start, int end) - { - const int PointColumn = 3; - const int EdgeColumn = 4; - - if (!parent.parent().isValid()) - { - if (parent.column() == PointColumn) - { - // Edges at and beyond start point have been incremented - for (std::vector::iterator point = mPointData.begin(); point != mPointData.end(); ++point) - { - for (std::vector::iterator edge = point->edgeList.begin(); - edge != point->edgeList.end(); ++edge) - { - if (*edge >= start) - *edge += end - start + 1; - } - } - - // Add points - mPointData.insert(mPointData.begin() + start, end - start + 1, PointData()); - for (int row = start; row <= end; ++row) - buildPoint(static_cast(row)); - - return true; - } - else if (parent.column() == EdgeColumn) - { - const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); - - std::set changedEdges; - - // Add edges - for (int row = start; row <= end; ++row) - { - const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[row]; - unsigned short v0 = static_cast(edge.mV0); - unsigned short v1 = static_cast(edge.mV1); - - if (v0 != v1 && v0 < NumPoints && v1 < NumPoints) - { - mPointData[v0].edgeList.push_back(v1); - changedEdges.insert(v0); - } - } - - // Reconstruct edges - for (std::set::iterator index = changedEdges.begin(); - index != changedEdges.end(); ++index) - { - destroyEdges(*index); - buildEdges(*index); - } - } - } - - return false; - } - - void Pathgrid::constructPointShape() - { - // Construct a diamond - const unsigned short VertexCount = 24; - - const osg::Vec3f ShapePoints[6] = - { - osg::Vec3f( 0.f, 0.f, PointShapeSize), - osg::Vec3f(-PointShapeSize/2, -PointShapeSize/2, 0.f), - osg::Vec3f(-PointShapeSize/2, PointShapeSize/2, 0.f), - osg::Vec3f( PointShapeSize/2, -PointShapeSize/2, 0.f), - osg::Vec3f( PointShapeSize/2, PointShapeSize/2, 0.f), - osg::Vec3f( 0.f, 0.f, -PointShapeSize) - }; - - const unsigned short ShapeIndices[VertexCount] = - { - 0, 2, 1, - 0, 1, 3, - 0, 3, 4, - 0, 4, 2, - 5, 1, 2, - 5, 3, 1, - 5, 4, 3, - 5, 2, 4 - }; - - osg::ref_ptr vertexArray = new osg::Vec3Array(); - osg::ref_ptr normalArray = new osg::Vec3Array(); - osg::ref_ptr colorArray = new osg::Vec4Array(); - osg::ref_ptr indexArray = new osg::DrawElementsUShort( - osg::PrimitiveSet::TRIANGLES, 24); - - for (unsigned short i = 0; i < VertexCount; ++i) - { - vertexArray->push_back(ShapePoints[ShapeIndices[i]]); - indexArray->setElement(i, i); - } - - for (unsigned short i = 0; i < VertexCount; i += 3) - { - osg::Vec3f v1 = vertexArray->at(i+1) - vertexArray->at(i); - osg::Vec3f v2 = vertexArray->at(i+2) - vertexArray->at(i); - osg::Vec3f normal = v1 ^ v2; - - normalArray->push_back(normal); - normalArray->push_back(normal); - normalArray->push_back(normal); - } - - colorArray->push_back(osg::Vec4f(1.f, 0.f, 0.f, 1.f)); - - mPointGeometry->setVertexArray(vertexArray); - mPointGeometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); - mPointGeometry->setColorArray(colorArray, osg::Array::BIND_OVERALL); - mPointGeometry->addPrimitiveSet(indexArray); - } - - void Pathgrid::buildGrid() - { - // Note: the number of pathgrid points is limited to the capacity of a signed short - const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); - const size_t NumEdges = mPathgridData.mEdges.size(); - - // Make points - mPointData.resize(NumPoints); - for (unsigned short i = 0; i < NumPoints; ++i) - buildPoint(i); - - // Add edges to list - for (size_t i = 0; i < NumEdges; ++i) - { - const CSMWorld::Pathgrid::Edge& edge = mPathgridData.mEdges[i]; - unsigned short v0 = static_cast(edge.mV0); - unsigned short v1 = static_cast(edge.mV1); - - if (v0 != v1 && v0 < NumPoints && v1 < NumPoints) - mPointData[v0].edgeList.push_back(v1); - } - - // Make edges - for (unsigned short i = 0; i < NumPoints; ++i) - buildEdges(i); - } - - void Pathgrid::destroyGrid() - { - const unsigned short NumPoints = static_cast(mPathgridData.mPoints.size()); - - for (unsigned short i = 0; i < NumPoints; ++i) - { - destroyEdges(i); - destroyPoint(i); - } - - mPointData.clear(); - } - - void Pathgrid::buildPoint(unsigned short index) - { - const CSMWorld::Pathgrid::Point& source = mPathgridData.mPoints[index]; - PointData& data = mPointData[index]; - - data.posNode = new osg::PositionAttitudeTransform(); - data.posNode->setPosition(osg::Vec3f(source.mX, source.mY, source.mZ)); - mBaseNode->addChild(data.posNode); - - osg::ref_ptr pointNode = new osg::Geode(); - pointNode->addDrawable(mPointGeometry); - data.posNode->addChild(pointNode); - - data.edgeGeometry = new osg::Geometry(); - mEdgeNode->addDrawable(data.edgeGeometry); - } - - void Pathgrid::destroyPoint(unsigned short index) - { - PointData& data = mPointData[index]; - - mBaseNode->removeChild(data.posNode); - data.posNode = 0; - - mEdgeNode->removeDrawable(data.edgeGeometry); - data.edgeGeometry = 0; - } - - void Pathgrid::buildEdges(unsigned short index) - { - // Note: the number of edges per point is limited to the capacity of an unsigned char - const unsigned short VertexCount = static_cast(mPointData[index].edgeList.size() * 2); - const osg::Quat DefaultRotation = osg::Quat(osg::PI / 2.f, osg::Vec3f(0.f, 0.f, 1.f)); - const osg::Vec3f DefaultDirection = osg::Vec3f(0.f, 1.f, 0.f); - const osg::Vec3f Offset = osg::Vec3f(0.f, 0.f, 10.f); - const osg::Vec4f StartColor = osg::Vec4f(1.f, 0.f, 0.f, 1.f); - const osg::Vec4f EndColor = osg::Vec4f(1.f, 0.5f, 0.f, 1.f); - - if (VertexCount == 0) - return; - - // Construct geometry - osg::ref_ptr vertexArray = new osg::Vec3Array(); - osg::ref_ptr colorArray = new osg::Vec4Array(); - osg::ref_ptr indexArray = new osg::DrawElementsUShort( - osg::PrimitiveSet::LINES, VertexCount); - - for (unsigned short i = 0; i < VertexCount; i += 2) - { - const std::vector& edges = mPointData[index].edgeList; - - const CSMWorld::Pathgrid::Point& originPoint = mPathgridData.mPoints[index]; - const CSMWorld::Pathgrid::Point& destPoint = mPathgridData.mPoints[edges[i / 2]]; - - osg::Vec3f origin = osg::Vec3f(originPoint.mX, originPoint.mY, originPoint.mZ); - osg::Vec3f destination = osg::Vec3f(destPoint.mX, destPoint.mY, destPoint.mZ); - osg::Vec3f direction = destination - origin; - - direction.z() = 0; - direction.normalize(); - - // In case the x,y coordinates are too similar - if (direction.isNaN()) - direction = DefaultDirection; - - vertexArray->push_back(origin + Offset + DefaultRotation.inverse() * direction * 0.33f * PointShapeSize); - vertexArray->push_back(destination+ Offset - DefaultRotation * direction * 0.33f * PointShapeSize); - colorArray->push_back(StartColor); - colorArray->push_back(EndColor); - indexArray->setElement(i, i); - indexArray->setElement(i + 1, i + 1); - } - - osg::ref_ptr edgeGeometry = mPointData[index].edgeGeometry; - edgeGeometry->setVertexArray(vertexArray); - edgeGeometry->setColorArray(colorArray, osg::Array::BIND_PER_VERTEX); - edgeGeometry->addPrimitiveSet(indexArray); - edgeGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - } - - void Pathgrid::destroyEdges(unsigned short index) - { - PointData& data = mPointData[index]; - - data.edgeGeometry->setVertexArray(0); - data.edgeGeometry->setColorArray(0); - data.edgeGeometry->getPrimitiveSetList().clear(); - } -} diff --git a/apps/opencs/view/render/pathgrid.hpp b/apps/opencs/view/render/pathgrid.hpp deleted file mode 100644 index 589614a8f..000000000 --- a/apps/opencs/view/render/pathgrid.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef OPENCS_VIEW_PATHGRID_H -#define OPENCS_VIEW_PATHGRID_H - -#include - -#include -#include - -namespace osg -{ - class Geode; - class Geometry; - class Group; - class PositionAttitudeTransform; -} - -namespace CSMWorld -{ - struct Pathgrid; - class CellCoordinates; -} - -namespace CSVRender -{ - class Pathgrid - { - public: - - Pathgrid(osg::Group* parent, const CSMWorld::Pathgrid& pathgrid, const CSMWorld::CellCoordinates& coords); - ~Pathgrid(); - - bool dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - - bool rowAboutToBeRemoved(const QModelIndex& parent, int start, int end); - - bool rowAdded(const QModelIndex& parent, int start, int end); - - private: - - struct PointData - { - osg::ref_ptr posNode; - std::vector edgeList; - osg::ref_ptr edgeGeometry; - }; - - static const float PointShapeSize; - - const CSMWorld::Pathgrid& mPathgridData; - std::vector mPointData; - - osg::ref_ptr mParentNode; - osg::ref_ptr mBaseNode; - osg::ref_ptr mPointGeometry; - osg::ref_ptr mEdgeNode; - - void constructPointShape(); - - void buildGrid(); - void destroyGrid(); - - void buildPoint(unsigned short index); - void destroyPoint(unsigned short index); - - void buildEdges(unsigned short index); - void destroyEdges(unsigned short index); - - // Not implemented - Pathgrid(const Pathgrid&); - Pathgrid& operator=(const Pathgrid&); - }; -} - -#endif diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index c7e875c18..79ffd4fb0 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -32,7 +32,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() } CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent) -: WorldspaceWidget (document, parent), mDocument(document), mCellId (cellId) +: WorldspaceWidget (document, parent), mCellId (cellId) { mCellsModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); @@ -197,81 +197,6 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (topLeft.parent().isValid()) - { - int row = topLeft.parent().row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - if (mCellId == pathgrid.mId && mCell->pathgridDataChanged(topLeft, bottomRight)) - flagAsModified(); - } -} - -void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (!parent.isValid()) - { - // Pathgrid going to be deleted - for (int row = start; row <= end; ++row) - { - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - if (mCellId == pathgrid.mId) - { - mCell->pathgridRemoved(); - flagAsModified(); - } - } - } - else - { - // Pathgrid data was modified - int row = parent.row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - if (mCellId == pathgrid.mId) - { - mCell->pathgridRowAboutToBeRemoved(parent, start, end); - flagAsModified(); - } - } -} - -void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, int start, int end) -{ - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); - - if (!parent.isValid()) - { - // Pathgrid added theoretically, unable to test until it is possible to add pathgrids - for (int row = start; row <= end; ++row) - { - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - if (mCellId == pathgrid.mId) - { - mCell->pathgridAdded(pathgrid); - } - } - } - else - { - // Pathgrid data was modified - int row = parent.row(); - - const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); - if (mCellId == pathgrid.mId) - { - mCell->pathgridRowAdded(parent, start, end); - flagAsModified(); - } - } -} - void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons ( CSVWidget::SceneToolToggle2 *tool) { diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 24b511c4c..c5bfd22e6 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -25,7 +25,6 @@ namespace CSVRender { Q_OBJECT - CSMDoc::Document& mDocument; std::string mCellId; CSMWorld::IdTable *mCellsModel; CSMWorld::IdTable *mReferenceablesModel; @@ -84,12 +83,6 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); - - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); - - virtual void pathgridAdded (const QModelIndex& parent, int start, int end); - virtual std::string getStartupInstruction(); protected: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index fa5fd0bee..927ce545f 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -59,15 +59,6 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (referenceAdded (const QModelIndex&, int, int))); - QAbstractItemModel *pathgrids = document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrids); - - connect (pathgrids, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), - this, SLOT (pathgridDataChanged (const QModelIndex&, const QModelIndex&))); - connect (pathgrids, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), - this, SLOT (pathgridAboutToBeRemoved (const QModelIndex&, int, int))); - connect (pathgrids, SIGNAL (rowsInserted (const QModelIndex&, int, int)), - this, SLOT (pathgridAdded (const QModelIndex&, int, int))); - QAbstractItemModel *debugProfiles = document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index bc528f52d..b18123944 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -228,12 +228,6 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0; - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; - - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; - - virtual void pathgridAdded (const QModelIndex& parent, int start, int end) = 0; - virtual void runRequest (const std::string& profile); void debugProfileDataChanged (const QModelIndex& topLeft, From 7fbcc47b151c89822e7e36408819a041ba368697 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 22:08:49 -0400 Subject: [PATCH 03/13] Add pathgrid modified signals. --- apps/opencs/view/render/cell.cpp | 20 ++++ apps/opencs/view/render/cell.hpp | 11 ++ .../view/render/pagedworldspacewidget.cpp | 101 ++++++++++++++++++ .../view/render/pagedworldspacewidget.hpp | 8 ++ .../view/render/unpagedworldspacewidget.cpp | 86 ++++++++++++++- .../view/render/unpagedworldspacewidget.hpp | 10 ++ apps/opencs/view/render/worldspacewidget.cpp | 11 ++ apps/opencs/view/render/worldspacewidget.hpp | 9 ++ 8 files changed, 255 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 9a352ffad..d841bd992 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -254,6 +254,26 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int return addObjects (start, end); } +void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid) +{ +} + +void CSVRender::Cell::pathgridRemoved() +{ +} + +void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ +} + +void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end) +{ +} + +void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end) +{ +} + void CSVRender::Cell::setSelection (int elementMask, Selection mode) { if (elementMask & Mask_Reference) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 631df24aa..4758a95c3 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -29,6 +29,7 @@ namespace CSMWorld { class Data; class CellCoordinates; + class Pathgrid; } namespace CSVRender @@ -103,6 +104,16 @@ namespace CSVRender /// this cell? bool referenceAdded (const QModelIndex& parent, int start, int end); + void pathgridAdded(const CSMWorld::Pathgrid& pathgrid); + + void pathgridRemoved(); + + void pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void pathgridRowRemoved(const QModelIndex& parent, int start, int end); + + void pathgridRowAdded(const QModelIndex& parent, int start, int end); + void setSelection (int elementMask, Selection mode); // Select everything that references the same ID as at least one of the elements diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 22b0e3805..1d9b22216 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -275,6 +275,107 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent flagAsModified(); } +void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (topLeft.parent().isValid()) + { + int row = topLeft.parent().row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridDataChanged(topLeft, bottomRight); + flagAsModified(); + } + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (parent.isValid()) + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRowRemoved(parent, start, end); + flagAsModified(); + } + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid going to be deleted + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRemoved(); + flagAsModified(); + } + } + } +} + +void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid added theoretically, unable to test until it is possible to add pathgrids + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridAdded(pathgrid); + flagAsModified(); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + CSMWorld::CellCoordinates coords = CSMWorld::CellCoordinates(pathgrid.mData.mX, pathgrid.mData.mY); + + std::map::iterator searchResult = mCells.find(coords); + if (searchResult != mCells.end()) + { + searchResult->second->pathgridRowAdded(parent, start, end); + flagAsModified(); + } + } +} + + std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() { osg::Vec3d eye, center, up; diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 4bdaa3820..3cd628df0 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -52,6 +52,14 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + virtual void pathgridRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + virtual std::string getStartupInstruction(); /// \note Does not update the view or any cell marker diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 79ffd4fb0..84b7a0ca8 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -32,7 +32,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() } CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent) -: WorldspaceWidget (document, parent), mCellId (cellId) +: WorldspaceWidget (document, parent), mDocument(document), mCellId (cellId) { mCellsModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); @@ -197,6 +197,90 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare flagAsModified(); } +void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (topLeft.parent().isValid()) + { + int row = topLeft.parent().row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridDataChanged(topLeft, bottomRight); + flagAsModified(); + } + } +} + +void CSVRender::UnpagedWorldspaceWidget::pathgridRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (parent.isValid()){ + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRowRemoved(parent, start, end); + flagAsModified(); + } + } +} + +void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid going to be deleted + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRemoved(); + flagAsModified(); + } + } + } +} + +void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, int start, int end) +{ + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + + if (!parent.isValid()) + { + // Pathgrid added theoretically, unable to test until it is possible to add pathgrids + for (int row = start; row <= end; ++row) + { + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridAdded(pathgrid); + flagAsModified(); + } + } + } + else + { + // Pathgrid data was modified + int row = parent.row(); + + const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get(); + if (mCellId == pathgrid.mId) + { + mCell->pathgridRowAdded(parent, start, end); + flagAsModified(); + } + } +} + void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons ( CSVWidget::SceneToolToggle2 *tool) { diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index c5bfd22e6..f06302032 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -25,6 +25,7 @@ namespace CSVRender { Q_OBJECT + CSMDoc::Document& mDocument; std::string mCellId; CSMWorld::IdTable *mCellsModel; CSMWorld::IdTable *mReferenceablesModel; @@ -83,6 +84,15 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end); + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + virtual void pathgridRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end); + + virtual std::string getStartupInstruction(); protected: diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 927ce545f..1bd3df981 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -59,6 +59,17 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (referenceAdded (const QModelIndex&, int, int))); + QAbstractItemModel *pathgrids = document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrids); + + connect (pathgrids, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (pathgridDataChanged (const QModelIndex&, const QModelIndex&))); + connect (pathgrids, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), + this, SLOT (pathgridRemoved (const QModelIndex&, int, int))); + connect (pathgrids, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (pathgridAboutToBeRemoved (const QModelIndex&, int, int))); + connect (pathgrids, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (pathgridAdded (const QModelIndex&, int, int))); + QAbstractItemModel *debugProfiles = document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index b18123944..d70694d22 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -228,6 +228,15 @@ namespace CSVRender virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0; + virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; + + virtual void pathgridRemoved (const QModelIndex& parent, int start, int end) = 0; + + virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; + + virtual void pathgridAdded (const QModelIndex& parent, int start, int end) = 0; + + virtual void runRequest (const std::string& profile); void debugProfileDataChanged (const QModelIndex& topLeft, From d141672b53d83773613b5b1dd5e98650407870fa Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 22:09:48 -0400 Subject: [PATCH 04/13] Pathgrid geometry creator --- components/CMakeLists.txt | 6 +- components/sceneutil/pathgridutil.cpp | 155 ++++++++++++++++++++++++++ components/sceneutil/pathgridutil.hpp | 39 +++++++ 3 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 components/sceneutil/pathgridutil.cpp create mode 100644 components/sceneutil/pathgridutil.hpp diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 2508cdc82..db8904f2b 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -22,7 +22,7 @@ endif (GIT_CHECKOUT) if (OPENGL_ES) find_package(OpenGLES REQUIRED) -else() +else() find_package(OpenGL REQUIRED) endif() @@ -50,7 +50,7 @@ add_component_dir (shader add_component_dir (sceneutil clone attach visitor util statesetupdater controller skeleton riggeometry lightcontroller - lightmanager lightutil positionattitudetransform workqueue unrefqueue + lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil ) add_component_dir (nif @@ -191,7 +191,7 @@ else() set(GL_LIB ${OPENGL_gl_LIBRARY}) endif() -target_link_libraries(components +target_link_libraries(components ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp new file mode 100644 index 000000000..1bf70168d --- /dev/null +++ b/components/sceneutil/pathgridutil.cpp @@ -0,0 +1,155 @@ +#include "pathgridutil.hpp" + +#include + +#include +#include + +namespace SceneUtil +{ + const unsigned short DiamondVertexCount = 24; + const float DiamondHalfHeight = 25.f; + const float DiamondHalfWidth = 10.f; + + const osg::Vec3f DiamondPoints[6] = + { + osg::Vec3f( 0.f, 0.f, DiamondHalfHeight * 2.f), + osg::Vec3f(-DiamondHalfWidth, -DiamondHalfWidth, DiamondHalfHeight), + osg::Vec3f(-DiamondHalfWidth, DiamondHalfWidth, DiamondHalfHeight), + osg::Vec3f( DiamondHalfWidth, -DiamondHalfWidth, DiamondHalfHeight), + osg::Vec3f( DiamondHalfWidth, DiamondHalfWidth, DiamondHalfHeight), + osg::Vec3f( 0.f, 0.f, 0.f) + }; + + const unsigned short DiamondIndices[DiamondVertexCount] = + { + 0, 2, 1, + 0, 1, 3, + 0, 3, 4, + 0, 4, 2, + 5, 1, 2, + 5, 3, 1, + 5, 4, 3, + 5, 2, 4 + }; + + const osg::Vec4f DiamondColor = osg::Vec4f(1.f, 0.f, 0.f, 1.f); + + osg::ref_ptr PathgridGeometryFactory::create(const ESM::Pathgrid& pathgrid) + { + const unsigned short PointCount = static_cast(pathgrid.mPoints.size()); + const size_t EdgeCount = pathgrid.mEdges.size(); + + const unsigned short VertexCount = PointCount * DiamondVertexCount; + + osg::ref_ptr gridGeometry = new osg::Geometry(); + + osg::ref_ptr vertices = new osg::Vec3Array(VertexCount); + osg::ref_ptr normals = new osg::Vec3Array(VertexCount); + osg::ref_ptr colors = new osg::Vec4Array(1); + osg::ref_ptr pointIndices = + new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, VertexCount); + osg::ref_ptr lineIndices = + new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, EdgeCount * 2); + + // Add each point/node + for (unsigned short i = 0; i < PointCount; ++i) + { + const ESM::Pathgrid::Point& point = pathgrid.mPoints[i]; + osg::Vec3f position = osg::Vec3f(point.mX, point.mY, point.mZ); + + addPoint(i * DiamondVertexCount, position, vertices, normals, pointIndices); + } + + // Add edges + unsigned short lineIndex = 0; + + for (ESM::Pathgrid::EdgeList::const_iterator edge = pathgrid.mEdges.begin(); + edge != pathgrid.mEdges.end(); ++edge) + { + if (edge->mV0 == edge->mV1 || edge->mV0 < 0 || edge->mV0 >= PointCount || + edge->mV1 < 0 || edge->mV1 >= PointCount) + continue; + + const ESM::Pathgrid::Point& from = pathgrid.mPoints[edge->mV0]; + const ESM::Pathgrid::Point& to = pathgrid.mPoints[edge->mV1]; + + osg::Vec3f fromPos = osg::Vec3f(from.mX, from.mY, from.mZ); + osg::Vec3f toPos = osg::Vec3f(to.mX, to.mY, to.mZ); + osg::Vec3f dir = toPos - fromPos; + dir.normalize(); + + osg::Quat rot = osg::Quat(-osg::PI / 2, osg::Vec3(0, 0, 1)); + dir = rot * dir; + + unsigned short diamondIndex = 0; + if (dir.isNaN()) + diamondIndex = 2; + else if (dir.y() >= 0 && dir.x() > 0) + diamondIndex = 8; + else if (dir.x() <= 0 && dir.y() > 0) + diamondIndex = 11; + else if (dir.y() <= 0 && dir.x() < 0) + diamondIndex = 2; + else if (dir.x() >= 0 && dir.y() < 0) + diamondIndex = 5; + + unsigned short fromIndex = static_cast(edge->mV0); + unsigned short toIndex = static_cast(edge->mV1); + + lineIndices->setElement(lineIndex++, fromIndex * DiamondVertexCount + diamondIndex); + lineIndices->setElement(lineIndex++, toIndex * DiamondVertexCount + diamondIndex); + } + + lineIndices->resize(lineIndex); + + (*colors)[0] = DiamondColor; + + gridGeometry->setVertexArray(vertices); + gridGeometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); + gridGeometry->setColorArray(colors, osg::Array::BIND_OVERALL); + gridGeometry->addPrimitiveSet(pointIndices); + gridGeometry->addPrimitiveSet(lineIndices); + + return gridGeometry; + } + + PathgridGeometryFactory& PathgridGeometryFactory::get() + { + static PathgridGeometryFactory instance; + return instance; + } + + PathgridGeometryFactory::PathgridGeometryFactory() + { + generateNormals(); + } + + void PathgridGeometryFactory::generateNormals() + { + mGeneratedNormals.resize(DiamondVertexCount); + + for (unsigned short i = 0; i < DiamondVertexCount; i += 3) + { + osg::Vec3f v1 = DiamondPoints[DiamondIndices[i + 1]] - DiamondPoints[DiamondIndices[i]]; + osg::Vec3f v2 = DiamondPoints[DiamondIndices[i + 2]] - DiamondPoints[DiamondIndices[i]]; + + osg::Vec3f normal = v1 ^ v2; + + mGeneratedNormals[i] = normal; + mGeneratedNormals[i + 1] = normal; + mGeneratedNormals[i + 2] = normal; + } + } + + void PathgridGeometryFactory::addPoint(unsigned short offset, const osg::Vec3f& position, osg::Vec3Array* vertices, + osg::Vec3Array* normals, osg::DrawElementsUShort* indices) + { + for (unsigned short i = 0; i < DiamondVertexCount; ++i) + { + (*vertices)[i + offset] = position + DiamondPoints[DiamondIndices[i]]; + (*normals)[i + offset] = mGeneratedNormals[i]; + indices->setElement(i + offset, i + offset); + } + } +} diff --git a/components/sceneutil/pathgridutil.hpp b/components/sceneutil/pathgridutil.hpp new file mode 100644 index 000000000..07f24fe68 --- /dev/null +++ b/components/sceneutil/pathgridutil.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_COMPONENTS_PATHGRIDUTIL_H +#define OPENMW_COMPONENTS_PATHGRIDUTIL_H + +#include +#include + +namespace ESM +{ + class Pathgrid; +} + +namespace SceneUtil +{ + + class PathgridGeometryFactory + { + public: + + osg::ref_ptr create(const ESM::Pathgrid& pathgrid); + static PathgridGeometryFactory& get(); + + private: + + PathgridGeometryFactory(); + + void generateNormals(); + + void addPoint(unsigned short offset, const osg::Vec3f& position, osg::Vec3Array* vertices, + osg::Vec3Array* normals, osg::DrawElementsUShort* indices); + + // Not implemented + PathgridGeometryFactory(const PathgridGeometryFactory&); + PathgridGeometryFactory& operator=(const PathgridGeometryFactory&); + + std::vector mGeneratedNormals; + }; +} + +#endif From 5cac8821232a6d6a92334fa15e44ffa904d782cd Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 22:10:17 -0400 Subject: [PATCH 05/13] Replace game version of pathgrid rendering with component. --- apps/openmw/mwrender/pathgrid.cpp | 109 +----------------------------- apps/openmw/mwrender/pathgrid.hpp | 3 - 2 files changed, 3 insertions(+), 109 deletions(-) diff --git a/apps/openmw/mwrender/pathgrid.cpp b/apps/openmw/mwrender/pathgrid.cpp index d79604a91..8d790e5e0 100644 --- a/apps/openmw/mwrender/pathgrid.cpp +++ b/apps/openmw/mwrender/pathgrid.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwbase/environment.hpp" @@ -23,107 +24,6 @@ namespace MWRender { -static const int POINT_MESH_BASE = 35; - -osg::ref_ptr Pathgrid::createPathgridLines(const ESM::Pathgrid *pathgrid) -{ - osg::ref_ptr geom = new osg::Geometry; - - osg::ref_ptr vertices = new osg::Vec3Array; - - for(ESM::Pathgrid::EdgeList::const_iterator it = pathgrid->mEdges.begin(); - it != pathgrid->mEdges.end(); - ++it) - { - const ESM::Pathgrid::Edge &edge = *it; - const ESM::Pathgrid::Point &p1 = pathgrid->mPoints[edge.mV0], &p2 = pathgrid->mPoints[edge.mV1]; - - osg::Vec3f direction = MWMechanics::PathFinder::MakeOsgVec3(p2) - MWMechanics::PathFinder::MakeOsgVec3(p1); - osg::Vec3f lineDisplacement = (direction^osg::Vec3f(0,0,1)); - lineDisplacement.normalize(); - - lineDisplacement = lineDisplacement * POINT_MESH_BASE + - osg::Vec3f(0, 0, 10); // move lines up a little, so they will be less covered by meshes/landscape - - vertices->push_back(MWMechanics::PathFinder::MakeOsgVec3(p1) + lineDisplacement); - vertices->push_back(MWMechanics::PathFinder::MakeOsgVec3(p2) + lineDisplacement); - } - - geom->setVertexArray(vertices); - - geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices->size())); - - osg::ref_ptr colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.f, 1.f, 0.f, 1.f)); - geom->setColorArray(colors, osg::Array::BIND_OVERALL); - - return geom; -} - -osg::ref_ptr Pathgrid::createPathgridPoints(const ESM::Pathgrid *pathgrid) -{ - osg::ref_ptr geom = new osg::Geometry; - - const float height = POINT_MESH_BASE * sqrtf(2); - - osg::ref_ptr vertices = new osg::Vec3Array; - osg::ref_ptr indices = new osg::UShortArray; - - bool first = true; - unsigned short startIndex = 0; - for(ESM::Pathgrid::PointList::const_iterator it = pathgrid->mPoints.begin(); - it != pathgrid->mPoints.end(); - ++it, startIndex += 6) - { - osg::Vec3f pointPos(MWMechanics::PathFinder::MakeOsgVec3(*it)); - - if (!first) - { - // degenerate triangle from previous octahedron - indices->push_back(startIndex - 4); // 2nd point of previous octahedron - indices->push_back(startIndex); // start point of current octahedron - } - - float pointMeshBase = static_cast(POINT_MESH_BASE); - - vertices->push_back(pointPos + osg::Vec3f(0, 0, height)); // 0 - vertices->push_back(pointPos + osg::Vec3f(-pointMeshBase, -pointMeshBase, 0)); // 1 - vertices->push_back(pointPos + osg::Vec3f(pointMeshBase, -pointMeshBase, 0)); // 2 - vertices->push_back(pointPos + osg::Vec3f(pointMeshBase, pointMeshBase, 0)); // 3 - vertices->push_back(pointPos + osg::Vec3f(-pointMeshBase, pointMeshBase, 0)); // 4 - vertices->push_back(pointPos + osg::Vec3f(0, 0, -height)); // 5 - - indices->push_back(startIndex + 0); - indices->push_back(startIndex + 1); - indices->push_back(startIndex + 2); - indices->push_back(startIndex + 5); - indices->push_back(startIndex + 3); - indices->push_back(startIndex + 4); - // degenerates - indices->push_back(startIndex + 4); - indices->push_back(startIndex + 5); - indices->push_back(startIndex + 5); - // end degenerates - indices->push_back(startIndex + 1); - indices->push_back(startIndex + 4); - indices->push_back(startIndex + 0); - indices->push_back(startIndex + 3); - indices->push_back(startIndex + 2); - - first = false; - } - - geom->setVertexArray(vertices); - - geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, indices->size(), &(*indices)[0])); - - osg::ref_ptr colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.f, 0.f, 0.f, 1.f)); - geom->setColorArray(colors, osg::Array::BIND_OVERALL); - - return geom; -} - Pathgrid::Pathgrid(osg::ref_ptr root) : mPathgridEnabled(false) , mRootNode(root) @@ -212,12 +112,9 @@ void Pathgrid::enableCellPathgrid(const MWWorld::CellStore *store) osg::ref_ptr cellPathGrid = new osg::PositionAttitudeTransform; cellPathGrid->setPosition(cellPathGridPos); - osg::ref_ptr lines = createPathgridLines(pathgrid); + osg::ref_ptr geometry = SceneUtil::PathgridGeometryFactory::get().create(*pathgrid); - osg::ref_ptr points = createPathgridPoints(pathgrid); - - cellPathGrid->addChild(lines); - cellPathGrid->addChild(points); + cellPathGrid->addChild(geometry); mPathGridRoot->addChild(cellPathGrid); diff --git a/apps/openmw/mwrender/pathgrid.hpp b/apps/openmw/mwrender/pathgrid.hpp index 39a6d71ed..22bfa8e73 100644 --- a/apps/openmw/mwrender/pathgrid.hpp +++ b/apps/openmw/mwrender/pathgrid.hpp @@ -48,9 +48,6 @@ namespace MWRender void enableCellPathgrid(const MWWorld::CellStore *store); void disableCellPathgrid(const MWWorld::CellStore *store); - // path grid meshes - osg::ref_ptr createPathgridLines(const ESM::Pathgrid *pathgrid); - osg::ref_ptr createPathgridPoints(const ESM::Pathgrid *pathgrid); public: Pathgrid(osg::ref_ptr root); ~Pathgrid(); From 8d95b63180fc86a378482b1c7f796d36e9e98eb4 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 22:10:43 -0400 Subject: [PATCH 06/13] Add pathgrid rendering to opencs --- apps/opencs/view/render/cell.cpp | 54 ++++++++++++++++++++++++++++++++ apps/opencs/view/render/cell.hpp | 4 +++ 2 files changed, 58 insertions(+) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index d841bd992..955e97e3e 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -1,10 +1,14 @@ #include "cell.hpp" +#include +#include +#include #include #include #include #include +#include #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" @@ -77,6 +81,16 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellNode = new osg::Group; rootNode->addChild(mCellNode); + osg::ref_ptr pathgridTransform = new osg::PositionAttitudeTransform(); + pathgridTransform->setPosition(osg::Vec3f(mCoordinates.getX() * ESM::Land::REAL_SIZE, + mCoordinates.getY() * ESM::Land::REAL_SIZE, 0)); + mCellNode->addChild(pathgridTransform); + + mPathgridGeode = new osg::Geode(); + pathgridTransform->addChild(mPathgridGeode); + + mPathgridGeometry = 0; + setCellMarker(); if (!mDeleted) @@ -104,6 +118,15 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st mCellBorder->buildShape(esmLand); } } + + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + { + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( + pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeode->addDrawable(mPathgridGeometry); + } } } @@ -256,22 +279,53 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid) { + mPathgridGeode->removeDrawable(mPathgridGeometry); + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create(pathgrid); + mPathgridGeode->addDrawable(mPathgridGeometry); } void CSVRender::Cell::pathgridRemoved() { + mPathgridGeode->removeDrawable(mPathgridGeometry); } void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + { + mPathgridGeode->removeDrawable(mPathgridGeometry); + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( + pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeode->addDrawable(mPathgridGeometry); + } } void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end) { + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + { + mPathgridGeode->removeDrawable(mPathgridGeometry); + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( + pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeode->addDrawable(mPathgridGeometry); + } } void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end) { + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + { + mPathgridGeode->removeDrawable(mPathgridGeometry); + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( + pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeode->addDrawable(mPathgridGeometry); + } } void CSVRender::Cell::setSelection (int elementMask, Selection mode) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 4758a95c3..0efb8757c 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -23,6 +23,8 @@ class QModelIndex; namespace osg { class Group; + class Geometry; + class Geode; } namespace CSMWorld @@ -41,6 +43,8 @@ namespace CSVRender CSMWorld::Data& mData; std::string mId; osg::ref_ptr mCellNode; + osg::ref_ptr mPathgridGeode; + osg::ref_ptr mPathgridGeometry; std::map mObjects; std::auto_ptr mTerrain; CSMWorld::CellCoordinates mCoordinates; From 3d26ff08c42597081ba6695e7577dc69d82ef977 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 2 May 2016 23:12:58 -0400 Subject: [PATCH 07/13] Get rid of lighting. --- components/sceneutil/pathgridutil.cpp | 76 +++++++++++---------------- components/sceneutil/pathgridutil.hpp | 7 --- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp index 1bf70168d..e7c3cecca 100644 --- a/components/sceneutil/pathgridutil.cpp +++ b/components/sceneutil/pathgridutil.cpp @@ -7,11 +7,12 @@ namespace SceneUtil { - const unsigned short DiamondVertexCount = 24; + const unsigned short DiamondVertexCount = 6; + const unsigned short DiamondIndexCount = 24; const float DiamondHalfHeight = 25.f; const float DiamondHalfWidth = 10.f; - const osg::Vec3f DiamondPoints[6] = + const osg::Vec3f DiamondPoints[DiamondVertexCount] = { osg::Vec3f( 0.f, 0.f, DiamondHalfHeight * 2.f), osg::Vec3f(-DiamondHalfWidth, -DiamondHalfWidth, DiamondHalfHeight), @@ -21,7 +22,7 @@ namespace SceneUtil osg::Vec3f( 0.f, 0.f, 0.f) }; - const unsigned short DiamondIndices[DiamondVertexCount] = + const unsigned short DiamondIndices[DiamondIndexCount] = { 0, 2, 1, 0, 1, 3, @@ -41,24 +42,38 @@ namespace SceneUtil const size_t EdgeCount = pathgrid.mEdges.size(); const unsigned short VertexCount = PointCount * DiamondVertexCount; + const unsigned short ColorCount = 1; + const size_t PointIndexCount = PointCount * DiamondIndexCount; + const size_t EdgeIndexCount = EdgeCount * 2; osg::ref_ptr gridGeometry = new osg::Geometry(); osg::ref_ptr vertices = new osg::Vec3Array(VertexCount); - osg::ref_ptr normals = new osg::Vec3Array(VertexCount); - osg::ref_ptr colors = new osg::Vec4Array(1); + osg::ref_ptr colors = new osg::Vec4Array(ColorCount); osg::ref_ptr pointIndices = - new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, VertexCount); + new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, PointIndexCount); osg::ref_ptr lineIndices = - new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, EdgeCount * 2); + new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, EdgeIndexCount); // Add each point/node - for (unsigned short i = 0; i < PointCount; ++i) + + + for (unsigned short pointIndex = 0; pointIndex < PointCount; ++pointIndex) { - const ESM::Pathgrid::Point& point = pathgrid.mPoints[i]; + const ESM::Pathgrid::Point& point = pathgrid.mPoints[pointIndex]; osg::Vec3f position = osg::Vec3f(point.mX, point.mY, point.mZ); - addPoint(i * DiamondVertexCount, position, vertices, normals, pointIndices); + unsigned short vertexOffset = pointIndex * DiamondVertexCount; + unsigned short indexOffset = pointIndex * DiamondIndexCount; + for (unsigned short i = 0; i < DiamondVertexCount; ++i) + { + (*vertices)[vertexOffset + i] = position + DiamondPoints[i]; + } + + for (unsigned short i = 0; i < DiamondIndexCount; ++i) + { + pointIndices->setElement(indexOffset + i, vertexOffset + DiamondIndices[i]); + } } // Add edges @@ -84,15 +99,15 @@ namespace SceneUtil unsigned short diamondIndex = 0; if (dir.isNaN()) - diamondIndex = 2; + diamondIndex = 1; else if (dir.y() >= 0 && dir.x() > 0) - diamondIndex = 8; + diamondIndex = 4; else if (dir.x() <= 0 && dir.y() > 0) - diamondIndex = 11; - else if (dir.y() <= 0 && dir.x() < 0) diamondIndex = 2; + else if (dir.y() <= 0 && dir.x() < 0) + diamondIndex = 1; else if (dir.x() >= 0 && dir.y() < 0) - diamondIndex = 5; + diamondIndex = 3; unsigned short fromIndex = static_cast(edge->mV0); unsigned short toIndex = static_cast(edge->mV1); @@ -106,10 +121,10 @@ namespace SceneUtil (*colors)[0] = DiamondColor; gridGeometry->setVertexArray(vertices); - gridGeometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX); gridGeometry->setColorArray(colors, osg::Array::BIND_OVERALL); gridGeometry->addPrimitiveSet(pointIndices); gridGeometry->addPrimitiveSet(lineIndices); + gridGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); return gridGeometry; } @@ -122,34 +137,5 @@ namespace SceneUtil PathgridGeometryFactory::PathgridGeometryFactory() { - generateNormals(); - } - - void PathgridGeometryFactory::generateNormals() - { - mGeneratedNormals.resize(DiamondVertexCount); - - for (unsigned short i = 0; i < DiamondVertexCount; i += 3) - { - osg::Vec3f v1 = DiamondPoints[DiamondIndices[i + 1]] - DiamondPoints[DiamondIndices[i]]; - osg::Vec3f v2 = DiamondPoints[DiamondIndices[i + 2]] - DiamondPoints[DiamondIndices[i]]; - - osg::Vec3f normal = v1 ^ v2; - - mGeneratedNormals[i] = normal; - mGeneratedNormals[i + 1] = normal; - mGeneratedNormals[i + 2] = normal; - } - } - - void PathgridGeometryFactory::addPoint(unsigned short offset, const osg::Vec3f& position, osg::Vec3Array* vertices, - osg::Vec3Array* normals, osg::DrawElementsUShort* indices) - { - for (unsigned short i = 0; i < DiamondVertexCount; ++i) - { - (*vertices)[i + offset] = position + DiamondPoints[DiamondIndices[i]]; - (*normals)[i + offset] = mGeneratedNormals[i]; - indices->setElement(i + offset, i + offset); - } } } diff --git a/components/sceneutil/pathgridutil.hpp b/components/sceneutil/pathgridutil.hpp index 07f24fe68..1bb668226 100644 --- a/components/sceneutil/pathgridutil.hpp +++ b/components/sceneutil/pathgridutil.hpp @@ -23,16 +23,9 @@ namespace SceneUtil PathgridGeometryFactory(); - void generateNormals(); - - void addPoint(unsigned short offset, const osg::Vec3f& position, osg::Vec3Array* vertices, - osg::Vec3Array* normals, osg::DrawElementsUShort* indices); - // Not implemented PathgridGeometryFactory(const PathgridGeometryFactory&); PathgridGeometryFactory& operator=(const PathgridGeometryFactory&); - - std::vector mGeneratedNormals; }; } From 7f0cc6e58329b0a00b37415e9f635306976776c9 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 03:17:36 -0400 Subject: [PATCH 08/13] Add a color gradiant to pathgrid nodes to make them less of an eyesore. --- components/sceneutil/pathgridutil.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp index e7c3cecca..d72e11968 100644 --- a/components/sceneutil/pathgridutil.cpp +++ b/components/sceneutil/pathgridutil.cpp @@ -34,7 +34,15 @@ namespace SceneUtil 5, 2, 4 }; - const osg::Vec4f DiamondColor = osg::Vec4f(1.f, 0.f, 0.f, 1.f); + const osg::Vec4f DiamondColors[DiamondVertexCount] = + { + osg::Vec4f(1.f, 0.f, 0.f, 1.f), + osg::Vec4f(.9f, .1f, 0.f, 1.f), + osg::Vec4f(.9f, .2f, 0.f, 1.f), + osg::Vec4f(.9f, .3f, 0.f, 1.f), + osg::Vec4f(.9f, .4f, 0.f, 1.f), + osg::Vec4f(.8f, .5f, 0.f, 1.f) + }; osg::ref_ptr PathgridGeometryFactory::create(const ESM::Pathgrid& pathgrid) { @@ -42,7 +50,7 @@ namespace SceneUtil const size_t EdgeCount = pathgrid.mEdges.size(); const unsigned short VertexCount = PointCount * DiamondVertexCount; - const unsigned short ColorCount = 1; + const unsigned short ColorCount = VertexCount; const size_t PointIndexCount = PointCount * DiamondIndexCount; const size_t EdgeIndexCount = EdgeCount * 2; @@ -68,6 +76,7 @@ namespace SceneUtil for (unsigned short i = 0; i < DiamondVertexCount; ++i) { (*vertices)[vertexOffset + i] = position + DiamondPoints[i]; + (*colors)[vertexOffset + i] = DiamondColors[i]; } for (unsigned short i = 0; i < DiamondIndexCount; ++i) @@ -118,10 +127,8 @@ namespace SceneUtil lineIndices->resize(lineIndex); - (*colors)[0] = DiamondColor; - gridGeometry->setVertexArray(vertices); - gridGeometry->setColorArray(colors, osg::Array::BIND_OVERALL); + gridGeometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX); gridGeometry->addPrimitiveSet(pointIndices); gridGeometry->addPrimitiveSet(lineIndices); gridGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); From 0eb863d8fc5b72724bf9c43cad9f63b917df53c5 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 03:18:47 -0400 Subject: [PATCH 09/13] Change color to blue to match the pathgrid visibility selector in the editor and slightly increase the scaling. --- components/sceneutil/pathgridutil.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp index d72e11968..1ba2c006b 100644 --- a/components/sceneutil/pathgridutil.cpp +++ b/components/sceneutil/pathgridutil.cpp @@ -9,8 +9,8 @@ namespace SceneUtil { const unsigned short DiamondVertexCount = 6; const unsigned short DiamondIndexCount = 24; - const float DiamondHalfHeight = 25.f; - const float DiamondHalfWidth = 10.f; + const float DiamondHalfHeight = 40.f; + const float DiamondHalfWidth = 16.f; const osg::Vec3f DiamondPoints[DiamondVertexCount] = { @@ -36,12 +36,12 @@ namespace SceneUtil const osg::Vec4f DiamondColors[DiamondVertexCount] = { - osg::Vec4f(1.f, 0.f, 0.f, 1.f), - osg::Vec4f(.9f, .1f, 0.f, 1.f), - osg::Vec4f(.9f, .2f, 0.f, 1.f), - osg::Vec4f(.9f, .3f, 0.f, 1.f), - osg::Vec4f(.9f, .4f, 0.f, 1.f), - osg::Vec4f(.8f, .5f, 0.f, 1.f) + osg::Vec4f(0.f, 0.f, 1.f, 1.f), + osg::Vec4f(0.f, .05f, .95f, 1.f), + osg::Vec4f(0.f, .1f, .95f, 1.f), + osg::Vec4f(0.f, .15f, .95f, 1.f), + osg::Vec4f(0.f, .2f, .95f, 1.f), + osg::Vec4f(0.f, .25f, 9.f, 1.f) }; osg::ref_ptr PathgridGeometryFactory::create(const ESM::Pathgrid& pathgrid) From 642b1d027342885d0a299694e6a60b4aeee184f9 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 03:27:47 -0400 Subject: [PATCH 10/13] Add mask. --- apps/opencs/view/render/cell.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 955e97e3e..1bd43c23f 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -84,6 +84,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st osg::ref_ptr pathgridTransform = new osg::PositionAttitudeTransform(); pathgridTransform->setPosition(osg::Vec3f(mCoordinates.getX() * ESM::Land::REAL_SIZE, mCoordinates.getY() * ESM::Land::REAL_SIZE, 0)); + pathgridTransform->setNodeMask(Mask_Pathgrid); mCellNode->addChild(pathgridTransform); mPathgridGeode = new osg::Geode(); From b11f5b27173adaffda0a8b5d4e730d6f43a03f14 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 15:06:28 -0400 Subject: [PATCH 11/13] Make edges differently colored. --- components/sceneutil/pathgridutil.cpp | 46 +++++++++++++++++++-------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp index 1ba2c006b..37c975dff 100644 --- a/components/sceneutil/pathgridutil.cpp +++ b/components/sceneutil/pathgridutil.cpp @@ -9,6 +9,11 @@ namespace SceneUtil { const unsigned short DiamondVertexCount = 6; const unsigned short DiamondIndexCount = 24; + + const unsigned short DiamondConnectorVertexCount = 4; + + const unsigned short DiamondTotalVertexCount = DiamondVertexCount + DiamondConnectorVertexCount; + const float DiamondHalfHeight = 40.f; const float DiamondHalfWidth = 16.f; @@ -34,6 +39,11 @@ namespace SceneUtil 5, 2, 4 }; + const unsigned short DiamondConnectorVertices[DiamondConnectorVertexCount] = + { + 1, 2, 3, 4 + }; + const osg::Vec4f DiamondColors[DiamondVertexCount] = { osg::Vec4f(0.f, 0.f, 1.f, 1.f), @@ -44,12 +54,14 @@ namespace SceneUtil osg::Vec4f(0.f, .25f, 9.f, 1.f) }; + const osg::Vec4f DiamondEdgeColor = osg::Vec4f(0.5f, 1.f, 1.f, 1.f); + osg::ref_ptr PathgridGeometryFactory::create(const ESM::Pathgrid& pathgrid) { const unsigned short PointCount = static_cast(pathgrid.mPoints.size()); const size_t EdgeCount = pathgrid.mEdges.size(); - const unsigned short VertexCount = PointCount * DiamondVertexCount; + const unsigned short VertexCount = PointCount * DiamondTotalVertexCount; const unsigned short ColorCount = VertexCount; const size_t PointIndexCount = PointCount * DiamondIndexCount; const size_t EdgeIndexCount = EdgeCount * 2; @@ -64,15 +76,15 @@ namespace SceneUtil new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, EdgeIndexCount); // Add each point/node - - for (unsigned short pointIndex = 0; pointIndex < PointCount; ++pointIndex) { const ESM::Pathgrid::Point& point = pathgrid.mPoints[pointIndex]; osg::Vec3f position = osg::Vec3f(point.mX, point.mY, point.mZ); - unsigned short vertexOffset = pointIndex * DiamondVertexCount; + unsigned short vertexOffset = pointIndex * DiamondTotalVertexCount; unsigned short indexOffset = pointIndex * DiamondIndexCount; + + // Point for (unsigned short i = 0; i < DiamondVertexCount; ++i) { (*vertices)[vertexOffset + i] = position + DiamondPoints[i]; @@ -83,6 +95,14 @@ namespace SceneUtil { pointIndices->setElement(indexOffset + i, vertexOffset + DiamondIndices[i]); } + + // Connectors + vertexOffset += DiamondVertexCount; + for (unsigned short i = 0; i < DiamondConnectorVertexCount; ++i) + { + (*vertices)[vertexOffset + i] = position + DiamondPoints[DiamondConnectorVertices[i]]; + (*colors)[vertexOffset + i] = DiamondEdgeColor; + } } // Add edges @@ -108,21 +128,21 @@ namespace SceneUtil unsigned short diamondIndex = 0; if (dir.isNaN()) - diamondIndex = 1; + diamondIndex = 0; else if (dir.y() >= 0 && dir.x() > 0) - diamondIndex = 4; - else if (dir.x() <= 0 && dir.y() > 0) - diamondIndex = 2; - else if (dir.y() <= 0 && dir.x() < 0) - diamondIndex = 1; - else if (dir.x() >= 0 && dir.y() < 0) diamondIndex = 3; + else if (dir.x() <= 0 && dir.y() > 0) + diamondIndex = 1; + else if (dir.y() <= 0 && dir.x() < 0) + diamondIndex = 0; + else if (dir.x() >= 0 && dir.y() < 0) + diamondIndex = 2; unsigned short fromIndex = static_cast(edge->mV0); unsigned short toIndex = static_cast(edge->mV1); - lineIndices->setElement(lineIndex++, fromIndex * DiamondVertexCount + diamondIndex); - lineIndices->setElement(lineIndex++, toIndex * DiamondVertexCount + diamondIndex); + lineIndices->setElement(lineIndex++, fromIndex * DiamondTotalVertexCount + DiamondVertexCount + diamondIndex); + lineIndices->setElement(lineIndex++, toIndex * DiamondTotalVertexCount + DiamondVertexCount + diamondIndex); } lineIndices->resize(lineIndex); From 1f902ff0695d515673db07bc9e7518b2895640b9 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 16:08:12 -0400 Subject: [PATCH 12/13] Remove code duplication. --- apps/opencs/view/render/cell.cpp | 56 ++++++++++---------------------- apps/opencs/view/render/cell.hpp | 2 ++ 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 1bd43c23f..a87451398 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -68,6 +68,19 @@ bool CSVRender::Cell::addObjects (int start, int end) return modified; } +void CSVRender::Cell::recreatePathgrid() +{ + const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); + int pathgridIndex = pathgrids.searchId(mId); + if (pathgridIndex != -1) + { + mPathgridGeode->removeDrawable(mPathgridGeometry); + mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( + pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeode->addDrawable(mPathgridGeometry); + } +} + CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, bool deleted) : mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0), @@ -120,14 +133,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st } } - const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); - int pathgridIndex = pathgrids.searchId(mId); - if (pathgridIndex != -1) - { - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( - pathgrids.getRecord(pathgridIndex).get()); - mPathgridGeode->addDrawable(mPathgridGeometry); - } + recreatePathgrid(); } } @@ -280,9 +286,7 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int void CSVRender::Cell::pathgridAdded(const CSMWorld::Pathgrid& pathgrid) { - mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create(pathgrid); - mPathgridGeode->addDrawable(mPathgridGeometry); + recreatePathgrid(); } void CSVRender::Cell::pathgridRemoved() @@ -292,41 +296,17 @@ void CSVRender::Cell::pathgridRemoved() void CSVRender::Cell::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); - int pathgridIndex = pathgrids.searchId(mId); - if (pathgridIndex != -1) - { - mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( - pathgrids.getRecord(pathgridIndex).get()); - mPathgridGeode->addDrawable(mPathgridGeometry); - } + recreatePathgrid(); } void CSVRender::Cell::pathgridRowRemoved(const QModelIndex& parent, int start, int end) { - const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); - int pathgridIndex = pathgrids.searchId(mId); - if (pathgridIndex != -1) - { - mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( - pathgrids.getRecord(pathgridIndex).get()); - mPathgridGeode->addDrawable(mPathgridGeometry); - } + recreatePathgrid(); } void CSVRender::Cell::pathgridRowAdded(const QModelIndex& parent, int start, int end) { - const CSMWorld::SubCellCollection& pathgrids = mData.getPathgrids(); - int pathgridIndex = pathgrids.searchId(mId); - if (pathgridIndex != -1) - { - mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( - pathgrids.getRecord(pathgridIndex).get()); - mPathgridGeode->addDrawable(mPathgridGeometry); - } + recreatePathgrid(); } void CSVRender::Cell::setSelection (int elementMask, Selection mode) diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 0efb8757c..e265fc21c 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -69,6 +69,8 @@ namespace CSVRender /// \return Have any objects been added? bool addObjects (int start, int end); + void recreatePathgrid(); + public: enum Selection From 14ae232938fd18d41e5773bf1d26fc774c555499 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 3 May 2016 16:11:39 -0400 Subject: [PATCH 13/13] Remove now unnecessary factory class. It was originally used for storing normals, but that functionality was removed. --- apps/opencs/view/render/cell.cpp | 3 +-- apps/openmw/mwrender/pathgrid.cpp | 2 +- components/sceneutil/pathgridutil.cpp | 12 +----------- components/sceneutil/pathgridutil.hpp | 17 +---------------- 4 files changed, 4 insertions(+), 30 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index a87451398..691b909bb 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -75,8 +75,7 @@ void CSVRender::Cell::recreatePathgrid() if (pathgridIndex != -1) { mPathgridGeode->removeDrawable(mPathgridGeometry); - mPathgridGeometry = SceneUtil::PathgridGeometryFactory::get().create( - pathgrids.getRecord(pathgridIndex).get()); + mPathgridGeometry = SceneUtil::createPathgridGeometry(pathgrids.getRecord(pathgridIndex).get()); mPathgridGeode->addDrawable(mPathgridGeometry); } } diff --git a/apps/openmw/mwrender/pathgrid.cpp b/apps/openmw/mwrender/pathgrid.cpp index 8d790e5e0..aae97fe35 100644 --- a/apps/openmw/mwrender/pathgrid.cpp +++ b/apps/openmw/mwrender/pathgrid.cpp @@ -112,7 +112,7 @@ void Pathgrid::enableCellPathgrid(const MWWorld::CellStore *store) osg::ref_ptr cellPathGrid = new osg::PositionAttitudeTransform; cellPathGrid->setPosition(cellPathGridPos); - osg::ref_ptr geometry = SceneUtil::PathgridGeometryFactory::get().create(*pathgrid); + osg::ref_ptr geometry = SceneUtil::createPathgridGeometry(*pathgrid); cellPathGrid->addChild(geometry); diff --git a/components/sceneutil/pathgridutil.cpp b/components/sceneutil/pathgridutil.cpp index 37c975dff..5d71efd1e 100644 --- a/components/sceneutil/pathgridutil.cpp +++ b/components/sceneutil/pathgridutil.cpp @@ -56,7 +56,7 @@ namespace SceneUtil const osg::Vec4f DiamondEdgeColor = osg::Vec4f(0.5f, 1.f, 1.f, 1.f); - osg::ref_ptr PathgridGeometryFactory::create(const ESM::Pathgrid& pathgrid) + osg::ref_ptr createPathgridGeometry(const ESM::Pathgrid& pathgrid) { const unsigned short PointCount = static_cast(pathgrid.mPoints.size()); const size_t EdgeCount = pathgrid.mEdges.size(); @@ -155,14 +155,4 @@ namespace SceneUtil return gridGeometry; } - - PathgridGeometryFactory& PathgridGeometryFactory::get() - { - static PathgridGeometryFactory instance; - return instance; - } - - PathgridGeometryFactory::PathgridGeometryFactory() - { - } } diff --git a/components/sceneutil/pathgridutil.hpp b/components/sceneutil/pathgridutil.hpp index 1bb668226..d547bbf3e 100644 --- a/components/sceneutil/pathgridutil.hpp +++ b/components/sceneutil/pathgridutil.hpp @@ -11,22 +11,7 @@ namespace ESM namespace SceneUtil { - - class PathgridGeometryFactory - { - public: - - osg::ref_ptr create(const ESM::Pathgrid& pathgrid); - static PathgridGeometryFactory& get(); - - private: - - PathgridGeometryFactory(); - - // Not implemented - PathgridGeometryFactory(const PathgridGeometryFactory&); - PathgridGeometryFactory& operator=(const PathgridGeometryFactory&); - }; + osg::ref_ptr createPathgridGeometry(const ESM::Pathgrid& pathgrid); } #endif