mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-24 11:11:34 +00:00
Merge branch 'cells'
This commit is contained in:
commit
b5650f5d4f
12 changed files with 561 additions and 19 deletions
|
@ -70,7 +70,7 @@ opencs_units (view/render
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight
|
||||||
lightingbright object
|
lightingbright object cell
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
|
|
201
apps/opencs/view/render/cell.cpp
Normal file
201
apps/opencs/view/render/cell.cpp
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
|
||||||
|
#include "cell.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/columns.hpp"
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
|
||||||
|
bool CSVRender::Cell::removeObject (const std::string& id)
|
||||||
|
{
|
||||||
|
std::map<std::string, Object *>::iterator iter =
|
||||||
|
mObjects.find (Misc::StringUtils::lowerCase (id));
|
||||||
|
|
||||||
|
if (iter==mObjects.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
delete iter->second;
|
||||||
|
mObjects.erase (iter);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
|
{
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell);
|
||||||
|
int stateColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (int i=start; i<=end; ++i)
|
||||||
|
{
|
||||||
|
std::string cell = Misc::StringUtils::lowerCase (references.data (
|
||||||
|
references.index (i, cellColumn)).toString().toUtf8().constData());
|
||||||
|
|
||||||
|
int state = references.data (references.index (i, stateColumn)).toInt();
|
||||||
|
|
||||||
|
if (cell==mId && state!=CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
std::string id = Misc::StringUtils::lowerCase (references.data (
|
||||||
|
references.index (i, idColumn)).toString().toUtf8().constData());
|
||||||
|
|
||||||
|
mObjects.insert (std::make_pair (id, new Object (mData, mCellNode, id, false)));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||||
|
const std::string& id, const Ogre::Vector3& origin)
|
||||||
|
: mData (data), mId (Misc::StringUtils::lowerCase (id))
|
||||||
|
{
|
||||||
|
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mCellNode->setPosition (origin);
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int rows = references.rowCount();
|
||||||
|
|
||||||
|
addObjects (0, rows-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Cell::~Cell()
|
||||||
|
{
|
||||||
|
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
delete iter->second;
|
||||||
|
|
||||||
|
mCellNode->getCreator()->destroySceneNode (mCellNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
if (iter->second->referenceableDataChanged (topLeft, bottomRight))
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
if (iter->second->referenceableAboutToBeRemoved (parent, start, end))
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell);
|
||||||
|
int stateColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
|
||||||
|
// list IDs in cell
|
||||||
|
std::map<std::string, bool> ids; // id, deleted state
|
||||||
|
|
||||||
|
for (int i=topLeft.row(); i<=bottomRight.row(); ++i)
|
||||||
|
{
|
||||||
|
std::string cell = Misc::StringUtils::lowerCase (references.data (
|
||||||
|
references.index (i, cellColumn)).toString().toUtf8().constData());
|
||||||
|
|
||||||
|
if (cell==mId)
|
||||||
|
{
|
||||||
|
std::string id = Misc::StringUtils::lowerCase (references.data (
|
||||||
|
references.index (i, idColumn)).toString().toUtf8().constData());
|
||||||
|
|
||||||
|
int state = references.data (references.index (i, stateColumn)).toInt();
|
||||||
|
|
||||||
|
ids.insert (std::make_pair (id, state==CSMWorld::RecordBase::State_Deleted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform update and remove where needed
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (std::map<std::string, Object *>::iterator iter (mObjects.begin());
|
||||||
|
iter!=mObjects.end(); ++iter)
|
||||||
|
{
|
||||||
|
if (iter->second->referenceDataChanged (topLeft, bottomRight))
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
std::map<std::string, bool>::iterator iter2 = ids.find (iter->first);
|
||||||
|
|
||||||
|
if (iter2!=ids.end())
|
||||||
|
{
|
||||||
|
if (iter2->second)
|
||||||
|
{
|
||||||
|
removeObject (iter->first);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ids.erase (iter2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new objects
|
||||||
|
for (std::map<std::string, bool>::iterator iter (ids.begin()); iter!=ids.end(); ++iter)
|
||||||
|
{
|
||||||
|
mObjects.insert (std::make_pair (
|
||||||
|
iter->first, new Object (mData, mCellNode, iter->first, false)));
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id);
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (int row = start; row<=end; ++row)
|
||||||
|
if (removeObject (references.data (
|
||||||
|
references.index (row, idColumn)).toString().toUtf8().constData()))
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return addObjects (start, end);
|
||||||
|
}
|
73
apps/opencs/view/render/cell.hpp
Normal file
73
apps/opencs/view/render/cell.hpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef OPENCS_VIEW_CELL_H
|
||||||
|
#define OPENCS_VIEW_CELL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
#include "object.hpp"
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class SceneManager;
|
||||||
|
class SceneNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Cell
|
||||||
|
{
|
||||||
|
CSMWorld::Data& mData;
|
||||||
|
std::string mId;
|
||||||
|
Ogre::SceneNode *mCellNode;
|
||||||
|
std::map<std::string, Object *> mObjects;
|
||||||
|
|
||||||
|
/// Ignored if cell does not have an object with the given ID.
|
||||||
|
///
|
||||||
|
/// \return Was the object deleted?
|
||||||
|
bool removeObject (const std::string& id);
|
||||||
|
|
||||||
|
/// Add objects from reference table that are within this cell.
|
||||||
|
///
|
||||||
|
/// \return Have any objects been added?
|
||||||
|
bool addObjects (int start, int end);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||||
|
const std::string& id, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
|
~Cell();
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this cell?
|
||||||
|
bool referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this cell?
|
||||||
|
bool referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this cell?
|
||||||
|
bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this cell?
|
||||||
|
bool referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
/// \return Did this call result in a modification of the visual representation of
|
||||||
|
/// this cell?
|
||||||
|
bool referenceAdded (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,7 +49,7 @@ void CSVRender::Object::update()
|
||||||
error = 1;
|
error = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// xxx check for Deleted state (error 1)
|
/// \todo check for Deleted state (error 1)
|
||||||
|
|
||||||
model = referenceables.getData (index,
|
model = referenceables.getData (index,
|
||||||
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)).
|
referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model)).
|
||||||
|
@ -81,19 +81,15 @@ void CSVRender::Object::adjust()
|
||||||
|
|
||||||
// position
|
// position
|
||||||
if (!mForceBaseToZero)
|
if (!mForceBaseToZero)
|
||||||
{
|
|
||||||
Ogre::Vector3 (reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]);
|
|
||||||
|
|
||||||
mBase->setPosition (Ogre::Vector3 (
|
mBase->setPosition (Ogre::Vector3 (
|
||||||
reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]));
|
||||||
}
|
|
||||||
|
|
||||||
// orientation
|
// orientation
|
||||||
Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.pos[0]), Ogre::Vector3::UNIT_X);
|
Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.rot[0]), Ogre::Vector3::UNIT_X);
|
||||||
|
|
||||||
Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.pos[1]), Ogre::Vector3::UNIT_Y);
|
Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.rot[1]), Ogre::Vector3::UNIT_Y);
|
||||||
|
|
||||||
Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.pos[2]), Ogre::Vector3::UNIT_Z);
|
Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.rot[2]), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
mBase->setOrientation (xr*yr*zr);
|
mBase->setOrientation (xr*yr*zr);
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,137 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
#include <QtGui/qevent.h>
|
#include <QtGui/qevent.h>
|
||||||
|
|
||||||
#include <apps/opencs/model/world/tablemimedata.hpp>
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||||
|
{
|
||||||
|
bool modified = false;
|
||||||
|
bool setCamera = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
// remove
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
|
||||||
|
while (iter!=mCells.end())
|
||||||
|
{
|
||||||
|
if (!mSelection.has (iter->first))
|
||||||
|
{
|
||||||
|
delete iter->second;
|
||||||
|
mCells.erase (iter++);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCells.begin()==mCells.end())
|
||||||
|
setCamera = true;
|
||||||
|
|
||||||
|
// add
|
||||||
|
for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
if (mCells.find (*iter)==mCells.end())
|
||||||
|
{
|
||||||
|
if (setCamera)
|
||||||
|
{
|
||||||
|
setCamera = false;
|
||||||
|
getCamera()->setPosition (8192*iter->getX()+4096, 8192*iter->getY()+4096, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCells.insert (std::make_pair (*iter,
|
||||||
|
new Cell (mDocument.getData(), getSceneManager(),
|
||||||
|
iter->getId ("std::default"))));
|
||||||
|
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
if (iter->second->referenceableDataChanged (topLeft, bottomRight))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceableAboutToBeRemoved (
|
||||||
|
const QModelIndex& parent, int start, int end)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
if (iter->second->referenceableAboutToBeRemoved (parent, start, end))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceableAdded (const QModelIndex& parent,
|
||||||
|
int start, int end)
|
||||||
|
{
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
{
|
||||||
|
QModelIndex topLeft = referenceables.index (start, 0);
|
||||||
|
QModelIndex bottomRight =
|
||||||
|
referenceables.index (end, referenceables.columnCount());
|
||||||
|
|
||||||
|
if (iter->second->referenceableDataChanged (topLeft, bottomRight))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
if (iter->second->referenceDataChanged (topLeft, bottomRight))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceAboutToBeRemoved (const QModelIndex& parent,
|
||||||
|
int start, int end)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
if (iter->second->referenceAboutToBeRemoved (parent, start, end))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
if (iter->second->referenceAdded (parent, start, end))
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document)
|
||||||
: WorldspaceWidget (document, parent)
|
: WorldspaceWidget (document, parent), mDocument (document)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
||||||
|
{
|
||||||
|
for (std::map<CSMWorld::CellCoordinates, Cell *>::iterator iter (mCells.begin());
|
||||||
|
iter!=mCells.end(); ++iter)
|
||||||
|
delete iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
||||||
{
|
{
|
||||||
if (!hint.empty())
|
if (!hint.empty())
|
||||||
|
@ -47,6 +170,10 @@ void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
||||||
void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection)
|
void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection)
|
||||||
{
|
{
|
||||||
mSelection = selection;
|
mSelection = selection;
|
||||||
|
|
||||||
|
if (adjustCells())
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
emit cellSelectionChanged (mSelection);
|
emit cellSelectionChanged (mSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +199,9 @@ void CSVRender::PagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld::
|
||||||
}
|
}
|
||||||
if (selectionChanged)
|
if (selectionChanged)
|
||||||
{
|
{
|
||||||
|
if (adjustCells())
|
||||||
|
flagAsModified();
|
||||||
|
|
||||||
emit cellSelectionChanged(mSelection);
|
emit cellSelectionChanged(mSelection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "../../model/world/cellselection.hpp"
|
#include "../../model/world/cellselection.hpp"
|
||||||
|
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
|
#include "cell.hpp"
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
@ -11,12 +14,32 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMDoc::Document& mDocument;
|
||||||
CSMWorld::CellSelection mSelection;
|
CSMWorld::CellSelection mSelection;
|
||||||
|
std::map<CSMWorld::CellCoordinates, Cell *> mCells;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::pair<int, int> getCoordinatesFromId(const std::string& record) const;
|
std::pair<int, int> getCoordinatesFromId(const std::string& record) const;
|
||||||
|
|
||||||
|
/// Bring mCells into sync with mSelection again.
|
||||||
|
///
|
||||||
|
/// \return Any cells added or removed?
|
||||||
|
bool adjustCells();
|
||||||
|
|
||||||
|
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceableAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document);
|
||||||
|
@ -24,6 +47,8 @@ namespace CSVRender
|
||||||
/// no cells are displayed. The cells to be displayed will be specified later through
|
/// no cells are displayed. The cells to be displayed will be specified later through
|
||||||
/// hint system.
|
/// hint system.
|
||||||
|
|
||||||
|
virtual ~PagedWorldspaceWidget();
|
||||||
|
|
||||||
void useViewHint (const std::string& hint);
|
void useViewHint (const std::string& hint);
|
||||||
|
|
||||||
void setCellSelection (const CSMWorld::CellSelection& selection);
|
void setCellSelection (const CSMWorld::CellSelection& selection);
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace CSVRender
|
||||||
mCamera->setPosition (300, 0, 0);
|
mCamera->setPosition (300, 0, 0);
|
||||||
mCamera->lookAt (0, 0, 0);
|
mCamera->lookAt (0, 0, 0);
|
||||||
mCamera->setNearClipDistance (0.1);
|
mCamera->setNearClipDistance (0.1);
|
||||||
mCamera->setFarClipDistance (30000);
|
mCamera->setFarClipDistance (300000); ///< \todo make this configurable
|
||||||
mCamera->roll (Ogre::Degree (90));
|
mCamera->roll (Ogre::Degree (90));
|
||||||
|
|
||||||
setLighting (&mLightingDay);
|
setLighting (&mLightingDay);
|
||||||
|
@ -137,6 +137,11 @@ namespace CSVRender
|
||||||
return mSceneMgr;
|
return mSceneMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Camera *SceneWidget::getCamera()
|
||||||
|
{
|
||||||
|
return mCamera;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneWidget::flagAsModified()
|
void SceneWidget::flagAsModified()
|
||||||
{
|
{
|
||||||
mUpdate = true;
|
mUpdate = true;
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace CSVRender
|
||||||
|
|
||||||
Ogre::SceneManager *getSceneManager();
|
Ogre::SceneManager *getSceneManager();
|
||||||
|
|
||||||
|
Ogre::Camera *getCamera();
|
||||||
|
|
||||||
void flagAsModified();
|
void flagAsModified();
|
||||||
|
|
||||||
void setDefaultAmbient (const Ogre::ColourValue& colour);
|
void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
|
|
@ -21,6 +21,8 @@ void CSVRender::UnpagedWorldspaceWidget::update()
|
||||||
setDefaultAmbient (colour);
|
setDefaultAmbient (colour);
|
||||||
|
|
||||||
/// \todo deal with mSunlight and mFog/mForDensity
|
/// \todo deal with mSunlight and mFog/mForDensity
|
||||||
|
|
||||||
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
||||||
|
@ -29,12 +31,17 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
|
||||||
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||||
|
|
||||||
|
mReferenceablesModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
connect (mCellsModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
connect (mCellsModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
|
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||||
|
@ -72,6 +79,62 @@ void CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector< CSMWorld
|
||||||
mCellId = data.begin()->getId();
|
mCellId = data.begin()->getId();
|
||||||
update();
|
update();
|
||||||
emit cellChanged(*data.begin());
|
emit cellChanged(*data.begin());
|
||||||
|
|
||||||
|
/// \todo replace mCell
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const
|
CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::dropType type) const
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
#define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
#define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
|
#include "cell.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
@ -25,6 +27,8 @@ namespace CSVRender
|
||||||
|
|
||||||
std::string mCellId;
|
std::string mCellId;
|
||||||
CSMWorld::IdTable *mCellsModel;
|
CSMWorld::IdTable *mCellsModel;
|
||||||
|
CSMWorld::IdTable *mReferenceablesModel;
|
||||||
|
std::auto_ptr<Cell> mCell;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
@ -37,6 +41,21 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
|
virtual void handleDrop(const std::vector<CSMWorld::UniversalId>& data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceableAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
virtual void referenceAdded (const QModelIndex& index, int start, int end);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
|
@ -10,15 +10,30 @@
|
||||||
#include "../world/scenetoolmode.hpp"
|
#include "../world/scenetoolmode.hpp"
|
||||||
#include <apps/opencs/model/world/universalid.hpp>
|
#include <apps/opencs/model/world/universalid.hpp>
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::WorldspaceWidget (const CSMDoc::Document& document, QWidget* parent)
|
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||||
: SceneWidget (parent), mDocument(document)
|
: SceneWidget (parent), mDocument(document)
|
||||||
{
|
{
|
||||||
Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
|
||||||
ent->setMaterialName("BaseWhite");
|
|
||||||
|
|
||||||
getSceneManager()->getRootSceneNode()->attachObject(ent);
|
|
||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
QAbstractItemModel *referenceables =
|
||||||
|
document.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||||
|
|
||||||
|
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (referenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (referenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
connect (referenceables, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (referenceableAdded (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
QAbstractItemModel *references =
|
||||||
|
document.getData().getTableModel (CSMWorld::UniversalId::Type_References);
|
||||||
|
|
||||||
|
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (referenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (referenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
connect (references, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (referenceAdded (const QModelIndex&, int, int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace CSVRender
|
||||||
ignored //either mixed cells, or not cells
|
ignored //either mixed cells, or not cells
|
||||||
};
|
};
|
||||||
|
|
||||||
WorldspaceWidget (const CSMDoc::Document& document, QWidget *parent = 0);
|
WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = 0);
|
||||||
|
|
||||||
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
||||||
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||||
|
@ -79,6 +79,19 @@ namespace CSVRender
|
||||||
|
|
||||||
void selectNavigationMode (const std::string& mode);
|
void selectNavigationMode (const std::string& mode);
|
||||||
|
|
||||||
|
virtual void referenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight) = 0;
|
||||||
|
|
||||||
|
virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void referenceableAdded (const QModelIndex& index, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0;
|
||||||
|
|
||||||
|
virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0;
|
||||||
|
|
||||||
|
virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
|
Loading…
Reference in a new issue