1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-22 00:53:52 +00:00
openmw/apps/opencs/view/render/unpagedworldspacewidget.cpp
fteppe 20da0892ef openMW_test_suite compiles and runs
Slowly moving through the open-cs errors

Good progress in openCS

Very good progress on openCS

Getting closer with openCS

OpenCS compiles and runs! Didn't have time to test it all though

ix openMW

everything compiles on windows??

Fix gcc

Fix Clang
2022-12-27 19:15:55 +01:00

377 lines
11 KiB
C++

#include "unpagedworldspacewidget.hpp"
#include <sstream>
#include <components/sceneutil/util.hpp>
#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>
#include "../../model/doc/document.hpp"
#include "../../model/world/data.hpp"
#include "../../model/world/idtable.hpp"
#include "../widget/scenetooltoggle2.hpp"
#include "cameracontroller.hpp"
#include "mask.hpp"
namespace CSVRender
{
class TagBase;
}
namespace osg
{
class Vec3f;
}
void CSVRender::UnpagedWorldspaceWidget::update()
{
const CSMWorld::Record<CSMWorld::Cell>& record
= dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&>(mCellsModel->getRecord(mCellId));
osg::Vec4f colour = SceneUtil::colourFromRGB(record.get().mAmbi.mAmbient);
setDefaultAmbient(colour);
bool isInterior = (record.get().mData.mFlags & ESM::Cell::Interior) != 0;
bool behaveLikeExterior = (record.get().mData.mFlags & ESM::Cell::QuasiEx) != 0;
setExterior(behaveLikeExterior || !isInterior);
/// \todo deal with mSunlight and mFog/mForDensity
flagAsModified();
}
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget(
const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
: WorldspaceWidget(document, parent)
, mDocument(document)
, mCellId(cellId)
{
mCellsModel
= &dynamic_cast<CSMWorld::IdTable&>(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells));
mReferenceablesModel = &dynamic_cast<CSMWorld::IdTable&>(
*document.getData().getTableModel(CSMWorld::UniversalId::Type_Referenceables));
connect(mCellsModel, &CSMWorld::IdTable::dataChanged, this, &UnpagedWorldspaceWidget::cellDataChanged);
connect(mCellsModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, this,
&UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved);
connect(
&document.getData(), &CSMWorld::Data::assetTablesChanged, this, &UnpagedWorldspaceWidget::assetTablesChanged);
update();
mCell = std::make_unique<Cell>(document.getData(), mRootNode, mCellId);
}
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
int index = mCellsModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification);
QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, index);
if (cellIndex.row() >= topLeft.row() && cellIndex.row() <= bottomRight.row())
{
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();
}
}
}
void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, 0);
if (cellIndex.row() >= start && cellIndex.row() <= end)
emit closeRequest();
}
void CSVRender::UnpagedWorldspaceWidget::assetTablesChanged()
{
if (mCell)
mCell->reloadAssets();
}
bool CSVRender::UnpagedWorldspaceWidget::handleDrop(
const std::vector<CSMWorld::UniversalId>& universalIdData, DropType type)
{
if (WorldspaceWidget::handleDrop(universalIdData, type))
return true;
if (type != Type_CellsInterior)
return false;
mCellId = universalIdData.begin()->getId();
mCell = std::make_unique<Cell>(getDocument().getData(), mRootNode, mCellId);
mCamPositionSet = false;
mOrbitCamControl->reset();
update();
emit cellChanged(*universalIdData.begin());
return true;
}
void CSVRender::UnpagedWorldspaceWidget::clearSelection(int elementMask)
{
mCell->setSelection(elementMask, Cell::Selection_Clear);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::invertSelection(int elementMask)
{
mCell->setSelection(elementMask, Cell::Selection_Invert);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectAll(int elementMask)
{
mCell->setSelection(elementMask, Cell::Selection_All);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId(int elementMask)
{
mCell->selectAllWithSameParentId(elementMask);
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::selectInsideCube(
const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode)
{
mCell->selectInsideCube(pointA, pointB, dragMode);
}
void CSVRender::UnpagedWorldspaceWidget::selectWithinDistance(
const osg::Vec3d& point, float distance, DragMode dragMode)
{
mCell->selectWithinDistance(point, distance, dragMode);
}
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();
}
CSVRender::Cell* CSVRender::UnpagedWorldspaceWidget::getCell(const CSMWorld::CellCoordinates& coords) const
{
return mCell.get();
}
osg::ref_ptr<CSVRender::TagBase> CSVRender::UnpagedWorldspaceWidget::getSnapTarget(unsigned int elementMask) const
{
return mCell->getSnapTarget(elementMask);
}
std::vector<osg::ref_ptr<CSVRender::TagBase>> CSVRender::UnpagedWorldspaceWidget::getSelection(
unsigned int elementMask) const
{
return mCell->getSelection(elementMask);
}
std::vector<osg::ref_ptr<CSVRender::TagBase>> CSVRender::UnpagedWorldspaceWidget::getEdited(
unsigned int elementMask) const
{
return mCell->getEdited(elementMask);
}
void CSVRender::UnpagedWorldspaceWidget::setSubMode(int subMode, unsigned int elementMask)
{
mCell->setSubMode(subMode, elementMask);
}
void CSVRender::UnpagedWorldspaceWidget::reset(unsigned int elementMask)
{
mCell->reset(elementMask);
}
void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged(
const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (mCell.get())
if (mCell.get()->referenceableDataChanged(topLeft, bottomRight))
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
if (mCell.get()->referenceableAboutToBeRemoved(parent, start, end))
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::referenceableAdded(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
{
QModelIndex topLeft = mReferenceablesModel->index(start, 0);
QModelIndex bottomRight = mReferenceablesModel->index(end, mReferenceablesModel->columnCount());
if (mCell.get()->referenceableDataChanged(topLeft, bottomRight))
flagAsModified();
}
}
void CSVRender::UnpagedWorldspaceWidget::referenceDataChanged(
const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
if (mCell.get())
if (mCell.get()->referenceDataChanged(topLeft, bottomRight))
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
if (mCell.get()->referenceAboutToBeRemoved(parent, start, end))
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::referenceAdded(const QModelIndex& parent, int start, int end)
{
if (mCell.get())
if (mCell.get()->referenceAdded(parent, start, end))
flagAsModified();
}
void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
const CSMWorld::SubCellCollection<CSMWorld::Pathgrid>& pathgrids = mDocument.getData().getPathgrids();
int rowStart = -1;
int rowEnd = -1;
if (topLeft.parent().isValid())
{
rowStart = topLeft.parent().row();
rowEnd = bottomRight.parent().row();
}
else
{
rowStart = topLeft.row();
rowEnd = bottomRight.row();
}
for (int row = rowStart; row <= rowEnd; ++row)
{
const CSMWorld::Pathgrid& pathgrid = pathgrids.getRecord(row).get();
if (ESM::RefId::stringRefId(mCellId) == pathgrid.mId)
{
mCell->pathgridModified();
flagAsModified();
return;
}
}
}
void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
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)
{
mCell->pathgridRemoved();
flagAsModified();
return;
}
}
}
}
void CSVRender::UnpagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end)
{
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)
{
mCell->pathgridModified();
flagAsModified();
return;
}
}
}
}
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool)
{
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;
stream << "player->positionCell " << position.x() << ", " << position.y() << ", " << position.z() << ", 0, \""
<< mCellId << "\"";
return stream.str();
}
CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements(
CSVRender::WorldspaceWidget::DropType type) const
{
dropRequirments requirements = WorldspaceWidget::getDropRequirements(type);
if (requirements != ignored)
return requirements;
switch (type)
{
case Type_CellsInterior:
return canHandle;
case Type_CellsExterior:
return needPaged;
default:
return ignored;
}
}