1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 23:23:53 +00:00
openmw/apps/opencs/view/render/unpagedworldspacewidget.cpp

378 lines
11 KiB
C++
Raw Normal View History

#include "unpagedworldspacewidget.hpp"
#include <sstream>
2015-04-11 18:09:40 +00:00
#include <components/sceneutil/util.hpp>
2022-10-19 17:02:00 +00:00
#include <apps/opencs/model/world/cell.hpp>
#include <apps/opencs/model/world/cellcoordinates.hpp>
#include <apps/opencs/model/world/columns.hpp>
#include <apps/opencs/model/world/pathgrid.hpp>
#include <apps/opencs/model/world/record.hpp>
#include <apps/opencs/model/world/subcellcollection.hpp>
#include <apps/opencs/view/render/cell.hpp>
#include <apps/opencs/view/render/worldspacewidget.hpp>
#include <components/esm3/loadcell.hpp>
#include <osg/Camera>
#include <osg/Vec4f>
#include <osg/ref_ptr>
#include <osgViewer/View>
2014-03-06 12:02:21 +00:00
#include "../../model/doc/document.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp"
2014-11-28 08:14:02 +00:00
#include "../widget/scenetooltoggle2.hpp"
#include "cameracontroller.hpp"
#include "mask.hpp"
2022-10-19 17:02:00 +00:00
namespace CSVRender
{
class TagBase;
}
namespace osg
{
class Vec3f;
}
2014-03-06 12:02:21 +00:00
void CSVRender::UnpagedWorldspaceWidget::update()
{
2022-09-22 18:26:05 +00:00
const CSMWorld::Record<CSMWorld::Cell>& record
= dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&>(mCellsModel->getRecord(mCellId));
2014-03-06 12:02:21 +00:00
2015-04-11 18:09:40 +00:00
osg::Vec4f colour = SceneUtil::colourFromRGB(record.get().mAmbi.mAmbient);
2022-09-22 18:26:05 +00:00
setDefaultAmbient(colour);
2014-03-06 12:02:21 +00:00
bool isInterior = (record.get().mData.mFlags & ESM::Cell::Interior) != 0;
bool behaveLikeExterior = (record.get().mData.mFlags & ESM::Cell::QuasiEx) != 0;
setExterior(behaveLikeExterior || !isInterior);
2014-03-06 12:02:21 +00:00
/// \todo deal with mSunlight and mFog/mForDensity
flagAsModified();
2014-03-06 12:02:21 +00:00
}
2022-09-22 18:26:05 +00:00
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget(
const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
: WorldspaceWidget(document, parent)
, mDocument(document)
, mCellId(cellId)
2014-03-06 12:02:21 +00:00
{
2022-09-22 18:26:05 +00:00
mCellsModel
= &dynamic_cast<CSMWorld::IdTable&>(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells));
2014-03-06 12:02:21 +00:00
2022-09-22 18:26:05 +00:00
mReferenceablesModel = &dynamic_cast<CSMWorld::IdTable&>(
*document.getData().getTableModel(CSMWorld::UniversalId::Type_Referenceables));
2022-09-22 18:26:05 +00:00
connect(mCellsModel, &CSMWorld::IdTable::dataChanged, this, &UnpagedWorldspaceWidget::cellDataChanged);
connect(mCellsModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, this,
&UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved);
2014-03-06 12:02:21 +00:00
2022-09-22 18:26:05 +00:00
connect(
&document.getData(), &CSMWorld::Data::assetTablesChanged, this, &UnpagedWorldspaceWidget::assetTablesChanged);
2017-08-19 23:36:45 +00:00
2014-03-06 12:02:21 +00:00
update();
2022-05-29 11:25:17 +00:00
mCell = std::make_unique<Cell>(document.getData(), mRootNode, mCellId);
2014-03-06 12:02:21 +00:00
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
2014-03-06 12:02:21 +00:00
{
2022-09-22 18:26:05 +00:00
int index = mCellsModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification);
QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, index);
2014-03-06 12:02:21 +00:00
2022-09-22 18:26:05 +00:00
if (cellIndex.row() >= topLeft.row() && cellIndex.row() <= bottomRight.row())
2014-03-06 12:02:21 +00:00
{
2022-09-22 18:26:05 +00:00
if (mCellsModel->data(cellIndex).toInt() == CSMWorld::RecordBase::State_Deleted)
{
emit closeRequest();
}
else
{
/// \todo possible optimisation: check columns and update only if relevant columns have
/// changed
update();
}
2014-03-06 12:02:21 +00:00
}
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
2014-03-06 12:02:21 +00:00
{
2022-09-22 18:26:05 +00:00
QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, 0);
2014-03-06 12:02:21 +00:00
2022-09-22 18:26:05 +00:00
if (cellIndex.row() >= start && cellIndex.row() <= end)
emit closeRequest();
2014-05-01 13:09:47 +00:00
}
2017-08-19 23:36:45 +00:00
void CSVRender::UnpagedWorldspaceWidget::assetTablesChanged()
{
if (mCell)
mCell->reloadAssets();
}
2022-09-22 18:26:05 +00:00
bool CSVRender::UnpagedWorldspaceWidget::handleDrop(
const std::vector<CSMWorld::UniversalId>& universalIdData, DropType type)
2014-05-01 13:09:47 +00:00
{
2022-09-22 18:26:05 +00:00
if (WorldspaceWidget::handleDrop(universalIdData, type))
return true;
2022-09-22 18:26:05 +00:00
if (type != Type_CellsInterior)
return false;
2016-10-15 16:34:54 +00:00
mCellId = universalIdData.begin()->getId();
2022-05-29 11:25:17 +00:00
mCell = std::make_unique<Cell>(getDocument().getData(), mRootNode, mCellId);
mCamPositionSet = false;
mOrbitCamControl->reset();
2014-05-03 12:00:30 +00:00
update();
2016-10-15 16:34:54 +00:00
emit cellChanged(*universalIdData.begin());
return true;
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::clearSelection(int elementMask)
{
2022-09-22 18:26:05 +00:00
mCell->setSelection(elementMask, Cell::Selection_Clear);
2015-09-29 14:06:55 +00:00
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::invertSelection(int elementMask)
2016-05-16 21:03:00 +00:00
{
2022-09-22 18:26:05 +00:00
mCell->setSelection(elementMask, Cell::Selection_Invert);
2016-05-16 21:03:00 +00:00
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::selectAll(int elementMask)
{
2022-09-22 18:26:05 +00:00
mCell->setSelection(elementMask, Cell::Selection_All);
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId(int elementMask)
{
2022-09-22 18:26:05 +00:00
mCell->selectAllWithSameParentId(elementMask);
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::selectInsideCube(
const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode)
{
2022-09-22 18:26:05 +00:00
mCell->selectInsideCube(pointA, pointB, dragMode);
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::selectWithinDistance(
const osg::Vec3d& point, float distance, DragMode dragMode)
{
2022-09-22 18:26:05 +00:00
mCell->selectWithinDistance(point, distance, dragMode);
}
2022-09-22 18:26:05 +00:00
std::string CSVRender::UnpagedWorldspaceWidget::getCellId(const osg::Vec3f& point) const
{
return mCellId;
}
CSVRender::Cell* CSVRender::UnpagedWorldspaceWidget::getCell(const osg::Vec3d& point) const
{
return mCell.get();
}
2019-09-11 09:59:15 +00:00
CSVRender::Cell* CSVRender::UnpagedWorldspaceWidget::getCell(const CSMWorld::CellCoordinates& coords) const
{
return mCell.get();
}
2022-11-04 22:04:42 +00:00
osg::ref_ptr<CSVRender::TagBase> CSVRender::UnpagedWorldspaceWidget::getSnapTarget(unsigned int elementMask) const
{
return mCell->getSnapTarget(elementMask);
}
2022-09-22 18:26:05 +00:00
std::vector<osg::ref_ptr<CSVRender::TagBase>> CSVRender::UnpagedWorldspaceWidget::getSelection(
unsigned int elementMask) const
{
2022-09-22 18:26:05 +00:00
return mCell->getSelection(elementMask);
}
2022-09-22 18:26:05 +00:00
std::vector<osg::ref_ptr<CSVRender::TagBase>> CSVRender::UnpagedWorldspaceWidget::getEdited(
2016-02-16 15:02:29 +00:00
unsigned int elementMask) const
{
2022-09-22 18:26:05 +00:00
return mCell->getEdited(elementMask);
2016-02-16 15:02:29 +00:00
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::setSubMode(int subMode, unsigned int elementMask)
2016-03-01 14:48:34 +00:00
{
2022-09-22 18:26:05 +00:00
mCell->setSubMode(subMode, elementMask);
2016-03-01 14:48:34 +00:00
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::reset(unsigned int elementMask)
2016-03-04 14:19:26 +00:00
{
2022-09-22 18:26:05 +00:00
mCell->reset(elementMask);
2016-03-04 14:19:26 +00:00
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged(
const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (mCell.get())
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceableDataChanged(topLeft, bottomRight))
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceableAboutToBeRemoved(parent, start, end))
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceableAdded(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
{
2022-09-22 18:26:05 +00:00
QModelIndex topLeft = mReferenceablesModel->index(start, 0);
QModelIndex bottomRight = mReferenceablesModel->index(end, mReferenceablesModel->columnCount());
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceableDataChanged(topLeft, bottomRight))
flagAsModified();
}
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceDataChanged(
const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (mCell.get())
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceDataChanged(topLeft, bottomRight))
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceAboutToBeRemoved(parent, start, end))
flagAsModified();
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::referenceAdded(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
2022-09-22 18:26:05 +00:00
if (mCell.get()->referenceAdded(parent, start, end))
flagAsModified();
2014-05-03 12:00:30 +00:00
}
2014-05-01 13:09:47 +00:00
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
2016-05-03 02:08:49 +00:00
{
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
int rowStart = -1;
int rowEnd = -1;
2016-05-03 02:08:49 +00:00
if (topLeft.parent().isValid())
{
rowStart = topLeft.parent().row();
rowEnd = bottomRight.parent().row();
}
else
{
rowStart = topLeft.row();
rowEnd = bottomRight.row();
2016-05-03 02:08:49 +00:00
}
for (int row = rowStart; row <= rowEnd; ++row)
{
2016-05-03 02:08:49 +00:00
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
2016-05-03 02:08:49 +00:00
{
mCell->pathgridModified();
2016-05-03 02:08:49 +00:00
flagAsModified();
return;
2016-05-03 02:08:49 +00:00
}
}
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end)
2016-05-03 02:08:49 +00:00
{
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& 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 (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
2016-05-03 02:08:49 +00:00
{
mCell->pathgridRemoved();
flagAsModified();
return;
2016-05-03 02:08:49 +00:00
}
}
}
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end)
2016-05-03 02:08:49 +00:00
{
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
if (!parent.isValid())
{
for (int row = start; row <= end; ++row)
{
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
2016-05-03 02:08:49 +00:00
{
mCell->pathgridModified();
2016-05-03 02:08:49 +00:00
flagAsModified();
return;
2016-05-03 02:08:49 +00:00
}
}
}
}
2022-09-22 18:26:05 +00:00
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool)
{
2022-09-22 18:26:05 +00:00
WorldspaceWidget::addVisibilitySelectorButtons(tool);
tool->addButton(Button_Terrain, Mask_Terrain, "Terrain", "", true);
tool->addButton(Button_Fog, Mask_Fog, "Fog");
}
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
{
osg::Vec3d eye, center, up;
mView->getCamera()->getViewMatrixAsLookAt(eye, center, up);
osg::Vec3d position = eye;
std::ostringstream stream;
2022-09-22 18:26:05 +00:00
stream << "player->positionCell " << position.x() << ", " << position.y() << ", " << position.z() << ", 0, \""
<< mCellId << "\"";
return stream.str();
}
2022-09-22 18:26:05 +00:00
CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements(
CSVRender::WorldspaceWidget::DropType type) const
2014-05-03 12:00:30 +00:00
{
2022-09-22 18:26:05 +00:00
dropRequirments requirements = WorldspaceWidget::getDropRequirements(type);
2022-09-22 18:26:05 +00:00
if (requirements != ignored)
return requirements;
2022-09-22 18:26:05 +00:00
switch (type)
2014-05-01 13:09:47 +00:00
{
case Type_CellsInterior:
2014-05-03 12:00:30 +00:00
return canHandle;
2014-05-01 13:09:47 +00:00
case Type_CellsExterior:
2014-05-03 12:00:30 +00:00
return needPaged;
2014-05-01 13:09:47 +00:00
2014-05-03 12:00:30 +00:00
default:
return ignored;
}
2014-05-01 13:09:47 +00:00
}