From f8019b4a97baf5ee15fb88bc8047a4d4e6b76e9c Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 21 Jul 2014 18:35:51 +0200 Subject: [PATCH 01/63] added a bilboard with the Cell coord. Can't be toggled off yet, and no clean up too. --- .../view/render/pagedworldspacewidget.cpp | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 1ee32fa97..e8a38321f 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -4,12 +4,192 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" +void WriteToTexture(const Ogre::String &str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font* font, const Ogre::ColourValue &color, char justify = 'l', bool wordwrap = true) +{ + using namespace Ogre; + + if (destTexture->getHeight() < destRectangle.bottom) + destRectangle.bottom = destTexture->getHeight(); + if (destTexture->getWidth() < destRectangle.right) + destRectangle.right = destTexture->getWidth(); + + if (!font->isLoaded()) + font->load(); + + TexturePtr fontTexture = (TexturePtr)TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()); + + HardwarePixelBufferSharedPtr fontBuffer = fontTexture->getBuffer(); + HardwarePixelBufferSharedPtr destBuffer = destTexture->getBuffer(); + + PixelBox destPb = destBuffer->lock(destRectangle, HardwareBuffer::HBL_NORMAL); + + // The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?) + + // create a buffer + size_t nBuffSize = fontBuffer->getSizeInBytes(); + uint8* buffer = (uint8*)calloc(nBuffSize, sizeof(uint8)); + + // create pixel box using the copy of the buffer + PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(), fontBuffer->getDepth(), fontBuffer->getFormat(), buffer); + fontBuffer->blitToMemory(fontPb); + + uint8* fontData = static_cast(fontPb.data); + uint8* destData = static_cast(destPb.data); + + const size_t fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format); + const size_t destPixelSize = PixelUtil::getNumElemBytes(destPb.format); + + const size_t fontRowPitchBytes = fontPb.rowPitch * fontPixelSize; + const size_t destRowPitchBytes = destPb.rowPitch * destPixelSize; + + Box *GlyphTexCoords; + GlyphTexCoords = new Box[str.size()]; + + Font::UVRect glypheTexRect; + size_t charheight = 0; + size_t charwidth = 0; + + for (unsigned int i = 0; i < str.size(); i++) + { + if ((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' ')) + { + glypheTexRect = font->getGlyphTexCoords(str[i]); + GlyphTexCoords[i].left = glypheTexRect.left * fontTexture->getSrcWidth(); + GlyphTexCoords[i].top = glypheTexRect.top * fontTexture->getSrcHeight(); + GlyphTexCoords[i].right = glypheTexRect.right * fontTexture->getSrcWidth(); + GlyphTexCoords[i].bottom = glypheTexRect.bottom * fontTexture->getSrcHeight(); + + if (GlyphTexCoords[i].getHeight() > charheight) + charheight = GlyphTexCoords[i].getHeight(); + if (GlyphTexCoords[i].getWidth() > charwidth) + charwidth = GlyphTexCoords[i].getWidth(); + } + + } + + size_t cursorX = 0; + size_t cursorY = 0; + size_t lineend = destRectangle.getWidth(); + bool carriagreturn = true; + for (unsigned int strindex = 0; strindex < str.size(); strindex++) + { + switch (str[strindex]) + { + case ' ': cursorX += charwidth; break; + case '\t':cursorX += charwidth * 3; break; + case '\n':cursorY += charheight; carriagreturn = true; break; + default: + { + //wrapping + if ((cursorX + GlyphTexCoords[strindex].getWidth()> lineend) && !carriagreturn) + { + cursorY += charheight; + carriagreturn = true; + } + + //justify + if (carriagreturn) + { + size_t l = strindex; + size_t textwidth = 0; + size_t wordwidth = 0; + + while ((l < str.size()) && (str[l] != '\n)')) + { + wordwidth = 0; + + switch (str[l]) + { + case ' ': wordwidth = charwidth; ++l; break; + case '\t': wordwidth = charwidth * 3; ++l; break; + case '\n': l = str.size(); + } + + if (wordwrap) + while ((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) + { + wordwidth += GlyphTexCoords[l].getWidth(); + ++l; + } + else + { + wordwidth += GlyphTexCoords[l].getWidth(); + l++; + } + + if ((textwidth + wordwidth) <= destRectangle.getWidth()) + textwidth += (wordwidth); + else + break; + } + + if ((textwidth == 0) && (wordwidth > destRectangle.getWidth())) + textwidth = destRectangle.getWidth(); + + switch (justify) + { + case 'c': cursorX = (destRectangle.getWidth() - textwidth) / 2; + lineend = destRectangle.getWidth() - cursorX; + break; + + case 'r': cursorX = (destRectangle.getWidth() - textwidth); + lineend = destRectangle.getWidth(); + break; + + default: cursorX = 0; + lineend = textwidth; + break; + } + + carriagreturn = false; + } + + //abort - net enough space to draw + if ((cursorY + charheight) > destRectangle.getHeight()) + goto stop; + + //draw pixel by pixel + for (size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++) + for (size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++) + { + float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0); + float invalpha = 1.0 - alpha; + size_t offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize; + ColourValue pix; + PixelUtil::unpackColour(&pix, destPb.format, &destData[offset]); + pix = (pix * invalpha) + (color * alpha); + PixelUtil::packColour(pix, destPb.format, &destData[offset]); + } + + cursorX += GlyphTexCoords[strindex].getWidth(); + }//default + }//switch + }//for + +stop: + delete[] GlyphTexCoords; + + destBuffer->unlock(); + + // Free the memory allocated for the buffer + free(buffer); buffer = 0; +} + bool CSVRender::PagedWorldspaceWidget::adjustCells() { bool modified = false; @@ -59,6 +239,61 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); + //billboard which indicate the Cell coord + Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); + billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); + + Ogre::Font* font; + if (Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).isNull()) + { + font = Ogre::FontManager::getSingletonPtr()->create("CellBillboardFont" + iter->getId(mWorldspace), "Data00000001").getPointer(); + font->setType(Ogre::FT_TRUETYPE); + font->setSource("Comic.ttf"); + font->setTrueTypeSize(256); + font->load(); + } + else + { + font = Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).getPointer(); + } + + //std:: + + Ogre::TexturePtr texture; + if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) + { + texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); + } + else + { + texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), "Data00000001", Ogre::TEX_TYPE_2D, 1024, 512, Ogre::MIP_UNLIMITED, Ogre::PF_X8R8G8B8, Ogre::TU_STATIC | Ogre::TU_AUTOMIPMAP); + WriteToTexture(std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()), texture, Ogre::Image::Box(0, 100, 1024, 512), font, Ogre::ColourValue(1.0, 1.0, 1.0, 1.0), 'c'); + } + + Ogre::MaterialPtr material; + if (Ogre::MaterialManager::getSingleton().resourceExists("CellBillboardMaterial" + iter->getId(mWorldspace))) + { + material = Ogre::MaterialManager::getSingleton().getByName("CellBillboardMaterial" + iter->getId(mWorldspace)); + } + else + { + material = Ogre::MaterialManager::getSingleton().create( + "CellBillboardMaterial" + iter->getId(mWorldspace), // name + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + material->getTechnique(0)->getPass(0)->createTextureUnitState("CellBillboardTexture" + iter->getId(mWorldspace)); + material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); + material->setDepthCheckEnabled(false); + material->setDepthWriteEnabled(false); + } + + Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); + Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); + mySet->setMaterial(material); + myBillboard->setDimensions(4000, 2000); + mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top + billboardNode->attachObject(mySet); + modified = true; } } From a5058625b3b606f513647be735f68d81e5026054 Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 21 Jul 2014 18:57:35 +0200 Subject: [PATCH 02/63] clean up + toggle function for the billboard --- .../view/render/pagedworldspacewidget.cpp | 24 ++++++++++++++++--- .../view/render/pagedworldspacewidget.hpp | 3 +++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index e8a38321f..9602d9f0c 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -190,6 +190,18 @@ stop: free(buffer); buffer = 0; } +void CSVRender::PagedWorldspaceWidget::displayCellCoord(bool display) +{ + mDisplayCellCoord = display; + std::map::iterator iter(mCells.begin()); + + while (iter != mCells.end()) + { + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->setVisible(display); + iter++; + } +} + bool CSVRender::PagedWorldspaceWidget::adjustCells() { bool modified = false; @@ -210,6 +222,12 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { delete iter->second; mCells.erase (iter++); + + getSceneManager()->getSceneNode("CellBillboardNode" + iter->first.getId(mWorldspace))->detachAllObjects(); + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->removeBillboard( + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->getBillboard(0)); + getSceneManager()->destroyBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace)); + modified = true; } else @@ -256,8 +274,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { font = Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).getPointer(); } - - //std:: Ogre::TexturePtr texture; if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) @@ -294,6 +310,8 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top billboardNode->attachObject(mySet); + mySet->setVisible(mDisplayCellCoord); + modified = true; } } @@ -365,7 +383,7 @@ void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent } CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) -: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default") +: WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mDisplayCellCoord(true) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index c4fb789ee..e0c1c6f54 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -18,6 +18,7 @@ namespace CSVRender CSMWorld::CellSelection mSelection; std::map mCells; std::string mWorldspace; + bool mDisplayCellCoord; private: @@ -54,6 +55,8 @@ namespace CSVRender void setCellSelection (const CSMWorld::CellSelection& selection); + void displayCellCoord(bool display); + virtual void handleDrop(const std::vector& data); virtual dropRequirments getDropRequirements(dropType type) const; From 2092e5fe228ca917685a36fe35668d94b1be6437 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 22 Jul 2014 11:49:45 +0200 Subject: [PATCH 03/63] compile fixes --- apps/opencs/model/doc/document.cpp | 1 + apps/openmw/mwmechanics/levelledlist.hpp | 2 ++ apps/openmw/mwrender/animation.cpp | 2 ++ apps/openmw/mwrender/occlusionquery.cpp | 2 ++ apps/openmw/mwrender/renderingmanager.cpp | 1 + apps/openmw/mwstate/statemanagerimp.cpp | 2 ++ apps/openmw/mwworld/containerstore.cpp | 1 + components/bsa/bsa_archive.cpp | 2 +- components/nif/niffile.hpp | 1 + extern/sdl4ogre/sdlinputwrapper.cpp | 1 + extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp | 2 ++ libs/openengine/bullet/physic.hpp | 1 + 12 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 23a47b313..6dc361c1e 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,6 +1,7 @@ #include "document.hpp" #include +#include #include diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index 5d9e29118..ad0677067 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -8,6 +8,8 @@ #include "../mwbase/environment.hpp" #include "../mwmechanics/creaturestats.hpp" +#include + namespace MWMechanics { diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 872740d74..f1fcce5f7 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1,5 +1,7 @@ #include "animation.hpp" +#include + #include #include #include diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 92a49acc0..c228a0160 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -1,5 +1,7 @@ #include "occlusionquery.hpp" +#include + #include #include #include diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 23edb3a7f..157265c96 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1,6 +1,7 @@ #include "renderingmanager.hpp" #include +#include #include #include diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index a3604cc66..cf4f05a4c 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -1,6 +1,8 @@ #include "statemanagerimp.hpp" +#include + #include #include #include diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index e330ddaee..7c7470bd1 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -1,6 +1,7 @@ #include "containerstore.hpp" +#include #include #include #include diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 6574f096b..4cd754f2b 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -45,7 +45,7 @@ static char strict_normalize_char(char ch) static char nonstrict_normalize_char(char ch) { - return ch == '\\' ? '/' : std::tolower(ch); + return ch == '\\' ? '/' : std::tolower(ch,std::locale()); } template diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index d70124263..87e46b234 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index f65dfb376..0f2008e99 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -4,6 +4,7 @@ #include #include +#include namespace SFO { diff --git a/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp b/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp index e71854019..8b819f6ef 100644 --- a/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp +++ b/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp @@ -8,6 +8,8 @@ #include #include +#include + namespace sh { OgreGpuProgram::OgreGpuProgram( diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index e37caee38..a806c2f3b 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -8,6 +8,7 @@ #include #include "BulletShapeLoader.h" #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" +#include From 1e7c4f26df4d2b61c29181dc8b1b066b60431ecc Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 22 Jul 2014 12:01:21 +0200 Subject: [PATCH 04/63] more compile fixes (damn you Visual studio) --- apps/openmw/mwrender/terraingrid.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/terraingrid.cpp b/apps/openmw/mwrender/terraingrid.cpp index f2bd92061..02899e0c5 100644 --- a/apps/openmw/mwrender/terraingrid.cpp +++ b/apps/openmw/mwrender/terraingrid.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" From 546b44a3be33a81174d77342d08fe07b04511970 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 22 Jul 2014 12:10:58 +0200 Subject: [PATCH 05/63] bugfixes --- apps/opencs/editor.cpp | 3 +++ apps/opencs/view/render/pagedworldspacewidget.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index b3513a7f1..f36c28e44 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -297,6 +298,8 @@ std::auto_ptr CS::Editor::setupGraphics() sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8"); + Ogre::FontManager* fontManager = new Ogre::FontManager(); + /// \todo add more configurable shiny settings return factory; diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 9602d9f0c..76be80c02 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -262,7 +262,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); Ogre::Font* font; - if (Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).isNull()) + if (!Ogre::FontManager::getSingletonPtr()->resourceExists("CellBillboardFont" + iter->getId(mWorldspace))) { font = Ogre::FontManager::getSingletonPtr()->create("CellBillboardFont" + iter->getId(mWorldspace), "Data00000001").getPointer(); font->setType(Ogre::FT_TRUETYPE); From 195767db7f4baa027ef4514bc6ed1d6ba3165499 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 22 Jul 2014 12:25:31 +0200 Subject: [PATCH 06/63] link back to OGre Wiki for some copied past code --- apps/opencs/view/render/pagedworldspacewidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 76be80c02..cce7a02c2 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -19,6 +19,7 @@ #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" +//all credits to http://www.ogre3d.org/tikiwiki/tiki-index.php?page=HowTo:+Write+text+on+texture void WriteToTexture(const Ogre::String &str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font* font, const Ogre::ColourValue &color, char justify = 'l', bool wordwrap = true) { using namespace Ogre; From baf6cca0519f2ad17464f4887c568c5fff937cf8 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 22 Jul 2014 13:32:15 +0200 Subject: [PATCH 07/63] modified tab to space --- .../view/render/pagedworldspacewidget.cpp | 384 +++++++++--------- .../view/render/pagedworldspacewidget.hpp | 6 +- 2 files changed, 195 insertions(+), 195 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index cce7a02c2..ac10cc908 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -22,185 +22,185 @@ //all credits to http://www.ogre3d.org/tikiwiki/tiki-index.php?page=HowTo:+Write+text+on+texture void WriteToTexture(const Ogre::String &str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font* font, const Ogre::ColourValue &color, char justify = 'l', bool wordwrap = true) { - using namespace Ogre; + using namespace Ogre; - if (destTexture->getHeight() < destRectangle.bottom) - destRectangle.bottom = destTexture->getHeight(); - if (destTexture->getWidth() < destRectangle.right) - destRectangle.right = destTexture->getWidth(); + if (destTexture->getHeight() < destRectangle.bottom) + destRectangle.bottom = destTexture->getHeight(); + if (destTexture->getWidth() < destRectangle.right) + destRectangle.right = destTexture->getWidth(); - if (!font->isLoaded()) - font->load(); + if (!font->isLoaded()) + font->load(); - TexturePtr fontTexture = (TexturePtr)TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()); + TexturePtr fontTexture = (TexturePtr)TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()); - HardwarePixelBufferSharedPtr fontBuffer = fontTexture->getBuffer(); - HardwarePixelBufferSharedPtr destBuffer = destTexture->getBuffer(); + HardwarePixelBufferSharedPtr fontBuffer = fontTexture->getBuffer(); + HardwarePixelBufferSharedPtr destBuffer = destTexture->getBuffer(); - PixelBox destPb = destBuffer->lock(destRectangle, HardwareBuffer::HBL_NORMAL); + PixelBox destPb = destBuffer->lock(destRectangle, HardwareBuffer::HBL_NORMAL); - // The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?) + // The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?) - // create a buffer - size_t nBuffSize = fontBuffer->getSizeInBytes(); - uint8* buffer = (uint8*)calloc(nBuffSize, sizeof(uint8)); + // create a buffer + size_t nBuffSize = fontBuffer->getSizeInBytes(); + uint8* buffer = (uint8*)calloc(nBuffSize, sizeof(uint8)); - // create pixel box using the copy of the buffer - PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(), fontBuffer->getDepth(), fontBuffer->getFormat(), buffer); - fontBuffer->blitToMemory(fontPb); + // create pixel box using the copy of the buffer + PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(), fontBuffer->getDepth(), fontBuffer->getFormat(), buffer); + fontBuffer->blitToMemory(fontPb); - uint8* fontData = static_cast(fontPb.data); - uint8* destData = static_cast(destPb.data); + uint8* fontData = static_cast(fontPb.data); + uint8* destData = static_cast(destPb.data); - const size_t fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format); - const size_t destPixelSize = PixelUtil::getNumElemBytes(destPb.format); + const size_t fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format); + const size_t destPixelSize = PixelUtil::getNumElemBytes(destPb.format); - const size_t fontRowPitchBytes = fontPb.rowPitch * fontPixelSize; - const size_t destRowPitchBytes = destPb.rowPitch * destPixelSize; + const size_t fontRowPitchBytes = fontPb.rowPitch * fontPixelSize; + const size_t destRowPitchBytes = destPb.rowPitch * destPixelSize; - Box *GlyphTexCoords; - GlyphTexCoords = new Box[str.size()]; + Box *GlyphTexCoords; + GlyphTexCoords = new Box[str.size()]; - Font::UVRect glypheTexRect; - size_t charheight = 0; - size_t charwidth = 0; + Font::UVRect glypheTexRect; + size_t charheight = 0; + size_t charwidth = 0; - for (unsigned int i = 0; i < str.size(); i++) - { - if ((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' ')) - { - glypheTexRect = font->getGlyphTexCoords(str[i]); - GlyphTexCoords[i].left = glypheTexRect.left * fontTexture->getSrcWidth(); - GlyphTexCoords[i].top = glypheTexRect.top * fontTexture->getSrcHeight(); - GlyphTexCoords[i].right = glypheTexRect.right * fontTexture->getSrcWidth(); - GlyphTexCoords[i].bottom = glypheTexRect.bottom * fontTexture->getSrcHeight(); + for (unsigned int i = 0; i < str.size(); i++) + { + if ((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' ')) + { + glypheTexRect = font->getGlyphTexCoords(str[i]); + GlyphTexCoords[i].left = glypheTexRect.left * fontTexture->getSrcWidth(); + GlyphTexCoords[i].top = glypheTexRect.top * fontTexture->getSrcHeight(); + GlyphTexCoords[i].right = glypheTexRect.right * fontTexture->getSrcWidth(); + GlyphTexCoords[i].bottom = glypheTexRect.bottom * fontTexture->getSrcHeight(); - if (GlyphTexCoords[i].getHeight() > charheight) - charheight = GlyphTexCoords[i].getHeight(); - if (GlyphTexCoords[i].getWidth() > charwidth) - charwidth = GlyphTexCoords[i].getWidth(); - } + if (GlyphTexCoords[i].getHeight() > charheight) + charheight = GlyphTexCoords[i].getHeight(); + if (GlyphTexCoords[i].getWidth() > charwidth) + charwidth = GlyphTexCoords[i].getWidth(); + } - } + } - size_t cursorX = 0; - size_t cursorY = 0; - size_t lineend = destRectangle.getWidth(); - bool carriagreturn = true; - for (unsigned int strindex = 0; strindex < str.size(); strindex++) - { - switch (str[strindex]) - { - case ' ': cursorX += charwidth; break; - case '\t':cursorX += charwidth * 3; break; - case '\n':cursorY += charheight; carriagreturn = true; break; - default: - { - //wrapping - if ((cursorX + GlyphTexCoords[strindex].getWidth()> lineend) && !carriagreturn) - { - cursorY += charheight; - carriagreturn = true; - } + size_t cursorX = 0; + size_t cursorY = 0; + size_t lineend = destRectangle.getWidth(); + bool carriagreturn = true; + for (unsigned int strindex = 0; strindex < str.size(); strindex++) + { + switch (str[strindex]) + { + case ' ': cursorX += charwidth; break; + case '\t':cursorX += charwidth * 3; break; + case '\n':cursorY += charheight; carriagreturn = true; break; + default: + { + //wrapping + if ((cursorX + GlyphTexCoords[strindex].getWidth()> lineend) && !carriagreturn) + { + cursorY += charheight; + carriagreturn = true; + } - //justify - if (carriagreturn) - { - size_t l = strindex; - size_t textwidth = 0; - size_t wordwidth = 0; + //justify + if (carriagreturn) + { + size_t l = strindex; + size_t textwidth = 0; + size_t wordwidth = 0; - while ((l < str.size()) && (str[l] != '\n)')) - { - wordwidth = 0; + while ((l < str.size()) && (str[l] != '\n)')) + { + wordwidth = 0; - switch (str[l]) - { - case ' ': wordwidth = charwidth; ++l; break; - case '\t': wordwidth = charwidth * 3; ++l; break; - case '\n': l = str.size(); - } + switch (str[l]) + { + case ' ': wordwidth = charwidth; ++l; break; + case '\t': wordwidth = charwidth * 3; ++l; break; + case '\n': l = str.size(); + } - if (wordwrap) - while ((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) - { - wordwidth += GlyphTexCoords[l].getWidth(); - ++l; - } - else - { - wordwidth += GlyphTexCoords[l].getWidth(); - l++; - } + if (wordwrap) + while ((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) + { + wordwidth += GlyphTexCoords[l].getWidth(); + ++l; + } + else + { + wordwidth += GlyphTexCoords[l].getWidth(); + l++; + } - if ((textwidth + wordwidth) <= destRectangle.getWidth()) - textwidth += (wordwidth); - else - break; - } + if ((textwidth + wordwidth) <= destRectangle.getWidth()) + textwidth += (wordwidth); + else + break; + } - if ((textwidth == 0) && (wordwidth > destRectangle.getWidth())) - textwidth = destRectangle.getWidth(); + if ((textwidth == 0) && (wordwidth > destRectangle.getWidth())) + textwidth = destRectangle.getWidth(); - switch (justify) - { - case 'c': cursorX = (destRectangle.getWidth() - textwidth) / 2; - lineend = destRectangle.getWidth() - cursorX; - break; + switch (justify) + { + case 'c': cursorX = (destRectangle.getWidth() - textwidth) / 2; + lineend = destRectangle.getWidth() - cursorX; + break; - case 'r': cursorX = (destRectangle.getWidth() - textwidth); - lineend = destRectangle.getWidth(); - break; + case 'r': cursorX = (destRectangle.getWidth() - textwidth); + lineend = destRectangle.getWidth(); + break; - default: cursorX = 0; - lineend = textwidth; - break; - } + default: cursorX = 0; + lineend = textwidth; + break; + } - carriagreturn = false; - } + carriagreturn = false; + } - //abort - net enough space to draw - if ((cursorY + charheight) > destRectangle.getHeight()) - goto stop; + //abort - net enough space to draw + if ((cursorY + charheight) > destRectangle.getHeight()) + goto stop; - //draw pixel by pixel - for (size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++) - for (size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++) - { - float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0); - float invalpha = 1.0 - alpha; - size_t offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize; - ColourValue pix; - PixelUtil::unpackColour(&pix, destPb.format, &destData[offset]); - pix = (pix * invalpha) + (color * alpha); - PixelUtil::packColour(pix, destPb.format, &destData[offset]); - } + //draw pixel by pixel + for (size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++) + for (size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++) + { + float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0); + float invalpha = 1.0 - alpha; + size_t offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize; + ColourValue pix; + PixelUtil::unpackColour(&pix, destPb.format, &destData[offset]); + pix = (pix * invalpha) + (color * alpha); + PixelUtil::packColour(pix, destPb.format, &destData[offset]); + } - cursorX += GlyphTexCoords[strindex].getWidth(); - }//default - }//switch - }//for + cursorX += GlyphTexCoords[strindex].getWidth(); + }//default + }//switch + }//for stop: - delete[] GlyphTexCoords; + delete[] GlyphTexCoords; - destBuffer->unlock(); + destBuffer->unlock(); - // Free the memory allocated for the buffer - free(buffer); buffer = 0; + // Free the memory allocated for the buffer + free(buffer); buffer = 0; } void CSVRender::PagedWorldspaceWidget::displayCellCoord(bool display) { - mDisplayCellCoord = display; - std::map::iterator iter(mCells.begin()); + mDisplayCellCoord = display; + std::map::iterator iter(mCells.begin()); - while (iter != mCells.end()) - { - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->setVisible(display); - iter++; - } + while (iter != mCells.end()) + { + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->setVisible(display); + iter++; + } } bool CSVRender::PagedWorldspaceWidget::adjustCells() @@ -224,10 +224,10 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() delete iter->second; mCells.erase (iter++); - getSceneManager()->getSceneNode("CellBillboardNode" + iter->first.getId(mWorldspace))->detachAllObjects(); - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->removeBillboard( - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->getBillboard(0)); - getSceneManager()->destroyBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace)); + getSceneManager()->getSceneNode("CellBillboardNode" + iter->first.getId(mWorldspace))->detachAllObjects(); + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->removeBillboard( + getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->getBillboard(0)); + getSceneManager()->destroyBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace)); modified = true; } @@ -258,60 +258,60 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); - //billboard which indicate the Cell coord - Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); - billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); + //billboard which indicate the Cell coord + Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); + billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); - Ogre::Font* font; - if (!Ogre::FontManager::getSingletonPtr()->resourceExists("CellBillboardFont" + iter->getId(mWorldspace))) - { - font = Ogre::FontManager::getSingletonPtr()->create("CellBillboardFont" + iter->getId(mWorldspace), "Data00000001").getPointer(); - font->setType(Ogre::FT_TRUETYPE); - font->setSource("Comic.ttf"); - font->setTrueTypeSize(256); - font->load(); - } - else - { - font = Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).getPointer(); - } + Ogre::Font* font; + if (!Ogre::FontManager::getSingletonPtr()->resourceExists("CellBillboardFont" + iter->getId(mWorldspace))) + { + font = Ogre::FontManager::getSingletonPtr()->create("CellBillboardFont" + iter->getId(mWorldspace), "Data00000001").getPointer(); + font->setType(Ogre::FT_TRUETYPE); + font->setSource("Comic.ttf"); + font->setTrueTypeSize(256); + font->load(); + } + else + { + font = Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).getPointer(); + } - Ogre::TexturePtr texture; - if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) - { - texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); - } - else - { - texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), "Data00000001", Ogre::TEX_TYPE_2D, 1024, 512, Ogre::MIP_UNLIMITED, Ogre::PF_X8R8G8B8, Ogre::TU_STATIC | Ogre::TU_AUTOMIPMAP); - WriteToTexture(std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()), texture, Ogre::Image::Box(0, 100, 1024, 512), font, Ogre::ColourValue(1.0, 1.0, 1.0, 1.0), 'c'); - } + Ogre::TexturePtr texture; + if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) + { + texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); + } + else + { + texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), "Data00000001", Ogre::TEX_TYPE_2D, 1024, 512, Ogre::MIP_UNLIMITED, Ogre::PF_X8R8G8B8, Ogre::TU_STATIC | Ogre::TU_AUTOMIPMAP); + WriteToTexture(std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()), texture, Ogre::Image::Box(0, 100, 1024, 512), font, Ogre::ColourValue(1.0, 1.0, 1.0, 1.0), 'c'); + } - Ogre::MaterialPtr material; - if (Ogre::MaterialManager::getSingleton().resourceExists("CellBillboardMaterial" + iter->getId(mWorldspace))) - { - material = Ogre::MaterialManager::getSingleton().getByName("CellBillboardMaterial" + iter->getId(mWorldspace)); - } - else - { - material = Ogre::MaterialManager::getSingleton().create( - "CellBillboardMaterial" + iter->getId(mWorldspace), // name - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Ogre::MaterialPtr material; + if (Ogre::MaterialManager::getSingleton().resourceExists("CellBillboardMaterial" + iter->getId(mWorldspace))) + { + material = Ogre::MaterialManager::getSingleton().getByName("CellBillboardMaterial" + iter->getId(mWorldspace)); + } + else + { + material = Ogre::MaterialManager::getSingleton().create( + "CellBillboardMaterial" + iter->getId(mWorldspace), // name + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - material->getTechnique(0)->getPass(0)->createTextureUnitState("CellBillboardTexture" + iter->getId(mWorldspace)); - material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); - material->setDepthCheckEnabled(false); - material->setDepthWriteEnabled(false); - } + material->getTechnique(0)->getPass(0)->createTextureUnitState("CellBillboardTexture" + iter->getId(mWorldspace)); + material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); + material->setDepthCheckEnabled(false); + material->setDepthWriteEnabled(false); + } - Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); - Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); - mySet->setMaterial(material); - myBillboard->setDimensions(4000, 2000); - mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top - billboardNode->attachObject(mySet); + Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); + Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); + mySet->setMaterial(material); + myBillboard->setDimensions(4000, 2000); + mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top + billboardNode->attachObject(mySet); - mySet->setVisible(mDisplayCellCoord); + mySet->setVisible(mDisplayCellCoord); modified = true; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index e0c1c6f54..8350ded1e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -18,7 +18,7 @@ namespace CSVRender CSMWorld::CellSelection mSelection; std::map mCells; std::string mWorldspace; - bool mDisplayCellCoord; + bool mDisplayCellCoord; private: @@ -53,9 +53,9 @@ namespace CSVRender void useViewHint (const std::string& hint); - void setCellSelection (const CSMWorld::CellSelection& selection); + void setCellSelection(const CSMWorld::CellSelection& selection); - void displayCellCoord(bool display); + void displayCellCoord(bool display); virtual void handleDrop(const std::vector& data); From 5fd599b5de0cbe2eb15e39da66a52c591693e05e Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 13:31:20 +0200 Subject: [PATCH 08/63] minor corrections --- apps/opencs/editor.cpp | 2 -- components/bsa/bsa_archive.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index f36c28e44..0fcac2474 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -298,8 +298,6 @@ std::auto_ptr CS::Editor::setupGraphics() sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8"); - Ogre::FontManager* fontManager = new Ogre::FontManager(); - /// \todo add more configurable shiny settings return factory; diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 4cd754f2b..4f656f9c4 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -45,7 +45,7 @@ static char strict_normalize_char(char ch) static char nonstrict_normalize_char(char ch) { - return ch == '\\' ? '/' : std::tolower(ch,std::locale()); + return ch == '\\' ? '/' : std::tolower(ch,std::locale::classic()); } template From e9cc1df69eeb862035f381fa9640eae52e874adc Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 13:31:32 +0200 Subject: [PATCH 09/63] use QPainter --- .../view/render/pagedworldspacewidget.cpp | 241 ++++-------------- 1 file changed, 50 insertions(+), 191 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index ac10cc908..9f9787352 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -2,6 +2,7 @@ #include "pagedworldspacewidget.hpp" #include +#include #include #include @@ -9,188 +10,16 @@ #include #include #include -#include #include #include #include #include +#include #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" -//all credits to http://www.ogre3d.org/tikiwiki/tiki-index.php?page=HowTo:+Write+text+on+texture -void WriteToTexture(const Ogre::String &str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font* font, const Ogre::ColourValue &color, char justify = 'l', bool wordwrap = true) -{ - using namespace Ogre; - - if (destTexture->getHeight() < destRectangle.bottom) - destRectangle.bottom = destTexture->getHeight(); - if (destTexture->getWidth() < destRectangle.right) - destRectangle.right = destTexture->getWidth(); - - if (!font->isLoaded()) - font->load(); - - TexturePtr fontTexture = (TexturePtr)TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()); - - HardwarePixelBufferSharedPtr fontBuffer = fontTexture->getBuffer(); - HardwarePixelBufferSharedPtr destBuffer = destTexture->getBuffer(); - - PixelBox destPb = destBuffer->lock(destRectangle, HardwareBuffer::HBL_NORMAL); - - // The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?) - - // create a buffer - size_t nBuffSize = fontBuffer->getSizeInBytes(); - uint8* buffer = (uint8*)calloc(nBuffSize, sizeof(uint8)); - - // create pixel box using the copy of the buffer - PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(), fontBuffer->getDepth(), fontBuffer->getFormat(), buffer); - fontBuffer->blitToMemory(fontPb); - - uint8* fontData = static_cast(fontPb.data); - uint8* destData = static_cast(destPb.data); - - const size_t fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format); - const size_t destPixelSize = PixelUtil::getNumElemBytes(destPb.format); - - const size_t fontRowPitchBytes = fontPb.rowPitch * fontPixelSize; - const size_t destRowPitchBytes = destPb.rowPitch * destPixelSize; - - Box *GlyphTexCoords; - GlyphTexCoords = new Box[str.size()]; - - Font::UVRect glypheTexRect; - size_t charheight = 0; - size_t charwidth = 0; - - for (unsigned int i = 0; i < str.size(); i++) - { - if ((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' ')) - { - glypheTexRect = font->getGlyphTexCoords(str[i]); - GlyphTexCoords[i].left = glypheTexRect.left * fontTexture->getSrcWidth(); - GlyphTexCoords[i].top = glypheTexRect.top * fontTexture->getSrcHeight(); - GlyphTexCoords[i].right = glypheTexRect.right * fontTexture->getSrcWidth(); - GlyphTexCoords[i].bottom = glypheTexRect.bottom * fontTexture->getSrcHeight(); - - if (GlyphTexCoords[i].getHeight() > charheight) - charheight = GlyphTexCoords[i].getHeight(); - if (GlyphTexCoords[i].getWidth() > charwidth) - charwidth = GlyphTexCoords[i].getWidth(); - } - - } - - size_t cursorX = 0; - size_t cursorY = 0; - size_t lineend = destRectangle.getWidth(); - bool carriagreturn = true; - for (unsigned int strindex = 0; strindex < str.size(); strindex++) - { - switch (str[strindex]) - { - case ' ': cursorX += charwidth; break; - case '\t':cursorX += charwidth * 3; break; - case '\n':cursorY += charheight; carriagreturn = true; break; - default: - { - //wrapping - if ((cursorX + GlyphTexCoords[strindex].getWidth()> lineend) && !carriagreturn) - { - cursorY += charheight; - carriagreturn = true; - } - - //justify - if (carriagreturn) - { - size_t l = strindex; - size_t textwidth = 0; - size_t wordwidth = 0; - - while ((l < str.size()) && (str[l] != '\n)')) - { - wordwidth = 0; - - switch (str[l]) - { - case ' ': wordwidth = charwidth; ++l; break; - case '\t': wordwidth = charwidth * 3; ++l; break; - case '\n': l = str.size(); - } - - if (wordwrap) - while ((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) - { - wordwidth += GlyphTexCoords[l].getWidth(); - ++l; - } - else - { - wordwidth += GlyphTexCoords[l].getWidth(); - l++; - } - - if ((textwidth + wordwidth) <= destRectangle.getWidth()) - textwidth += (wordwidth); - else - break; - } - - if ((textwidth == 0) && (wordwidth > destRectangle.getWidth())) - textwidth = destRectangle.getWidth(); - - switch (justify) - { - case 'c': cursorX = (destRectangle.getWidth() - textwidth) / 2; - lineend = destRectangle.getWidth() - cursorX; - break; - - case 'r': cursorX = (destRectangle.getWidth() - textwidth); - lineend = destRectangle.getWidth(); - break; - - default: cursorX = 0; - lineend = textwidth; - break; - } - - carriagreturn = false; - } - - //abort - net enough space to draw - if ((cursorY + charheight) > destRectangle.getHeight()) - goto stop; - - //draw pixel by pixel - for (size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++) - for (size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++) - { - float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0); - float invalpha = 1.0 - alpha; - size_t offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize; - ColourValue pix; - PixelUtil::unpackColour(&pix, destPb.format, &destData[offset]); - pix = (pix * invalpha) + (color * alpha); - PixelUtil::packColour(pix, destPb.format, &destData[offset]); - } - - cursorX += GlyphTexCoords[strindex].getWidth(); - }//default - }//switch - }//for - -stop: - delete[] GlyphTexCoords; - - destBuffer->unlock(); - - // Free the memory allocated for the buffer - free(buffer); buffer = 0; -} - void CSVRender::PagedWorldspaceWidget::displayCellCoord(bool display) { mDisplayCellCoord = display; @@ -225,8 +54,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mCells.erase (iter++); getSceneManager()->getSceneNode("CellBillboardNode" + iter->first.getId(mWorldspace))->detachAllObjects(); - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->removeBillboard( - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->getBillboard(0)); + getSceneManager()->destroySceneNode("CellBillboardNode" + iter->first.getId(mWorldspace)); getSceneManager()->destroyBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace)); modified = true; @@ -262,19 +90,17 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); - Ogre::Font* font; - if (!Ogre::FontManager::getSingletonPtr()->resourceExists("CellBillboardFont" + iter->getId(mWorldspace))) - { - font = Ogre::FontManager::getSingletonPtr()->create("CellBillboardFont" + iter->getId(mWorldspace), "Data00000001").getPointer(); - font->setType(Ogre::FT_TRUETYPE); - font->setSource("Comic.ttf"); - font->setTrueTypeSize(256); - font->load(); - } - else - { - font = Ogre::FontManager::getSingletonPtr()->getByName("CellBillboardFont" + iter->getId(mWorldspace)).getPointer(); - } + QImage image(QSize(1024, 512), QImage::Format::Format_RGB888); + QPainter painter(&image); + std::string text = std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()); + QFont font = painter.font(); + font.setPointSize(18); + painter.setFont(font); + painter.setBrush(Qt::blue); + painter.setPen(Qt::SolidLine); + painter.setPen(Qt::red); + painter.drawText(QPoint(100, 100), QString(text.c_str())); + painter.save(); Ogre::TexturePtr texture; if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) @@ -283,8 +109,41 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } else { - texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), "Data00000001", Ogre::TEX_TYPE_2D, 1024, 512, Ogre::MIP_UNLIMITED, Ogre::PF_X8R8G8B8, Ogre::TU_STATIC | Ogre::TU_AUTOMIPMAP); - WriteToTexture(std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()), texture, Ogre::Image::Box(0, 100, 1024, 512), font, Ogre::ColourValue(1.0, 1.0, 1.0, 1.0), 'c'); + texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, 1024, 512, 1, Ogre::PF_X8B8G8R8, Ogre::TU_DEFAULT); + Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); + pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); + const Ogre::PixelBox& pixBox = pixelBuffer->getCurrentLock(); + + Ogre::uint8* pDest = static_cast(pixBox.data); + for (size_t i = 0, width = texture->getWidth(); i < width; ++i) + { + for (size_t j = 0, height = texture->getHeight(); j < height; ++j) + { + QRgb color = image.pixel(QPoint(i,j)); + *pDest++ = qBlue(color); + *pDest++ = qGreen(color); + *pDest++ = qRed(color); + *pDest++ = 0; + } + } + pixelBuffer->unlock(); + texture->load(); + /*Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer(); + buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); + const Ogre::PixelBox &pb = buffer->getCurrentLock(); + + /// Update the contents of pb here + /// Image data starts at pb.data and has format pb.format + /// Here we assume data.format is PF_X8R8G8B8 so we can address pixels as uint32. + uchar *data = static_cast(pb.data); + memcpy(data, img.bits(), buffer->getSizeInBytes()); + std::cout << buffer->getSizeInBytes() << std::endl << img.byteCount(); + + + /// Unlock the buffer again (frees it for use by the GPU) + buffer->unlock();*/ } Ogre::MaterialPtr material; @@ -307,7 +166,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); mySet->setMaterial(material); - myBillboard->setDimensions(4000, 2000); + myBillboard->setDimensions(1024, 512); mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top billboardNode->attachObject(mySet); From d4d8f07bf3ef698bdfe3d89b67ccc3fbdcf4d588 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 13:32:56 +0200 Subject: [PATCH 10/63] clean up --- apps/opencs/view/render/pagedworldspacewidget.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 9f9787352..87737b849 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -130,20 +130,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } pixelBuffer->unlock(); texture->load(); - /*Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer(); - buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); - const Ogre::PixelBox &pb = buffer->getCurrentLock(); - - /// Update the contents of pb here - /// Image data starts at pb.data and has format pb.format - /// Here we assume data.format is PF_X8R8G8B8 so we can address pixels as uint32. - uchar *data = static_cast(pb.data); - memcpy(data, img.bits(), buffer->getSizeInBytes()); - std::cout << buffer->getSizeInBytes() << std::endl << img.byteCount(); - - - /// Unlock the buffer again (frees it for use by the GPU) - buffer->unlock();*/ } Ogre::MaterialPtr material; From 321d385a5da268dc5ad4789ed2d3ce6e2c73c877 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 17:18:08 +0200 Subject: [PATCH 11/63] clean up --- .../view/render/pagedworldspacewidget.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 87737b849..06fb212ff 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -90,17 +90,15 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); - QImage image(QSize(1024, 512), QImage::Format::Format_RGB888); + QImage image(QSize(1024, 1024), QImage::Format::Format_RGB888); QPainter painter(&image); std::string text = std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()); QFont font = painter.font(); - font.setPointSize(18); + font.setPointSize(256); painter.setFont(font); - painter.setBrush(Qt::blue); painter.setPen(Qt::SolidLine); - painter.setPen(Qt::red); - painter.drawText(QPoint(100, 100), QString(text.c_str())); - painter.save(); + painter.setPen(Qt::white); + painter.drawText(QRect(0, 0, 1024, 1024), Qt::AlignCenter, QString(text.c_str())); Ogre::TexturePtr texture; if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) @@ -111,17 +109,19 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, 1024, 512, 1, Ogre::PF_X8B8G8R8, Ogre::TU_DEFAULT); + Ogre::TEX_TYPE_2D, 1024, 1024, 1, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixBox = pixelBuffer->getCurrentLock(); + std::cout << texture->getWidth() << texture->getHeight(); + Ogre::uint8* pDest = static_cast(pixBox.data); for (size_t i = 0, width = texture->getWidth(); i < width; ++i) { for (size_t j = 0, height = texture->getHeight(); j < height; ++j) { - QRgb color = image.pixel(QPoint(i,j)); + QRgb color = image.pixel(QPoint(j,i)); *pDest++ = qBlue(color); *pDest++ = qGreen(color); *pDest++ = qRed(color); @@ -151,8 +151,8 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); + mySet->setDefaultDimensions(4000, 2000); mySet->setMaterial(material); - myBillboard->setDimensions(1024, 512); mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top billboardNode->attachObject(mySet); From 465914c77c1dad61f08d5e6e3df1b75b56518fd9 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 17:20:02 +0200 Subject: [PATCH 12/63] more clean up --- apps/opencs/view/render/pagedworldspacewidget.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 06fb212ff..078a8dfe2 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -2,7 +2,6 @@ #include "pagedworldspacewidget.hpp" #include -#include #include #include @@ -114,8 +113,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixBox = pixelBuffer->getCurrentLock(); - std::cout << texture->getWidth() << texture->getHeight(); - Ogre::uint8* pDest = static_cast(pixBox.data); for (size_t i = 0, width = texture->getWidth(); i < width; ++i) { From 11922dc53a1cb68aa365004fb7496ba3de8be784 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 17:41:13 +0200 Subject: [PATCH 13/63] code is shorter, thanks scrawl --- .../view/render/pagedworldspacewidget.cpp | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 078a8dfe2..d9367b2fe 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -109,23 +109,11 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 1024, 1024, 1, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); - Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); - pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); - const Ogre::PixelBox& pixBox = pixelBuffer->getCurrentLock(); - Ogre::uint8* pDest = static_cast(pixBox.data); - for (size_t i = 0, width = texture->getWidth(); i < width; ++i) - { - for (size_t j = 0, height = texture->getHeight(); j < height; ++j) - { - QRgb color = image.pixel(QPoint(j,i)); - *pDest++ = qBlue(color); - *pDest++ = qGreen(color); - *pDest++ = qRed(color); - *pDest++ = 0; - } - } - pixelBuffer->unlock(); + int w = 1024; + int h = 1024; + Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)image.constBits(), w*h*Ogre::PixelUtil::getNumElemBytes(Ogre::PixelFormat::PF_R8G8B8), false)); + texture->loadRawData(stream, w, h, Ogre::PixelFormat::PF_R8G8B8); texture->load(); } From 1ac220593d180d9d6f4561c05a99c1897b713e02 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 12 Aug 2014 21:32:07 +0200 Subject: [PATCH 14/63] clean up --- apps/opencs/editor.cpp | 1 - apps/opencs/view/render/pagedworldspacewidget.cpp | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 0fcac2474..b3513a7f1 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -13,7 +13,6 @@ #include #include -#include #include diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d9367b2fe..9862c1210 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -99,16 +99,13 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() painter.setPen(Qt::white); painter.drawText(QRect(0, 0, 1024, 1024), Qt::AlignCenter, QString(text.c_str())); - Ogre::TexturePtr texture; - if (Ogre::TextureManager::getSingleton().resourceExists("CellBillboardTexture" + iter->getId(mWorldspace))) - { - texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); - } - else + + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); + if (texture.isNull()) { texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, 1024, 1024, 1, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); + Ogre::TEX_TYPE_2D, 1024, 1024, 5, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); int w = 1024; int h = 1024; From 687b62dfd3e6a20b6fc111f08478898dc7cfda20 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 30 Sep 2014 18:46:26 +1000 Subject: [PATCH 15/63] Revert some changes (mostly iostream adds) --- apps/opencs/model/doc/document.cpp | 1 - apps/opencs/view/render/pagedworldspacewidget.cpp | 4 ++-- apps/opencs/view/render/pagedworldspacewidget.hpp | 1 - apps/openmw/mwmechanics/levelledlist.hpp | 2 -- apps/openmw/mwrender/animation.cpp | 2 -- apps/openmw/mwrender/occlusionquery.cpp | 2 -- apps/openmw/mwrender/renderingmanager.cpp | 1 - apps/openmw/mwstate/statemanagerimp.cpp | 2 -- apps/openmw/mwworld/containerstore.cpp | 1 - components/nif/niffile.hpp | 13 ------------- components/terrain/terraingrid.cpp | 1 - extern/sdl4ogre/sdlinputwrapper.cpp | 1 - extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp | 2 -- 13 files changed, 2 insertions(+), 31 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 040a4462d..9a174d9d5 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2,7 +2,6 @@ #include #include -#include #include diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 22af7cd86..b201f2110 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -107,7 +107,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); if (texture.isNull()) { - texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), + texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 1024, 1024, 5, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); @@ -396,4 +396,4 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int /// \todo check if no selected cell is affected and do not update, if that is the case if (adjustCells()) flagAsModified(); -} \ No newline at end of file +} diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 1b43510ff..304424453 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -60,7 +60,6 @@ namespace CSVRender void displayCellCoord(bool display); - /// \return Drop handled? virtual bool handleDrop (const std::vector& data, DropType type); diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index ad0677067..5d9e29118 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -8,8 +8,6 @@ #include "../mwbase/environment.hpp" #include "../mwmechanics/creaturestats.hpp" -#include - namespace MWMechanics { diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index bdc74f5e3..12ba3c2da 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1,7 +1,5 @@ #include "animation.hpp" -#include - #include #include #include diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index c228a0160..92a49acc0 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -1,7 +1,5 @@ #include "occlusionquery.hpp" -#include - #include #include #include diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 7b597f0c8..4512bbbeb 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1,7 +1,6 @@ #include "renderingmanager.hpp" #include -#include #include #include diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 2ec061fe7..18ebe11ce 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -1,8 +1,6 @@ #include "statemanagerimp.hpp" -#include - #include #include #include diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 8382311aa..085b079d9 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -1,7 +1,6 @@ #include "containerstore.hpp" -#include #include #include #include diff --git a/components/nif/niffile.hpp b/components/nif/niffile.hpp index f7cee6c40..108e455d7 100644 --- a/components/nif/niffile.hpp +++ b/components/nif/niffile.hpp @@ -5,21 +5,8 @@ #include #include -<<<<<<< HEAD -#include -#include #include -#include -#include -#include -#include - -#include -======= -#include ->>>>>>> master - #include "record.hpp" namespace Nif diff --git a/components/terrain/terraingrid.cpp b/components/terrain/terraingrid.cpp index 106f00e76..fe322a6bf 100644 --- a/components/terrain/terraingrid.cpp +++ b/components/terrain/terraingrid.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "chunk.hpp" diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index d0be46966..db46a4af9 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -4,7 +4,6 @@ #include #include -#include namespace SFO { diff --git a/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp b/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp index 8b819f6ef..e71854019 100644 --- a/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp +++ b/extern/shiny/Platforms/Ogre/OgreGpuProgram.cpp @@ -8,8 +8,6 @@ #include #include -#include - namespace sh { OgreGpuProgram::OgreGpuProgram( From dee090355f73afb2e1c9ef2c3d2dd829e22eecf2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 30 Sep 2014 19:23:19 +1000 Subject: [PATCH 16/63] Changes to compile on Ubuntu 14.04. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b201f2110..4c08bb750 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -93,9 +93,11 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); - QImage image(QSize(1024, 1024), QImage::Format::Format_RGB888); + QImage image(QSize(1024, 1024), QImage::Format_RGB888); QPainter painter(&image); - std::string text = std::to_string(iter->getX()) + ";" + std::to_string(iter->getY()); + std::stringstream ss; + ss << iter->getX() << ";" << iter->getY(); + std::string text = ss.str(); QFont font = painter.font(); font.setPointSize(256); painter.setFont(font); @@ -113,8 +115,8 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() int w = 1024; int h = 1024; - Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)image.constBits(), w*h*Ogre::PixelUtil::getNumElemBytes(Ogre::PixelFormat::PF_R8G8B8), false)); - texture->loadRawData(stream, w, h, Ogre::PixelFormat::PF_R8G8B8); + Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)image.constBits(), w*h*Ogre::PixelUtil::getNumElemBytes(Ogre::PF_R8G8B8), false)); + texture->loadRawData(stream, w, h, Ogre::PF_R8G8B8); texture->load(); } From a9745cce1e11877aba83beaaa82f41d2c5c8e78a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 30 Sep 2014 21:02:31 +1000 Subject: [PATCH 17/63] Suppress some compiler warnings. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 4c08bb750..a1b6e855e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -13,8 +13,8 @@ #include #include -#include -#include +#include +#include #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" @@ -138,7 +138,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); - Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); + //Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); mySet->setDefaultDimensions(4000, 2000); mySet->setMaterial(material); mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top From 5ffb740120893e82bd8ac4915f3f207b45e0c1df Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 1 Oct 2014 07:19:15 +1000 Subject: [PATCH 18/63] Fix silly mistake (thanks scrawl for picking that up) --- apps/opencs/view/render/pagedworldspacewidget.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index a1b6e855e..903a47886 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -138,7 +138,10 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); - //Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); + // FIXME: myBillboard is currently not used but will be required later + // for manipulating the billboard (e.g. mouse events). Ignore compiler + // warnings for now. + Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); mySet->setDefaultDimensions(4000, 2000); mySet->setMaterial(material); mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top From 3aea1bf5f951c6006792461a81f3429b24bd7583 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sat, 4 Oct 2014 05:48:56 +1000 Subject: [PATCH 19/63] CMake changes for using Ogre Overlay. --- apps/opencs/CMakeLists.txt | 1 + cmake/FindOGRE.cmake | 98 +++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 7094f8799..2869904cc 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -198,6 +198,7 @@ endif(APPLE) target_link_libraries(opencs ${OGRE_LIBRARIES} + ${OGRE_Overlay_LIBRARIES} ${OGRE_STATIC_PLUGINS} ${SHINY_LIBRARIES} ${Boost_LIBRARIES} diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 5608c528c..24a26ccc7 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -18,7 +18,7 @@ # Once done, this will define # # OGRE_FOUND - system has OGRE -# OGRE_INCLUDE_DIRS - the OGRE include directories +# OGRE_INCLUDE_DIRS - the OGRE include directories # OGRE_LIBRARIES - link these to use the OGRE core # OGRE_BINARY_REL - location of the main Ogre binary (win32 non-static only, release) # OGRE_BINARY_DBG - location of the main Ogre binaries (win32 non-static only, debug) @@ -35,7 +35,7 @@ # # OGRE_${COMPONENT}_FOUND - ${COMPONENT} is available # OGRE_${COMPONENT}_INCLUDE_DIRS - additional include directories for ${COMPONENT} -# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT} +# OGRE_${COMPONENT}_LIBRARIES - link these to use ${COMPONENT} # OGRE_${COMPONENT}_BINARY_REL - location of the component binary (win32 non-static only, release) # OGRE_${COMPONENT}_BINARY_DBG - location of the component binary (win32 non-static only, debug) # @@ -110,9 +110,9 @@ if (OGRE_PREFIX_SOURCE AND OGRE_PREFIX_BUILD) set(OGRE_INC_SEARCH_PATH ${dir}/include ${OGRE_INC_SEARCH_PATH}) set(OGRE_LIB_SEARCH_PATH ${dir}/lib ${OGRE_LIB_SEARCH_PATH}) set(OGRE_BIN_SEARCH_PATH ${dir}/bin ${OGRE_BIN_SEARCH_PATH}) - set(OGRE_BIN_SEARCH_PATH ${dir}/Samples/Common/bin ${OGRE_BIN_SEARCH_PATH}) + set(OGRE_BIN_SEARCH_PATH ${dir}/Samples/Common/bin ${OGRE_BIN_SEARCH_PATH}) endforeach(dir) - + if (OGRE_PREFIX_DEPENDENCIES_DIR) set(OGRE_INC_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/include ${OGRE_INC_SEARCH_PATH}) set(OGRE_LIB_SEARCH_PATH ${OGRE_PREFIX_DEPENDENCIES_DIR}/lib ${OGRE_LIB_SEARCH_PATH}) @@ -124,12 +124,12 @@ else() endif () # redo search if any of the environmental hints changed -set(OGRE_COMPONENTS Paging Terrain +set(OGRE_COMPONENTS Paging Terrain Overlay Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX RenderSystem_Direct3D10 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES2) -set(OGRE_RESET_VARS - OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR +set(OGRE_RESET_VARS + OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG OGRE_PLUGIN_DIR_DBG OGRE_PLUGIN_DIR_REL OGRE_MEDIA_DIR) foreach (comp ${OGRE_COMPONENTS}) @@ -148,7 +148,7 @@ if(NOT OGRE_BUILD_PLATFORM_IPHONE AND APPLE) # try to find framework on OSX findpkg_framework(OGRE) else() - set(OGRE_LIBRARY_FWK "") + set(OGRE_LIBRARY_FWK "") endif() # locate Ogre include files @@ -215,8 +215,8 @@ list(REMOVE_DUPLICATES OGRE_INCLUDE_DIR) findpkg_finish(OGRE) add_parent_dir(OGRE_INCLUDE_DIRS OGRE_INCLUDE_DIR) if (OGRE_SOURCE) - # If working from source rather than SDK, add samples include - set(OGRE_INCLUDE_DIRS ${OGRE_INCLUDE_DIRS} "${OGRE_SOURCE}/Samples/Common/include") + # If working from source rather than SDK, add samples include + set(OGRE_INCLUDE_DIRS ${OGRE_INCLUDE_DIRS} "${OGRE_SOURCE}/Samples/Common/include") endif() mark_as_advanced(OGRE_CONFIG_INCLUDE_DIR OGRE_MEDIA_DIR OGRE_PLUGIN_DIR_REL OGRE_PLUGIN_DIR_DBG) @@ -259,13 +259,13 @@ if (OGRE_STATIC) endif () if (ANDROID) - set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} - ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} + set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} + ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} ${Cocoa_LIBRARIES} ${Carbon_LIBRARIES}) else () - set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} - ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} - ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} + set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} + ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} + ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} ${Cocoa_LIBRARIES} ${Carbon_LIBRARIES}) endif() @@ -279,9 +279,9 @@ endif() set(OGRE_DEPS_FOUND FALSE) endif () if (UNIX AND NOT APPLE AND NOT ANDROID) - if (NOT X11_FOUND) + if (NOT X11_FOUND) set(OGRE_DEPS_FOUND FALSE) - endif () + endif () endif () if (OGRE_CONFIG_THREADS) @@ -311,7 +311,7 @@ endif() endif () endif () endif () - + if (NOT OGRE_DEPS_FOUND) pkg_message(OGRE "Could not find all required dependencies for the Ogre package.") set(OGRE_FOUND FALSE) @@ -329,13 +329,13 @@ set(OGRE_LIBRARY_DIRS ${OGRE_LIBRARY_DIR_REL} ${OGRE_LIBRARY_DIR_DBG}) # find binaries if (NOT OGRE_STATIC) - if (WIN32) - find_file(OGRE_BINARY_REL NAMES "OgreMain.dll" HINTS ${OGRE_BIN_SEARCH_PATH} + if (WIN32) + find_file(OGRE_BINARY_REL NAMES "OgreMain.dll" HINTS ${OGRE_BIN_SEARCH_PATH} PATH_SUFFIXES "" release relwithdebinfo minsizerel) - find_file(OGRE_BINARY_DBG NAMES "OgreMain_d.dll" HINTS ${OGRE_BIN_SEARCH_PATH} + find_file(OGRE_BINARY_DBG NAMES "OgreMain_d.dll" HINTS ${OGRE_BIN_SEARCH_PATH} PATH_SUFFIXES "" debug ) - endif() - mark_as_advanced(OGRE_BINARY_REL OGRE_BINARY_DBG) + endif() + mark_as_advanced(OGRE_BINARY_REL OGRE_BINARY_DBG) endif() @@ -343,7 +343,7 @@ endif() # Find Ogre components ######################################################### -set(OGRE_COMPONENT_SEARCH_PATH_REL +set(OGRE_COMPONENT_SEARCH_PATH_REL ${OGRE_LIBRARY_DIR_REL}/.. ${OGRE_LIBRARY_DIR_REL}/../.. ${OGRE_BIN_SEARCH_PATH} @@ -366,17 +366,19 @@ macro(ogre_find_component COMPONENT HEADER) if (OGRE_${COMPONENT}_FOUND) # find binaries if (NOT OGRE_STATIC) - if (WIN32) - find_file(OGRE_${COMPONENT}_BINARY_REL NAMES "Ogre${COMPONENT}.dll" HINTS ${OGRE_COMPONENT_SEARCH_PATH_REL} PATH_SUFFIXES "" bin bin/release bin/relwithdebinfo bin/minsizerel release) - find_file(OGRE_${COMPONENT}_BINARY_DBG NAMES "Ogre${COMPONENT}_d.dll" HINTS ${OGRE_COMPONENT_SEARCH_PATH_DBG} PATH_SUFFIXES "" bin bin/debug debug) - endif() - mark_as_advanced(OGRE_${COMPONENT}_BINARY_REL OGRE_${COMPONENT}_BINARY_DBG) + if (WIN32) + find_file(OGRE_${COMPONENT}_BINARY_REL NAMES "Ogre${COMPONENT}.dll" HINTS ${OGRE_COMPONENT_SEARCH_PATH_REL} PATH_SUFFIXES "" bin bin/release bin/relwithdebinfo bin/minsizerel release) + find_file(OGRE_${COMPONENT}_BINARY_DBG NAMES "Ogre${COMPONENT}_d.dll" HINTS ${OGRE_COMPONENT_SEARCH_PATH_DBG} PATH_SUFFIXES "" bin bin/debug debug) + endif() + mark_as_advanced(OGRE_${COMPONENT}_BINARY_REL OGRE_${COMPONENT}_BINARY_DBG) endif() endif() endmacro() # look for Paging component ogre_find_component(Paging OgrePaging.h) +# look for Overlay component +ogre_find_component(Overlay OgreOverlay.h) # look for Terrain component ogre_find_component(Terrain OgreTerrain.h) # look for Property component @@ -395,17 +397,17 @@ macro(ogre_find_plugin PLUGIN HEADER) set(TMP_CMAKE_LIB_PREFIX ${CMAKE_FIND_LIBRARY_PREFIXES}) set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "") endif() - + # strip RenderSystem_ or Plugin_ prefix from plugin name string(REPLACE "RenderSystem_" "" PLUGIN_TEMP ${PLUGIN}) string(REPLACE "Plugin_" "" PLUGIN_NAME ${PLUGIN_TEMP}) - + # header files for plugins are not usually needed, but find them anyway if they are present set(OGRE_PLUGIN_PATH_SUFFIXES - PlugIns PlugIns/${PLUGIN_NAME} Plugins Plugins/${PLUGIN_NAME} ${PLUGIN} + PlugIns PlugIns/${PLUGIN_NAME} Plugins Plugins/${PLUGIN_NAME} ${PLUGIN} RenderSystems RenderSystems/${PLUGIN_NAME} ${ARGN}) - find_path(OGRE_${PLUGIN}_INCLUDE_DIR NAMES ${HEADER} - HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE} + find_path(OGRE_${PLUGIN}_INCLUDE_DIR NAMES ${HEADER} + HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${OGRE_PLUGIN_PATH_SUFFIXES}) # find link libraries for plugins set(OGRE_${PLUGIN}_LIBRARY_NAMES "${PLUGIN}${OGRE_LIB_SUFFIX}") @@ -443,15 +445,15 @@ macro(ogre_find_plugin PLUGIN HEADER) if (OGRE_${PLUGIN}_FOUND) if (NOT OGRE_PLUGIN_DIR_REL OR NOT OGRE_PLUGIN_DIR_DBG) if (WIN32) - set(OGRE_PLUGIN_SEARCH_PATH_REL + set(OGRE_PLUGIN_SEARCH_PATH_REL ${OGRE_LIBRARY_DIR_REL}/.. ${OGRE_LIBRARY_DIR_REL}/../.. - ${OGRE_BIN_SEARCH_PATH} + ${OGRE_BIN_SEARCH_PATH} ) set(OGRE_PLUGIN_SEARCH_PATH_DBG ${OGRE_LIBRARY_DIR_DBG}/.. ${OGRE_LIBRARY_DIR_DBG}/../.. - ${OGRE_BIN_SEARCH_PATH} + ${OGRE_BIN_SEARCH_PATH} ) find_path(OGRE_PLUGIN_DIR_REL NAMES "${PLUGIN}.dll" HINTS ${OGRE_PLUGIN_SEARCH_PATH_REL} PATH_SUFFIXES "" bin bin/release bin/relwithdebinfo bin/minsizerel release) @@ -468,16 +470,16 @@ macro(ogre_find_plugin PLUGIN HEADER) set(OGRE_PLUGIN_DIR_DBG ${OGRE_PLUGIN_DIR_TMP}) endif () endif () - - # find binaries - if (NOT OGRE_STATIC) - if (WIN32) - find_file(OGRE_${PLUGIN}_REL NAMES "${PLUGIN}.dll" HINTS ${OGRE_PLUGIN_DIR_REL}) - find_file(OGRE_${PLUGIN}_DBG NAMES "${PLUGIN}_d.dll" HINTS ${OGRE_PLUGIN_DIR_DBG}) - endif() - mark_as_advanced(OGRE_${PLUGIN}_REL OGRE_${PLUGIN}_DBG) - endif() - + + # find binaries + if (NOT OGRE_STATIC) + if (WIN32) + find_file(OGRE_${PLUGIN}_REL NAMES "${PLUGIN}.dll" HINTS ${OGRE_PLUGIN_DIR_REL}) + find_file(OGRE_${PLUGIN}_DBG NAMES "${PLUGIN}_d.dll" HINTS ${OGRE_PLUGIN_DIR_DBG}) + endif() + mark_as_advanced(OGRE_${PLUGIN}_REL OGRE_${PLUGIN}_DBG) + endif() + endif () if (TMP_CMAKE_LIB_PREFIX) @@ -521,7 +523,7 @@ if (OGRE_STATIC) if (NOT Cg_FOUND) set(OGRE_Plugin_CgProgramManager_FOUND FALSE) endif () - + set(OGRE_RenderSystem_Direct3D9_LIBRARIES ${OGRE_RenderSystem_Direct3D9_LIBRARIES} ${DirectX9_LIBRARIES} ) From 85d93807c5bd909389c52483b9f1d70eefd7bc17 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 5 Oct 2014 19:25:37 +1100 Subject: [PATCH 20/63] Working version. White lines still present. Marker toggle hard-coded to 'm' key. Mouse events not implemented. --- apps/opencs/CMakeLists.txt | 2 +- .../view/render/pagedworldspacewidget.cpp | 158 +++++---- .../view/render/pagedworldspacewidget.hpp | 12 +- apps/opencs/view/render/scenewidget.cpp | 10 + apps/opencs/view/render/scenewidget.hpp | 2 + apps/opencs/view/render/textoverlay.cpp | 301 ++++++++++++++++++ apps/opencs/view/render/textoverlay.hpp | 54 ++++ apps/opencs/view/render/worldspacewidget.cpp | 3 + apps/opencs/view/render/worldspacewidget.hpp | 4 +- 9 files changed, 458 insertions(+), 88 deletions(-) create mode 100644 apps/opencs/view/render/textoverlay.cpp create mode 100644 apps/opencs/view/render/textoverlay.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 2869904cc..ff29a7da2 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -81,7 +81,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell + lightingbright object cell textoverlay ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 903a47886..200c1a9d7 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -4,17 +4,13 @@ #include #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include + +#include "../../../../components/esm/loadland.hpp" +#include "textoverlay.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" @@ -23,18 +19,6 @@ #include "elements.hpp" -void CSVRender::PagedWorldspaceWidget::displayCellCoord(bool display) -{ - mDisplayCellCoord = display; - std::map::iterator iter(mCells.begin()); - - while (iter != mCells.end()) - { - getSceneManager()->getBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace))->setVisible(display); - iter++; - } -} - bool CSVRender::PagedWorldspaceWidget::adjustCells() { bool modified = false; @@ -56,9 +40,14 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() delete iter->second; mCells.erase (iter++); - getSceneManager()->getSceneNode("CellBillboardNode" + iter->first.getId(mWorldspace))->detachAllObjects(); - getSceneManager()->destroySceneNode("CellBillboardNode" + iter->first.getId(mWorldspace)); - getSceneManager()->destroyBillboardSet("CellBillboardSet" + iter->first.getId(mWorldspace)); + // destroy manual objects and entities + std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); + if(it != mEntities.end()) + { + getSceneManager()->destroyEntity(it->second); + mEntities.erase(it); + } + getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); modified = true; } @@ -82,72 +71,37 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() if (setCamera) { setCamera = false; - getCamera()->setPosition (8192*iter->getX()+4096, 8192*iter->getY()+4096, 0); + getCamera()->setPosition (ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 0); } mCells.insert (std::make_pair (*iter, - new Cell (mDocument.getData(), getSceneManager(), - iter->getId (mWorldspace)))); + new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); - //billboard which indicate the Cell coord - Ogre::SceneNode* billboardNode = getSceneManager()->getRootSceneNode()->createChildSceneNode("CellBillboardNode" + iter->getId(mWorldspace)); - billboardNode->setPosition(8192 * iter->getX() + 4096, 8192 * iter->getY() + 4096, 0); + // FIXME: delete this later + Ogre::ManualObject* manual = getSceneManager()->createManualObject("manual" + iter->getId(mWorldspace)); - QImage image(QSize(1024, 1024), QImage::Format_RGB888); - QPainter painter(&image); - std::stringstream ss; - ss << iter->getX() << ";" << iter->getY(); - std::string text = ss.str(); - QFont font = painter.font(); - font.setPointSize(256); - painter.setFont(font); - painter.setPen(Qt::SolidLine); - painter.setPen(Qt::white); - painter.drawText(QRect(0, 0, 1024, 1024), Qt::AlignCenter, QString(text.c_str())); + manual->begin("BaseWhite", Ogre::RenderOperation::OT_LINE_LIST); + // define start and end point (x, y, z) + // FIXME: need terrain height to get the correct starting point + manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 0); + manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 2000); + manual->end(); + Ogre::MeshPtr meshPtr = manual->convertToMesh("vLine" + iter->getId(mWorldspace)); + Ogre::Entity* entity = getSceneManager()->createEntity(meshPtr); + getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(entity); + //entity->setVisible(false); - Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("CellBillboardTexture" + iter->getId(mWorldspace)); - if (texture.isNull()) - { - texture = Ogre::TextureManager::getSingleton().createManual("CellBillboardTexture" + iter->getId(mWorldspace), - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, 1024, 1024, 5, Ogre::PF_X8R8G8B8, Ogre::TU_DEFAULT); + mEntities.insert(std::make_pair(iter->getId(mWorldspace), entity)); - int w = 1024; - int h = 1024; - Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream((void*)image.constBits(), w*h*Ogre::PixelUtil::getNumElemBytes(Ogre::PF_R8G8B8), false)); - texture->loadRawData(stream, w, h, Ogre::PF_R8G8B8); - texture->load(); - } - - Ogre::MaterialPtr material; - if (Ogre::MaterialManager::getSingleton().resourceExists("CellBillboardMaterial" + iter->getId(mWorldspace))) - { - material = Ogre::MaterialManager::getSingleton().getByName("CellBillboardMaterial" + iter->getId(mWorldspace)); - } - else - { - material = Ogre::MaterialManager::getSingleton().create( - "CellBillboardMaterial" + iter->getId(mWorldspace), // name - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - material->getTechnique(0)->getPass(0)->createTextureUnitState("CellBillboardTexture" + iter->getId(mWorldspace)); - material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); - material->setDepthCheckEnabled(false); - material->setDepthWriteEnabled(false); - } - - Ogre::BillboardSet* mySet = getSceneManager()->createBillboardSet("CellBillboardSet" + iter->getId(mWorldspace)); - // FIXME: myBillboard is currently not used but will be required later - // for manipulating the billboard (e.g. mouse events). Ignore compiler - // warnings for now. - Ogre::Billboard* myBillboard = mySet->createBillboard(Ogre::Vector3(0, 0, 0)); - mySet->setDefaultDimensions(4000, 2000); - mySet->setMaterial(material); - mySet->setRenderQueueGroup(mySet->getRenderQueueGroup() + 1); // render the bilboard on top - billboardNode->attachObject(mySet); - - mySet->setVisible(mDisplayCellCoord); + CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); + textDisp->enable(true); + textDisp->setCaption(iter->getId(mWorldspace)); + textDisp->update(); + mTextOverlays.push_back(textDisp); modified = true; } @@ -156,6 +110,34 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() return modified; } +void CSVRender::PagedWorldspaceWidget::updateOverlay(bool toggleOverlay) +{ + if(!mTextOverlays.empty()) + { + std::list::iterator it = mTextOverlays.begin(); + for(; it != mTextOverlays.end(); ++it) + { + (*it)->update(toggleOverlay); + } + std::map::iterator iter (mCells.begin()); + +#if 0 + if(toggleOverlay) + { + while (iter!=mCells.end()) + { + std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); + if(it != mEntities.end()) + { + it->second->setVisible(!it->second->isVisible()); + } + ++iter; + } + } +#endif + } +} + void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { @@ -234,7 +216,7 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() } CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) -: WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mDisplayCellCoord(true) +: WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mTextOverlays(0) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); @@ -251,7 +233,17 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { for (std::map::iterator iter (mCells.begin()); iter!=mCells.end(); ++iter) + { delete iter->second; + + std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); + if(it != mEntities.end()) + { + getSceneManager()->destroyEntity(it->second); + mEntities.erase(it); + } + getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); + } } void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 304424453..1013319d1 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -10,6 +10,9 @@ namespace CSVRender { + + class TextOverlay; + class PagedWorldspaceWidget : public WorldspaceWidget { Q_OBJECT @@ -19,7 +22,8 @@ namespace CSVRender std::map mCells; std::string mWorldspace; CSVWidget::SceneToolToggle *mControlElements; - bool mDisplayCellCoord; + std::list mTextOverlays; + std::map mEntities; private: @@ -58,8 +62,6 @@ namespace CSVRender void setCellSelection(const CSMWorld::CellSelection& selection); - void displayCellCoord(bool display); - /// \return Drop handled? virtual bool handleDrop (const std::vector& data, DropType type); @@ -73,6 +75,10 @@ namespace CSVRender virtual unsigned int getElementMask() const; + protected: + + virtual void updateOverlay(bool toggleOverlay = false); + signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5ddb5e084..089f4a4f3 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" @@ -57,6 +58,9 @@ namespace CSVRender setLighting (&mLightingDay); + Ogre::OverlaySystem *mOverlaySystem = new Ogre::OverlaySystem(); // FIXME: delete + mSceneMgr->addRenderQueueListener(mOverlaySystem); + QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), this, SLOT (update())); @@ -283,6 +287,8 @@ namespace CSVRender break; + case Qt::Key_M: updateOverlay(true); + default: QWidget::keyReleaseEvent (event); } } @@ -377,9 +383,13 @@ namespace CSVRender { mUpdate = false; mWindow->update(); + updateOverlay(); } } + void SceneWidget::updateOverlay(bool toggleOverlay) + { } + void SceneWidget::setLighting (Lighting *lighting) { if (mLighting) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 8301cd446..650b4d1b5 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -59,6 +59,8 @@ namespace CSVRender void setDefaultAmbient (const Ogre::ColourValue& colour); ///< \note The actual ambient colour may differ based on lighting settings. + virtual void updateOverlay(bool toggleOverlay = false); + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e); diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp new file mode 100644 index 000000000..31c9e50ac --- /dev/null +++ b/apps/opencs/view/render/textoverlay.cpp @@ -0,0 +1,301 @@ +#include "textoverlay.hpp" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "OgreHardwarePixelBuffer.h" + +namespace CSVRender +{ + +static const int sMargin = 5; // margin around overlay text in pixels + +// Things to do: +// - configurable font size in pixels (automatically calulate everything else from it) +// - configurable texture to use +// - configurable toggle key to enable/disable the text overlays (currntly fixed 'm') +// - try material script +// - setup common resources such as font in a central place, so that they are not +// repeated for each text overlay (also destroy once) +// - decide whether to use QPaint + +// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=ObjectTextDisplay +// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=MovableTextOverlay +// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Creating+dynamic+textures +// http://www.ogre3d.org/tikiwiki/ManualObject +TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) + : mOverlay(0), mCaption(""), mEnabled(false), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) + , mFontHeight(16) // FIXME: make this configurable +{ + if(id == "" || !camera || !obj) + throw std::runtime_error("TextOverlay could not be created."); + + // setup font + if (Ogre::FontManager::getSingleton().resourceExists("DejaVuLGC")) + mFont = Ogre::FontManager::getSingleton().getByName("DejaVuLGC","General"); + else + { + Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resources\\mygui", "FileSystem"); + mFont = Ogre::FontManager::getSingleton().create("DejaVuLGC","General"); + mFont->setType(Ogre::FT_TRUETYPE); + mFont->setSource("DejaVuLGCSansMono.ttf"); + mFont->setTrueTypeSize(mFontHeight); + mFont->setTrueTypeResolution(96); + } + if(!mFont.isNull()) + mFont->load(); + else + throw std::runtime_error("TextOverlay font not loaded."); + + // setup overlay + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); + mOverlay = overlayMgr.getByName("CellIDPanel"); + if(!mOverlay) + mOverlay = overlayMgr.create("CellIDPanel"); + + // create texture + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("DynamicTransBlue"); + if(texture.isNull()) + { + texture = Ogre::TextureManager::getSingleton().createManual( + "DynamicTransBlue", // name + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, // type + 8, 8, // width & height + 0, // number of mipmaps + Ogre::PF_BYTE_BGRA, // pixel format + Ogre::TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for + // textures updated very often (e.g. each frame) + + Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); + pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); + const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); + + uint8_t* pDest = static_cast(pixelBox.data); + + // Fill in some pixel data. This will give a semi-transparent blue, + // but this is of course dependent on the chosen pixel format. + for (size_t j = 0; j < 8; j++) + { + for(size_t i = 0; i < 8; i++) + { + *pDest++ = 255; // B + *pDest++ = 0; // G + *pDest++ = 0; // R + *pDest++ = 63; // A + } + + pDest += pixelBox.getRowSkip() * Ogre::PixelUtil::getNumElemBytes(pixelBox.format); + } + pixelBuffer->unlock(); + } + + // setup material for containers + Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().create("TransOverlayMaterial", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true ); + Ogre::Pass *pass = mQuadMaterial->getTechnique( 0 )->getPass( 0 ); + pass->setLightingEnabled( false ); + pass->setDepthWriteEnabled( false ); + pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA ); + + Ogre::TextureUnitState *tex = pass->createTextureUnitState("MyCustomState", 0); + tex->setTextureName("DynamicTransBlue"); + tex->setTextureFiltering( Ogre::TFO_ANISOTROPIC ); + mQuadMaterial->load(); + + mContainer = static_cast(overlayMgr.createOverlayElement("Panel", "container"+mId)); + mContainer->setMaterialName("TransOverlayMaterial"); + mOverlay->add2D(mContainer); + + // setup text area overlay element + mElement = static_cast(overlayMgr.createOverlayElement("TextArea", "text"+mId)); + mElement->setMetricsMode(Ogre::GMM_RELATIVE); + mElement->setDimensions(1.0, 1.0); + mElement->setMetricsMode(Ogre::GMM_PIXELS); + mElement->setPosition(sMargin*2, sMargin*1.3); // 1.3 & 2 = fudge factor + + mElement->setFontName("DejaVuLGC"); + mElement->setCharHeight(fontHeight()); // NOTE: seems that this is required as well as font->setTrueTypeSize() + mElement->setHorizontalAlignment(Ogre::GHA_LEFT); + //mElement->setColour(Ogre::ColourValue(1.0, 1.0, 1.0)); // R, G, B + mElement->setColour(Ogre::ColourValue(1.0, 1.0, 0)); // yellow + + mContainer->addChild(mElement); + mOverlay->show(); +} + +void TextOverlay::getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y) +{ + Ogre::Vector3 hcsPosition = mCamera->getProjectionMatrix() * (mCamera->getViewMatrix() * position); + + x = 1.0f - ((hcsPosition.x * 0.5f) + 0.5f); // 0 <= x <= 1 // left := 0,right := 1 + y = ((hcsPosition.y * 0.5f) + 0.5f); // 0 <= y <= 1 // bottom := 0,top := 1 +} + +void TextOverlay::getMinMaxEdgesOfTopAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY) +{ + MinX = 0, MinY = 0, MaxX = 0, MaxY = 0; + float X[4]; // the 2D dots of the AABB in screencoordinates + float Y[4]; + + if (!mObj->isInScene()) + return; + + const Ogre::AxisAlignedBox &AABB = mObj->getWorldBoundingBox(true); // the AABB of the target + const Ogre::Vector3 CornersOfTopAABB[4] = { AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_TOP), + AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_TOP), + AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_TOP), + AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_TOP)}; + + //The normal vector of the plaine.this points directly infront of the cam + Ogre::Vector3 CameraPlainNormal = mCamera->getDerivedOrientation().zAxis(); + + //the plaine that devides the space bevor and behin the cam + Ogre::Plane CameraPlain = Ogre::Plane(CameraPlainNormal, mCamera->getDerivedPosition()); + + for (int i = 0; i < 4; i++) + { + X[i] = 0; + Y[i] = 0; + + getScreenCoordinates(CornersOfTopAABB[i],X[i],Y[i]); // transfor into 2d dots + + if (CameraPlain.getSide(CornersOfTopAABB[i]) == Ogre::Plane::NEGATIVE_SIDE) + { + if (i == 0) // accept the first set of values, no matter how bad it might be. + { + MinX = X[i]; + MinY = Y[i]; + MaxX = X[i]; + MaxY = Y[i]; + } + else // now compare if you get "better" values + { + if (MinX > X[i]) MinX = X[i]; + if (MinY > Y[i]) MinY = Y[i]; + if (MaxX < X[i]) MaxX = X[i]; + if (MaxY < Y[i]) MaxY = Y[i]; + } + } + else + { + MinX = 0; + MinY = 0; + MaxX = 0; + MaxY = 0; + break; + } + } +} + +TextOverlay::~TextOverlay() +{ + Ogre::OverlayManager::OverlayMapIterator iter = Ogre::OverlayManager::getSingleton().getOverlayIterator(); + if(!iter.hasMoreElements()) + mOverlay->hide(); + + Ogre::OverlayManager *overlayMgr = Ogre::OverlayManager::getSingletonPtr(); + mContainer->removeChild("text"+mId); + mOverlay->remove2D(mContainer); + overlayMgr->destroyOverlayElement(mElement); + overlayMgr->destroyOverlayElement(mContainer); + + if(!iter.hasMoreElements()) + overlayMgr->destroy(mOverlay); +} + +void TextOverlay::enable(bool enable) +{ + mEnabled = enable; + if (enable) + mOverlay->show(); + else + mOverlay->hide(); +} + +void TextOverlay::setCaption(const Ogre::String& text) +{ + if(mCaption == text) + return; + + mCaption = text; + mElement->setCaption(text); +} + +Ogre::FontPtr TextOverlay::getFont() +{ + return mFont; +} + +int TextOverlay::textWidth() +{ + float textWidth = 0; + + // NOTE: assumed fixed width font, i.e. no compensation for narrow glyphs + for(Ogre::String::const_iterator i = mCaption.begin(); i < mCaption.end(); ++i) + textWidth += getFont()->getGlyphAspectRatio(*i); + + textWidth *= fontHeight(); + + return (int) textWidth; +} + +int TextOverlay::fontHeight() +{ + return mFontHeight; +} + +void TextOverlay::update(bool toggleOverlay) +{ + if(toggleOverlay) + mEnabled = !mEnabled; + + if (!mEnabled) + { + mOverlay->hide(); + Ogre::Root::getSingleton().renderOneFrame(); + return; + } + else + mOverlay->show(); + + float min_x, max_x, min_y, max_y; + getMinMaxEdgesOfTopAABBIn2D(min_x, min_y, max_x, max_y); + + if ((min_x>0.0) && (max_x<1.0) && (min_y>0.0) && (max_y<1.0)) + { + mOnScreen = true; + mContainer->show(); + } + else + { + mOnScreen = false; + mContainer->hide(); + Ogre::Root::getSingleton().renderOneFrame(); + return; + } + + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); + float viewportWidth = std::max(overlayMgr.getViewportWidth(), 1); // zero at the start + float viewportHeight = std::max(overlayMgr.getViewportHeight(), 1); // zero at the start + + float relTextWidth = (2*sMargin + textWidth() + sMargin) / viewportWidth; // 2 = fudge factor + float relTextHeight = (sMargin + fontHeight() + sMargin) / viewportHeight; + + mContainer->setMetricsMode(Ogre::GMM_RELATIVE); + mContainer->setPosition(1-(min_x + max_x + relTextWidth)/2, 1-max_y-(relTextHeight-sMargin/viewportHeight)); + + mContainer->setDimensions(relTextWidth, relTextHeight); + + Ogre::Root::getSingleton().renderOneFrame(); +} + +} diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp new file mode 100644 index 000000000..a90b30194 --- /dev/null +++ b/apps/opencs/view/render/textoverlay.hpp @@ -0,0 +1,54 @@ +#ifndef OPENCS_VIEW_TEXTOVERLAY_H +#define OPENCS_VIEW_TEXTOVERLAY_H + +#include +#include + +namespace Ogre +{ + class MovableObject; + class Camera; + class Font; + class Overlay; + class OverlayContainer; + class TextAreaOverlayElement; +} + +namespace CSVRender +{ + + class TextOverlay + { + Ogre::Overlay* mOverlay; + Ogre::OverlayContainer* mContainer; + Ogre::TextAreaOverlayElement* mElement; + Ogre::String mCaption; + + const Ogre::MovableObject* mObj; + const Ogre::Camera* mCamera; + Ogre::FontPtr mFont; + int mFontHeight; // in pixels + Ogre::String mId; + + bool mEnabled; + bool mOnScreen; // not used + + Ogre::FontPtr getFont(); + int textWidth(); + int fontHeight(); + void getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y); + void getMinMaxEdgesOfTopAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY); + + public: + + TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String &id); + virtual ~TextOverlay(); + + void enable(bool enable); + void setCaption(const Ogre::String& text); + void update(bool toggleOverlay = false); + }; + +} + +#endif // OPENCS_VIEW_TEXTOVERLAY_H diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index fa304dd82..eca00fcba 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -314,3 +314,6 @@ void CSVRender::WorldspaceWidget::elementSelectionChanged() setVisibilityMask (getElementMask()); flagAsModified(); } + +void CSVRender::WorldspaceWidget::updateOverlay(bool toggleOverlay) +{ } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 0754e9ecf..a7d3a7882 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -88,6 +88,8 @@ namespace CSVRender CSMDoc::Document& getDocument(); + virtual void updateOverlay(bool toggleOverlay = false); + private: void dragEnterEvent(QDragEnterEvent *event); @@ -134,4 +136,4 @@ namespace CSVRender }; } -#endif \ No newline at end of file +#endif From dbb2781817d53f6374bfa39d21637f7656692f95 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 08:20:09 +1100 Subject: [PATCH 21/63] Mouse click on text overlay implemented. Removed 'm' keybinding for overlay toggle. White lines not visible by default. --- .../view/render/pagedworldspacewidget.cpp | 55 ++++++++++++------- .../view/render/pagedworldspacewidget.hpp | 4 +- apps/opencs/view/render/scenewidget.cpp | 4 +- apps/opencs/view/render/scenewidget.hpp | 6 +- apps/opencs/view/render/textoverlay.cpp | 44 ++++++++++----- apps/opencs/view/render/textoverlay.hpp | 6 ++ apps/opencs/view/render/worldspacewidget.cpp | 3 - apps/opencs/view/render/worldspacewidget.hpp | 2 - 8 files changed, 78 insertions(+), 46 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 200c1a9d7..e4677b78d 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -3,10 +3,13 @@ #include +#include + #include #include - #include +#include // FIXME +#include // FIXME #include #include "../../../../components/esm/loadland.hpp" @@ -78,7 +81,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mCells.insert (std::make_pair (*iter, new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); - // FIXME: delete this later Ogre::ManualObject* manual = getSceneManager()->createManualObject("manual" + iter->getId(mWorldspace)); manual->begin("BaseWhite", Ogre::RenderOperation::OT_LINE_LIST); @@ -93,8 +95,9 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() Ogre::MeshPtr meshPtr = manual->convertToMesh("vLine" + iter->getId(mWorldspace)); Ogre::Entity* entity = getSceneManager()->createEntity(meshPtr); getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(entity); - //entity->setVisible(false); + entity->setVisible(false); + // keep pointers so that they can be deleted later mEntities.insert(std::make_pair(iter->getId(mWorldspace), entity)); CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); @@ -110,31 +113,41 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() return modified; } -void CSVRender::PagedWorldspaceWidget::updateOverlay(bool toggleOverlay) +void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) +{ + //std::cout << "Qt x: " + std::to_string(event->x()) << ", y: " + std::to_string(event->y()) << std::endl; + + int viewportWidth = getCamera()->getViewport()->getActualWidth(); + int viewportHeight = getCamera()->getViewport()->getActualHeight(); + + Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay(event->x()/viewportWidth, event->y()/viewportHeight); + Ogre::RaySceneQuery *rayScnQuery = getSceneManager()->createRayQuery(Ogre::Ray()); + rayScnQuery->setRay(mouseRay); + Ogre::RaySceneQueryResult &result = rayScnQuery->execute(); + Ogre::RaySceneQueryResult::iterator it = result.begin(); + + std::list::iterator iter = mTextOverlays.begin(); + for(; iter != mTextOverlays.end(); ++iter) + { + if((*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) + { + std::cout << "clicked: " << (*iter)->getCaption() << std::endl; + (*iter)->enable(false); + } + } + + SceneWidget::mouseReleaseEvent(event); +} + +void CSVRender::PagedWorldspaceWidget::updateOverlay() { if(!mTextOverlays.empty()) { std::list::iterator it = mTextOverlays.begin(); for(; it != mTextOverlays.end(); ++it) { - (*it)->update(toggleOverlay); + (*it)->update(); } - std::map::iterator iter (mCells.begin()); - -#if 0 - if(toggleOverlay) - { - while (iter!=mCells.end()) - { - std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); - if(it != mEntities.end()) - { - it->second->setVisible(!it->second->isVisible()); - } - ++iter; - } - } -#endif } } diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 1013319d1..42a7ef45d 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -77,7 +77,9 @@ namespace CSVRender protected: - virtual void updateOverlay(bool toggleOverlay = false); + virtual void updateOverlay(); + + virtual void mouseReleaseEvent (QMouseEvent *event); signals: diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 089f4a4f3..d70346f81 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -287,8 +287,6 @@ namespace CSVRender break; - case Qt::Key_M: updateOverlay(true); - default: QWidget::keyReleaseEvent (event); } } @@ -387,7 +385,7 @@ namespace CSVRender } } - void SceneWidget::updateOverlay(bool toggleOverlay) + void SceneWidget::updateOverlay() { } void SceneWidget::setLighting (Lighting *lighting) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 650b4d1b5..1dab9a978 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -59,7 +59,9 @@ namespace CSVRender void setDefaultAmbient (const Ogre::ColourValue& colour); ///< \note The actual ambient colour may differ based on lighting settings. - virtual void updateOverlay(bool toggleOverlay = false); + virtual void updateOverlay(); + + virtual void mouseReleaseEvent (QMouseEvent *event); private: void paintEvent(QPaintEvent* e); @@ -78,8 +80,6 @@ namespace CSVRender void mouseMoveEvent (QMouseEvent *event); - void mouseReleaseEvent (QMouseEvent *event); - void updateOgreWindow(); void setLighting (Lighting *lighting); diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 31c9e50ac..91fb88385 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -11,20 +11,16 @@ #include #include #include -#include "OgreHardwarePixelBuffer.h" +#include namespace CSVRender { -static const int sMargin = 5; // margin around overlay text in pixels - // Things to do: // - configurable font size in pixels (automatically calulate everything else from it) // - configurable texture to use // - configurable toggle key to enable/disable the text overlays (currntly fixed 'm') // - try material script -// - setup common resources such as font in a central place, so that they are not -// repeated for each text overlay (also destroy once) // - decide whether to use QPaint // http://www.ogre3d.org/tikiwiki/tiki-index.php?page=ObjectTextDisplay @@ -32,7 +28,7 @@ static const int sMargin = 5; // margin around overlay text in pixels // http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Creating+dynamic+textures // http://www.ogre3d.org/tikiwiki/ManualObject TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) - : mOverlay(0), mCaption(""), mEnabled(false), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) + : mOverlay(0), mCaption(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) , mFontHeight(16) // FIXME: make this configurable { if(id == "" || !camera || !obj) @@ -120,7 +116,7 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam mElement->setMetricsMode(Ogre::GMM_RELATIVE); mElement->setDimensions(1.0, 1.0); mElement->setMetricsMode(Ogre::GMM_PIXELS); - mElement->setPosition(sMargin*2, sMargin*1.3); // 1.3 & 2 = fudge factor + mElement->setPosition(2*fontHeight()/3, 1.3*fontHeight()/3); // 1.3 & 2 = fudge factor mElement->setFontName("DejaVuLGC"); mElement->setCharHeight(fontHeight()); // NOTE: seems that this is required as well as font->setTrueTypeSize() @@ -214,11 +210,21 @@ TextOverlay::~TextOverlay() void TextOverlay::enable(bool enable) { + if(enable == mContainer->isVisible()) + return; + mEnabled = enable; if (enable) - mOverlay->show(); + mContainer->show(); else - mOverlay->hide(); + mContainer->hide(); + + Ogre::Root::getSingleton().renderOneFrame(); +} + +bool TextOverlay::isEnabled() +{ + return mEnabled; } void TextOverlay::setCaption(const Ogre::String& text) @@ -287,15 +293,27 @@ void TextOverlay::update(bool toggleOverlay) float viewportWidth = std::max(overlayMgr.getViewportWidth(), 1); // zero at the start float viewportHeight = std::max(overlayMgr.getViewportHeight(), 1); // zero at the start - float relTextWidth = (2*sMargin + textWidth() + sMargin) / viewportWidth; // 2 = fudge factor - float relTextHeight = (sMargin + fontHeight() + sMargin) / viewportHeight; + int width = 2*fontHeight()/3 + textWidth() + fontHeight()/3; // 2 = fudge factor + int height = fontHeight()/3 + fontHeight() + fontHeight()/3; + + float relTextWidth = width / viewportWidth; + float relTextHeight = height / viewportHeight; + + float posX = 1 - (min_x + max_x + relTextWidth)/2; + float posY = 1 - max_y - (relTextHeight-fontHeight()/3/viewportHeight); mContainer->setMetricsMode(Ogre::GMM_RELATIVE); - mContainer->setPosition(1-(min_x + max_x + relTextWidth)/2, 1-max_y-(relTextHeight-sMargin/viewportHeight)); - + mContainer->setPosition(posX, posY); mContainer->setDimensions(relTextWidth, relTextHeight); + mPos = QRect(posX*viewportWidth, posY*viewportHeight, width, height); + Ogre::Root::getSingleton().renderOneFrame(); } +QRect TextOverlay::container() +{ + return mPos; +} + } diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index a90b30194..3f0c6ac57 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -1,6 +1,8 @@ #ifndef OPENCS_VIEW_TEXTOVERLAY_H #define OPENCS_VIEW_TEXTOVERLAY_H +#include + #include #include @@ -29,6 +31,7 @@ namespace CSVRender Ogre::FontPtr mFont; int mFontHeight; // in pixels Ogre::String mId; + QRect mPos; bool mEnabled; bool mOnScreen; // not used @@ -45,8 +48,11 @@ namespace CSVRender virtual ~TextOverlay(); void enable(bool enable); + bool isEnabled(); void setCaption(const Ogre::String& text); void update(bool toggleOverlay = false); + QRect container(); + Ogre::String getCaption() { return mCaption; } // FIXME: debug }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index eca00fcba..fa304dd82 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -314,6 +314,3 @@ void CSVRender::WorldspaceWidget::elementSelectionChanged() setVisibilityMask (getElementMask()); flagAsModified(); } - -void CSVRender::WorldspaceWidget::updateOverlay(bool toggleOverlay) -{ } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index a7d3a7882..92b0bd71a 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -88,8 +88,6 @@ namespace CSVRender CSMDoc::Document& getDocument(); - virtual void updateOverlay(bool toggleOverlay = false); - private: void dragEnterEvent(QDragEnterEvent *event); From e38417e66256f08732e4bf3fdb745d04a14d9250 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 13:55:36 +1100 Subject: [PATCH 22/63] Visibility mask implemented. For testing rigged up 'M' and 'N' keys for show/hide. The scenewidget doesn't receive any mouse events for about a second after toggling the visibility flag. No idea what is causing this. --- .../view/render/pagedworldspacewidget.cpp | 91 +++++++++++++++---- .../view/render/pagedworldspacewidget.hpp | 1 + apps/opencs/view/render/scenewidget.cpp | 26 +++++- apps/opencs/view/render/scenewidget.hpp | 2 + apps/opencs/view/render/textoverlay.cpp | 14 +-- apps/opencs/view/render/textoverlay.hpp | 2 +- 6 files changed, 105 insertions(+), 31 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index e4677b78d..2755d9db1 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -8,8 +8,10 @@ #include #include #include -#include // FIXME -#include // FIXME +#include +#include +#include +#include #include #include "../../../../components/esm/loadland.hpp" @@ -115,32 +117,88 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { - //std::cout << "Qt x: " + std::to_string(event->x()) << ", y: " + std::to_string(event->y()) << std::endl; - - int viewportWidth = getCamera()->getViewport()->getActualWidth(); - int viewportHeight = getCamera()->getViewport()->getActualHeight(); - - Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay(event->x()/viewportWidth, event->y()/viewportHeight); - Ogre::RaySceneQuery *rayScnQuery = getSceneManager()->createRayQuery(Ogre::Ray()); - rayScnQuery->setRay(mouseRay); - Ogre::RaySceneQueryResult &result = rayScnQuery->execute(); - Ogre::RaySceneQueryResult::iterator it = result.begin(); - std::list::iterator iter = mTextOverlays.begin(); for(; iter != mTextOverlays.end(); ++iter) { - if((*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) + if(mDisplayCellCoord && + (*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) { std::cout << "clicked: " << (*iter)->getCaption() << std::endl; - (*iter)->enable(false); + //(*iter)->enable(false); // FIXME: for testing only } } +#if 0 + // mouse picking + int viewportWidth = getCamera()->getViewport()->getActualWidth(); + int viewportHeight = getCamera()->getViewport()->getActualHeight(); + + Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay((float)(event->x()/viewportWidth), + (float)(event->y()/viewportHeight)); + Ogre::RaySceneQuery *rayScnQuery = getSceneManager()->createRayQuery(Ogre::Ray()); + rayScnQuery->setRay(mouseRay); + rayScnQuery->setSortByDistance(true); + Ogre::RaySceneQueryResult result = rayScnQuery->execute(); + + Ogre::RaySceneQueryResult::iterator it = result.begin(); + for (; it != result.end(); it++) + { + if(it->worldFragment) + { + // FIXME: just testing + std::string str; + if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_NONE) + str = "no world geometry hits"; + else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_PLANE_BOUNDED_REGION) + str = "pointers to convex plane-bounded regions"; + else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_SINGLE_INTERSECTION) + str = "single intersection point"; + else if(it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_CUSTOM_GEOMETRY) + str = "custom geometry"; + else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_RENDER_OPERATION) + str = "general render operation structure"; + + std::cout << "fragment type: " << str << std::endl; + } + else if (it->movable) + { + // FIXME: just testing + it->movable->getParentSceneNode()->showBoundingBox(true); + + std::cout << "movable object: " + it->movable->getName() << std::endl; + } + else + std::cout << "nothing: " << std::endl; + } + + getSceneManager()->destroyQuery(rayScnQuery); +#endif + SceneWidget::mouseReleaseEvent(event); } void CSVRender::PagedWorldspaceWidget::updateOverlay() { + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); + Ogre::Overlay* overlay = overlayMgr.getByName("CellIDPanel"); + if(overlay && !mTextOverlays.empty()) + { + if(getCamera()->getViewport()) + { + if((uint32_t)getCamera()->getViewport()->getVisibilityMask() + & (uint32_t)CSVRender::Elements::Element_CellMarker) + { + mDisplayCellCoord = true; + overlay->show(); + } + else + { + mDisplayCellCoord = false; + overlay->hide(); + } + } + } + if(!mTextOverlays.empty()) { std::list::iterator it = mTextOverlays.begin(); @@ -229,7 +287,8 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() } CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) -: WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mTextOverlays(0) +: WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mDisplayCellCoord(true) +, mTextOverlays(0) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 42a7ef45d..c6c8d8e13 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -22,6 +22,7 @@ namespace CSVRender std::map mCells; std::string mWorldspace; CSVWidget::SceneToolToggle *mControlElements; + bool mDisplayCellCoord; std::list mTextOverlays; std::map mEntities; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index d70346f81..8835f857a 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -18,6 +18,7 @@ #include "navigation.hpp" #include "lighting.hpp" +#include "elements.hpp" // FIXME: for testing only namespace CSVRender { @@ -58,7 +59,7 @@ namespace CSVRender setLighting (&mLightingDay); - Ogre::OverlaySystem *mOverlaySystem = new Ogre::OverlaySystem(); // FIXME: delete + Ogre::OverlaySystem *mOverlaySystem = new Ogre::OverlaySystem(); mSceneMgr->addRenderQueueListener(mOverlaySystem); QTimer *timer = new QTimer (this); @@ -162,8 +163,17 @@ namespace CSVRender if (mWindow) Ogre::Root::getSingleton().destroyRenderTarget (mWindow); + if (mOverlaySystem) + { + if (mSceneMgr) + mSceneMgr->removeRenderQueueListener (mOverlaySystem); + + delete mOverlaySystem; + } + if (mSceneMgr) Ogre::Root::getSingleton().destroySceneManager (mSceneMgr); + } void SceneWidget::setVisibilityMask (unsigned int mask) @@ -287,6 +297,20 @@ namespace CSVRender break; + //FIXME: for testing only + case Qt::Key_N: + setVisibilityMask((uint32_t)mViewport->getVisibilityMask() + & ~(uint32_t)CSVRender::Elements::Element_CellMarker); + updateOverlay(); + break; + + //FIXME: for testing only + case Qt::Key_M: + setVisibilityMask((uint32_t)mViewport->getVisibilityMask() + | (uint32_t)CSVRender::Elements::Element_CellMarker); + updateOverlay(); + break; + default: QWidget::keyReleaseEvent (event); } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 1dab9a978..05d5c7621 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -15,6 +15,7 @@ namespace Ogre class SceneManager; class RenderWindow; class Viewport; + class OverlaySystem; } namespace CSVWidget @@ -89,6 +90,7 @@ namespace CSVRender Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; + Ogre::OverlaySystem *mOverlaySystem; Navigation *mNavigation; Lighting *mLighting; diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 91fb88385..377810ef4 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -259,20 +259,8 @@ int TextOverlay::fontHeight() return mFontHeight; } -void TextOverlay::update(bool toggleOverlay) +void TextOverlay::update() { - if(toggleOverlay) - mEnabled = !mEnabled; - - if (!mEnabled) - { - mOverlay->hide(); - Ogre::Root::getSingleton().renderOneFrame(); - return; - } - else - mOverlay->show(); - float min_x, max_x, min_y, max_y; getMinMaxEdgesOfTopAABBIn2D(min_x, min_y, max_x, max_y); diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 3f0c6ac57..30a5e3524 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -50,7 +50,7 @@ namespace CSVRender void enable(bool enable); bool isEnabled(); void setCaption(const Ogre::String& text); - void update(bool toggleOverlay = false); + void update(); QRect container(); Ogre::String getCaption() { return mCaption; } // FIXME: debug }; From 6d687993b85666a7565afe060b9dc4bb7877c250 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 14:08:35 +1100 Subject: [PATCH 23/63] Remove C++11 stuff. --- apps/opencs/view/render/scenewidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 8835f857a..b37bdf2ba 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -300,14 +300,14 @@ namespace CSVRender //FIXME: for testing only case Qt::Key_N: setVisibilityMask((uint32_t)mViewport->getVisibilityMask() - & ~(uint32_t)CSVRender::Elements::Element_CellMarker); + & ~(uint32_t)CSVRender::Element_CellMarker); updateOverlay(); break; //FIXME: for testing only case Qt::Key_M: setVisibilityMask((uint32_t)mViewport->getVisibilityMask() - | (uint32_t)CSVRender::Elements::Element_CellMarker); + | (uint32_t)CSVRender::Element_CellMarker); updateOverlay(); break; From cc6153eb8ee32659629d25d7e2c2d1df86f1baa9 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 14:21:44 +1100 Subject: [PATCH 24/63] Removed temporary key bindings. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 2 +- apps/opencs/view/render/scenewidget.cpp | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 2755d9db1..6bd81d2f9 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -186,7 +186,7 @@ void CSVRender::PagedWorldspaceWidget::updateOverlay() if(getCamera()->getViewport()) { if((uint32_t)getCamera()->getViewport()->getVisibilityMask() - & (uint32_t)CSVRender::Elements::Element_CellMarker) + & (uint32_t)CSVRender::Element_CellMarker) { mDisplayCellCoord = true; overlay->show(); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index b37bdf2ba..431d94b7e 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -297,20 +297,6 @@ namespace CSVRender break; - //FIXME: for testing only - case Qt::Key_N: - setVisibilityMask((uint32_t)mViewport->getVisibilityMask() - & ~(uint32_t)CSVRender::Element_CellMarker); - updateOverlay(); - break; - - //FIXME: for testing only - case Qt::Key_M: - setVisibilityMask((uint32_t)mViewport->getVisibilityMask() - | (uint32_t)CSVRender::Element_CellMarker); - updateOverlay(); - break; - default: QWidget::keyReleaseEvent (event); } } From 972c7890602bdecea6cadb0f1bbf4cbf5706f602 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 20:25:09 +1100 Subject: [PATCH 25/63] Add Ogre Overlay path to cmake. --- CMakeLists.txt | 2 +- apps/opencs/view/render/pagedworldspacewidget.cpp | 4 ++-- apps/opencs/view/render/scenewidget.cpp | 2 +- apps/opencs/view/render/textoverlay.cpp | 9 ++++----- apps/opencs/view/render/textoverlay.hpp | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 542ea3e94..3c1ebc524 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,7 +272,7 @@ endif () endif(OGRE_STATIC) include_directories("." - ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} + ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR}/Overlay ${SDL2_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 6bd81d2f9..f93aeaf0e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -8,8 +8,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 431d94b7e..b84e528cb 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 377810ef4..34518951b 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -4,10 +4,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -19,7 +19,6 @@ namespace CSVRender // Things to do: // - configurable font size in pixels (automatically calulate everything else from it) // - configurable texture to use -// - configurable toggle key to enable/disable the text overlays (currntly fixed 'm') // - try material script // - decide whether to use QPaint diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 30a5e3524..a4f043538 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace Ogre { From b3e09cce00e444f4ade3fdc3f216729239115e32 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 6 Oct 2014 22:29:45 +1100 Subject: [PATCH 26/63] Remove mouse picking code. --- .../view/render/pagedworldspacewidget.cpp | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index f93aeaf0e..1f7b8c31a 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -124,56 +124,9 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) (*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) { std::cout << "clicked: " << (*iter)->getCaption() << std::endl; - //(*iter)->enable(false); // FIXME: for testing only } } -#if 0 - // mouse picking - int viewportWidth = getCamera()->getViewport()->getActualWidth(); - int viewportHeight = getCamera()->getViewport()->getActualHeight(); - - Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay((float)(event->x()/viewportWidth), - (float)(event->y()/viewportHeight)); - Ogre::RaySceneQuery *rayScnQuery = getSceneManager()->createRayQuery(Ogre::Ray()); - rayScnQuery->setRay(mouseRay); - rayScnQuery->setSortByDistance(true); - Ogre::RaySceneQueryResult result = rayScnQuery->execute(); - - Ogre::RaySceneQueryResult::iterator it = result.begin(); - for (; it != result.end(); it++) - { - if(it->worldFragment) - { - // FIXME: just testing - std::string str; - if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_NONE) - str = "no world geometry hits"; - else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_PLANE_BOUNDED_REGION) - str = "pointers to convex plane-bounded regions"; - else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_SINGLE_INTERSECTION) - str = "single intersection point"; - else if(it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_CUSTOM_GEOMETRY) - str = "custom geometry"; - else if (it->worldFragment->fragmentType == Ogre::SceneQuery::WorldFragmentType::WFT_RENDER_OPERATION) - str = "general render operation structure"; - - std::cout << "fragment type: " << str << std::endl; - } - else if (it->movable) - { - // FIXME: just testing - it->movable->getParentSceneNode()->showBoundingBox(true); - - std::cout << "movable object: " + it->movable->getName() << std::endl; - } - else - std::cout << "nothing: " << std::endl; - } - - getSceneManager()->destroyQuery(rayScnQuery); -#endif - SceneWidget::mouseReleaseEvent(event); } From 0197f7088f7842a6bb16328b203bb88b301f2c6e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 06:04:13 +1100 Subject: [PATCH 27/63] Remove extra frame rendering after enabling/disabling the label. --- apps/opencs/view/render/textoverlay.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 34518951b..b451583da 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -217,8 +217,6 @@ void TextOverlay::enable(bool enable) mContainer->show(); else mContainer->hide(); - - Ogre::Root::getSingleton().renderOneFrame(); } bool TextOverlay::isEnabled() From f48f841d31257017e86e2b3fa2f9d88b7b27d72d Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 06:40:28 +1100 Subject: [PATCH 28/63] Add full path for Ogre Overlay headers (workaround for osx). --- apps/opencs/view/render/pagedworldspacewidget.cpp | 4 ++-- apps/opencs/view/render/scenewidget.cpp | 2 +- apps/opencs/view/render/textoverlay.cpp | 8 ++++---- apps/opencs/view/render/textoverlay.hpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 1f7b8c31a..b397aa7bb 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -8,8 +8,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index b84e528cb..486db6a15 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index b451583da..200f77476 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -4,10 +4,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index a4f043538..3db36c378 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace Ogre { From 7640875f9d09b6b8748089e4b5915e717e4c37ff Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 10:34:30 +1100 Subject: [PATCH 29/63] More cleanup. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 15 ++++++++------- apps/opencs/view/render/scenewidget.cpp | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b397aa7bb..03e5e1427 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -117,17 +117,18 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { - std::list::iterator iter = mTextOverlays.begin(); - for(; iter != mTextOverlays.end(); ++iter) + if(event->button() == Qt::RightButton) { - if(mDisplayCellCoord && - (*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) + std::list::iterator iter = mTextOverlays.begin(); + for(; iter != mTextOverlays.end(); ++iter) { - std::cout << "clicked: " << (*iter)->getCaption() << std::endl; + if(mDisplayCellCoord && + (*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) + { + std::cout << "clicked: " << (*iter)->getCaption() << std::endl; + } } } - - SceneWidget::mouseReleaseEvent(event); } void CSVRender::PagedWorldspaceWidget::updateOverlay() diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 486db6a15..d58ac8ec3 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -18,7 +18,6 @@ #include "navigation.hpp" #include "lighting.hpp" -#include "elements.hpp" // FIXME: for testing only namespace CSVRender { From 0cccdfd114f5d6179f6c48828e49d435ce6970b2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 19:35:28 +1100 Subject: [PATCH 30/63] Added description below the cell id (name if exists, or region) --- .../view/render/pagedworldspacewidget.cpp | 3 +++ apps/opencs/view/render/textoverlay.cpp | 25 +++++++++++++++---- apps/opencs/view/render/textoverlay.hpp | 2 ++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 03e5e1427..0cccde5cf 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -105,6 +105,9 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); textDisp->enable(true); textDisp->setCaption(iter->getId(mWorldspace)); + std::string desc = cells.getRecord(index).get().mName; + if(desc == "") desc = cells.getRecord(index).get().mRegion; + textDisp->setDesc(desc); textDisp->update(); mTextOverlays.push_back(textDisp); diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 200f77476..143d08fc4 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -233,6 +233,15 @@ void TextOverlay::setCaption(const Ogre::String& text) mElement->setCaption(text); } +void TextOverlay::setDesc(const Ogre::String& text) +{ + if(mDesc == text) + return; + + mDesc = text; + mElement->setCaption(mCaption + ((text == "") ? "" : ("\n" + text))); +} + Ogre::FontPtr TextOverlay::getFont() { return mFont; @@ -240,15 +249,19 @@ Ogre::FontPtr TextOverlay::getFont() int TextOverlay::textWidth() { - float textWidth = 0; + float captionWidth = 0; + float descWidth = 0; // NOTE: assumed fixed width font, i.e. no compensation for narrow glyphs for(Ogre::String::const_iterator i = mCaption.begin(); i < mCaption.end(); ++i) - textWidth += getFont()->getGlyphAspectRatio(*i); + captionWidth += getFont()->getGlyphAspectRatio(*i); + for(Ogre::String::const_iterator i = mDesc.begin(); i < mDesc.end(); ++i) + descWidth += getFont()->getGlyphAspectRatio(*i); - textWidth *= fontHeight(); + captionWidth *= fontHeight(); + descWidth *= fontHeight(); - return (int) textWidth; + return (int) std::max(captionWidth, descWidth); } int TextOverlay::fontHeight() @@ -278,8 +291,10 @@ void TextOverlay::update() float viewportWidth = std::max(overlayMgr.getViewportWidth(), 1); // zero at the start float viewportHeight = std::max(overlayMgr.getViewportHeight(), 1); // zero at the start - int width = 2*fontHeight()/3 + textWidth() + fontHeight()/3; // 2 = fudge factor + int width = fontHeight()/3 + textWidth() + fontHeight()/3; int height = fontHeight()/3 + fontHeight() + fontHeight()/3; + if(mDesc != "") + height = fontHeight()/3 + 2*fontHeight() + fontHeight()/3; float relTextWidth = width / viewportWidth; float relTextHeight = height / viewportHeight; diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 3db36c378..7402e33a0 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -25,6 +25,7 @@ namespace CSVRender Ogre::OverlayContainer* mContainer; Ogre::TextAreaOverlayElement* mElement; Ogre::String mCaption; + Ogre::String mDesc; const Ogre::MovableObject* mObj; const Ogre::Camera* mCamera; @@ -50,6 +51,7 @@ namespace CSVRender void enable(bool enable); bool isEnabled(); void setCaption(const Ogre::String& text); + void setDesc(const Ogre::String& text); void update(); QRect container(); Ogre::String getCaption() { return mCaption; } // FIXME: debug From a161ad3cd53e4fa504fdd67614a13b0f9e84721e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 20:11:44 +1100 Subject: [PATCH 31/63] Sort cell id column by numerical order. --- apps/opencs/model/world/idtableproxymodel.cpp | 23 ++++++++++++++++++- apps/opencs/model/world/idtableproxymodel.hpp | 6 ++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index a5e9d354a..fdfdacbf3 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -47,4 +47,25 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptrdata(left).toString()); + int leftX = cellPattern.cap(1).toInt(); + int leftY = cellPattern.cap(2).toInt(); + + int rightResult = cellPattern.indexIn(sourceModel()->data(right).toString()); + int rightX = cellPattern.cap(1).toInt(); + int rightY = cellPattern.cap(2).toInt(); + + if(leftResult != -1 && rightResult != -1) + return(leftX < rightX) || (leftX == rightX && leftY <= rightY); + else + return QSortFilterProxyModel::lessThan(left, right); +} diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index b63dccd5e..23e3193fb 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -33,7 +33,11 @@ namespace CSMWorld virtual QModelIndex getModelIndex (const std::string& id, int column) const; void setFilter (const boost::shared_ptr& filter); + + protected: + + bool lessThan(const QModelIndex &left, const QModelIndex &right) const; }; } -#endif \ No newline at end of file +#endif From 7836ee9ab6aba6dc3bd84535cc2f6c45866daef9 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 7 Oct 2014 21:18:32 +1100 Subject: [PATCH 32/63] Fixed crash exiting internal cells. Better starting camera position for external cells. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 14 ++++++++++++++ apps/opencs/view/render/pagedworldspacewidget.hpp | 2 ++ apps/opencs/view/render/scenewidget.cpp | 2 -- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 0cccde5cf..4a128d4af 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -134,8 +134,22 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) } } +void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) +{ + if(event->button() == Qt::RightButton) + { + std::cout << "double clicked" << std::endl; + } +} + void CSVRender::PagedWorldspaceWidget::updateOverlay() { + // better camera position at the start + if(getCamera()->getViewport() && getCamera()->getPosition().z < 1) + { + getCamera()->move(getCamera()->getDirection() * -6000); + } + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); Ogre::Overlay* overlay = overlayMgr.getByName("CellIDPanel"); if(overlay && !mTextOverlays.empty()) diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index c6c8d8e13..b3f3fb4ef 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -82,6 +82,8 @@ namespace CSVRender virtual void mouseReleaseEvent (QMouseEvent *event); + virtual void mouseDoubleClickEvent (QMouseEvent *event); + signals: void cellSelectionChanged (const CSMWorld::CellSelection& selection); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index d58ac8ec3..723b5027e 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -166,8 +166,6 @@ namespace CSVRender { if (mSceneMgr) mSceneMgr->removeRenderQueueListener (mOverlaySystem); - - delete mOverlaySystem; } if (mSceneMgr) From e1197e75bc085392a62d0707110e7ad45c2c8a82 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 8 Oct 2014 07:54:22 +1100 Subject: [PATCH 33/63] Handle change of names or regions to dynamically update the overlay. --- .../view/render/pagedworldspacewidget.cpp | 70 +++++++++++++++---- .../view/render/pagedworldspacewidget.hpp | 4 +- apps/opencs/view/render/textoverlay.cpp | 2 +- apps/opencs/view/render/textoverlay.hpp | 3 +- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 4a128d4af..d818de79b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -32,7 +32,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); { - // remove + // remove (or name/region modified) std::map::iterator iter (mCells.begin()); while (iter!=mCells.end()) @@ -43,21 +43,61 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted) { delete iter->second; - mCells.erase (iter++); + mCells.erase (iter); + + // delete overlays + std::map::iterator itOverlay = mTextOverlays.find(iter->first); + if(itOverlay != mTextOverlays.end()) + { + delete itOverlay->second; + mTextOverlays.erase(itOverlay); + } // destroy manual objects and entities - std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); - if(it != mEntities.end()) + std::map::iterator itEntity = mEntities.find(iter->first); + if(itEntity != mEntities.end()) { - getSceneManager()->destroyEntity(it->second); - mEntities.erase(it); + getSceneManager()->destroyEntity(itEntity->second); + mEntities.erase(itEntity); } getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); + iter++; modified = true; } else + { + // check if name or region field has changed + std::string name = cells.getRecord(index).get().mName; + std::string region = cells.getRecord(index).get().mRegion; + + std::map::iterator it = mTextOverlays.find(iter->first); + if(it != mTextOverlays.end()) + { + if(it->second->getDesc() != "") // previously had name + { + if(name != it->second->getDesc()) // new name + { + if(name != "") + it->second->setDesc(name); + else // name deleted, use region + it->second->setDesc(region); + it->second->update(); + } + } + else if(name != "") // name added + { + it->second->setDesc(name); + it->second->update(); + } + else if(region != it->second->getDesc()) // new region + { + it->second->setDesc(region); + it->second->update(); + } + } ++iter; + } } } @@ -100,7 +140,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() entity->setVisible(false); // keep pointers so that they can be deleted later - mEntities.insert(std::make_pair(iter->getId(mWorldspace), entity)); + mEntities.insert(std::make_pair(*iter, entity)); CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); textDisp->enable(true); @@ -109,7 +149,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() if(desc == "") desc = cells.getRecord(index).get().mRegion; textDisp->setDesc(desc); textDisp->update(); - mTextOverlays.push_back(textDisp); + mTextOverlays.insert(std::make_pair(*iter, textDisp)); modified = true; } @@ -122,13 +162,14 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { if(event->button() == Qt::RightButton) { - std::list::iterator iter = mTextOverlays.begin(); + std::map::iterator iter = mTextOverlays.begin(); for(; iter != mTextOverlays.end(); ++iter) { if(mDisplayCellCoord && - (*iter)->isEnabled() && (*iter)->container().contains(event->x(), event->y())) + iter->second->isEnabled() && iter->second->container().contains(event->x(), event->y())) { - std::cout << "clicked: " << (*iter)->getCaption() << std::endl; + std::cout << "clicked: " << iter->second->getCaption() << std::endl; + break; } } } @@ -172,10 +213,10 @@ void CSVRender::PagedWorldspaceWidget::updateOverlay() if(!mTextOverlays.empty()) { - std::list::iterator it = mTextOverlays.begin(); + std::map::iterator it = mTextOverlays.begin(); for(; it != mTextOverlays.end(); ++it) { - (*it)->update(); + it->second->update(); } } } @@ -259,7 +300,6 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget(document, parent), mDocument(document), mWorldspace("std::default"), mDisplayCellCoord(true) -, mTextOverlays(0) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); @@ -279,7 +319,7 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { delete iter->second; - std::map::iterator it = mEntities.find(iter->first.getId(mWorldspace)); + std::map::iterator it = mEntities.find(iter->first); if(it != mEntities.end()) { getSceneManager()->destroyEntity(it->second); diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index b3f3fb4ef..611ebd04b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -23,8 +23,8 @@ namespace CSVRender std::string mWorldspace; CSVWidget::SceneToolToggle *mControlElements; bool mDisplayCellCoord; - std::list mTextOverlays; - std::map mEntities; + std::map mTextOverlays; + std::map mEntities; private: diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 143d08fc4..901b601e8 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -27,7 +27,7 @@ namespace CSVRender // http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Creating+dynamic+textures // http://www.ogre3d.org/tikiwiki/ManualObject TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) - : mOverlay(0), mCaption(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) + : mOverlay(0), mCaption(""), mDesc(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) , mFontHeight(16) // FIXME: make this configurable { if(id == "" || !camera || !obj) diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 7402e33a0..17530a010 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -54,7 +54,8 @@ namespace CSVRender void setDesc(const Ogre::String& text); void update(); QRect container(); - Ogre::String getCaption() { return mCaption; } // FIXME: debug + Ogre::String getCaption() { return mCaption; } // FIXME: debug + Ogre::String getDesc() { return mDesc; } }; } From 4fd7537155845cea9ec07074826c8468757026f2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 8 Oct 2014 07:59:21 +1100 Subject: [PATCH 34/63] Use default sort until a more generic sort that uses numeric order can be implemented. --- apps/opencs/model/world/idtableproxymodel.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index fdfdacbf3..93c1749c6 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -51,21 +51,5 @@ void CSMWorld::IdTableProxyModel::setFilter (const boost::shared_ptrdata(left).toString()); - int leftX = cellPattern.cap(1).toInt(); - int leftY = cellPattern.cap(2).toInt(); - - int rightResult = cellPattern.indexIn(sourceModel()->data(right).toString()); - int rightX = cellPattern.cap(1).toInt(); - int rightY = cellPattern.cap(2).toInt(); - - if(leftResult != -1 && rightResult != -1) - return(leftX < rightX) || (leftX == rightX && leftY <= rightY); - else - return QSortFilterProxyModel::lessThan(left, right); + return QSortFilterProxyModel::lessThan(left, right); } From e2560de05aba8fb661f578fdade6f52e9968bbf5 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 8 Oct 2014 08:08:03 +1100 Subject: [PATCH 35/63] Don't use windows path separator. --- apps/opencs/view/render/textoverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 901b601e8..1fbcd5a88 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -38,7 +38,7 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam mFont = Ogre::FontManager::getSingleton().getByName("DejaVuLGC","General"); else { - Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resources\\mygui", "FileSystem"); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resources/mygui", "FileSystem"); mFont = Ogre::FontManager::getSingleton().create("DejaVuLGC","General"); mFont->setType(Ogre::FT_TRUETYPE); mFont->setSource("DejaVuLGCSansMono.ttf"); From 5d8022bdc5257d64e4e46356128fe0686cfd098f Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 8 Oct 2014 21:22:12 +1100 Subject: [PATCH 36/63] Update overlay upon control elements button signal. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 7 +++++++ apps/opencs/view/render/pagedworldspacewidget.hpp | 4 ++++ apps/opencs/view/render/worldspacewidget.hpp | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d818de79b..318abb4b0 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -455,6 +455,13 @@ CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibil return mControlElements; } +void CSVRender::PagedWorldspaceWidget::elementSelectionChanged () +{ + WorldspaceWidget::elementSelectionChanged(); + + updateOverlay(); +} + void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 611ebd04b..26b8a386a 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -88,6 +88,10 @@ namespace CSVRender void cellSelectionChanged (const CSMWorld::CellSelection& selection); + protected slots: + + virtual void elementSelectionChanged(); + private slots: virtual void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 92b0bd71a..6204e7f02 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -125,7 +125,7 @@ namespace CSVRender protected slots: - void elementSelectionChanged(); + virtual void elementSelectionChanged(); signals: From b3ef7a71e224c874227a9682933800410196b9f3 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 9 Oct 2014 05:56:44 +1100 Subject: [PATCH 37/63] Different implementation of update overlay fix. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 7 ------- apps/opencs/view/render/pagedworldspacewidget.hpp | 4 ---- apps/opencs/view/render/worldspacewidget.cpp | 5 +++++ apps/opencs/view/render/worldspacewidget.hpp | 4 +++- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 318abb4b0..d818de79b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -455,13 +455,6 @@ CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibil return mControlElements; } -void CSVRender::PagedWorldspaceWidget::elementSelectionChanged () -{ - WorldspaceWidget::elementSelectionChanged(); - - updateOverlay(); -} - void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 26b8a386a..611ebd04b 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -88,10 +88,6 @@ namespace CSVRender void cellSelectionChanged (const CSMWorld::CellSelection& selection); - protected slots: - - virtual void elementSelectionChanged(); - private slots: virtual void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index fa304dd82..da1c80c4d 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -313,4 +313,9 @@ void CSVRender::WorldspaceWidget::elementSelectionChanged() { setVisibilityMask (getElementMask()); flagAsModified(); + updateOverlay(); +} + +void CSVRender::WorldspaceWidget::updateOverlay() +{ } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 6204e7f02..4830d772b 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -88,6 +88,8 @@ namespace CSVRender CSMDoc::Document& getDocument(); + virtual void updateOverlay(); + private: void dragEnterEvent(QDragEnterEvent *event); @@ -125,7 +127,7 @@ namespace CSVRender protected slots: - virtual void elementSelectionChanged(); + void elementSelectionChanged(); signals: From bfd10a03c0044d98587bd93a18d7fc5517c787ad Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 10 Oct 2014 13:35:14 +1100 Subject: [PATCH 38/63] User configuration manager's resource directory. --- apps/opencs/editor.cpp | 4 ++++ apps/opencs/view/render/textoverlay.cpp | 11 +++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index de3e23965..20763beea 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -295,6 +295,10 @@ std::auto_ptr CS::Editor::setupGraphics() sh::OgrePlatform* platform = new sh::OgrePlatform ("General", (mResources / "materials").string()); + // for font used in overlays + Ogre::Root::getSingleton().addResourceLocation ((mResources / "mygui").string(), + "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + if (!boost::filesystem::exists (mCfgMgr.getCachePath())) boost::filesystem::create_directories (mCfgMgr.getCachePath()); diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 1fbcd5a88..117a57193 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -20,15 +20,15 @@ namespace CSVRender // - configurable font size in pixels (automatically calulate everything else from it) // - configurable texture to use // - try material script -// - decide whether to use QPaint +// - decide whether to use QPaint (http://www.ogre3d.org/tikiwiki/Ogre+overlays+using+Qt) -// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=ObjectTextDisplay -// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=MovableTextOverlay -// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Creating+dynamic+textures +// http://www.ogre3d.org/tikiwiki/ObjectTextDisplay +// http://www.ogre3d.org/tikiwiki/MovableTextOverlay +// http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures // http://www.ogre3d.org/tikiwiki/ManualObject TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) : mOverlay(0), mCaption(""), mDesc(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) - , mFontHeight(16) // FIXME: make this configurable + , mFontHeight(16) // FIXME: make font height configurable { if(id == "" || !camera || !obj) throw std::runtime_error("TextOverlay could not be created."); @@ -38,7 +38,6 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam mFont = Ogre::FontManager::getSingleton().getByName("DejaVuLGC","General"); else { - Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resources/mygui", "FileSystem"); mFont = Ogre::FontManager::getSingleton().create("DejaVuLGC","General"); mFont->setType(Ogre::FT_TRUETYPE); mFont->setSource("DejaVuLGCSansMono.ttf"); From 3e5027abbb9b4dcbc510fb43ed2d6c68ab65164e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 10 Oct 2014 13:36:16 +1100 Subject: [PATCH 39/63] Incorporate terrain height to labels and camera. --- apps/opencs/view/render/cell.cpp | 8 ++++ apps/opencs/view/render/cell.hpp | 2 + .../view/render/pagedworldspacewidget.cpp | 42 ++++++++++--------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 4fd66b14a..9ff24780c 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -214,3 +214,11 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int return addObjects (start, end); } + +float CSVRender::Cell::getTerrainHeightAt(const Ogre::Vector3 &pos) const +{ + if(mTerrain.get() != NULL) + return mTerrain->getHeightAt(pos); + else + return -std::numeric_limits::max(); +} diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index e63e09520..98056c354 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -70,6 +70,8 @@ namespace CSVRender /// \return Did this call result in a modification of the visual representation of /// this cell? bool referenceAdded (const QModelIndex& parent, int start, int end); + + float getTerrainHeightAt(const Ogre::Vector3 &pos) const; }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d2bf4cb05..bbdc96baf 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -68,6 +68,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() else { // check if name or region field has changed + // FIXME: config setting std::string name = cells.getRecord(index).get().mName; std::string region = cells.getRecord(index).get().mRegion; @@ -113,26 +114,34 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() if (index > 0 && cells.getRecord (index).mState!=CSMWorld::RecordBase::State_Deleted && mCells.find (*iter)==mCells.end()) { + Cell *cell = new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)); + mCells.insert (std::make_pair (*iter, cell)); + + float height = cell->getTerrainHeightAt(Ogre::Vector3( + ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + 0)); if (setCamera) { setCamera = false; - getCamera()->setPosition (ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, - ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 0); + getCamera()->setPosition ( + ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + height); + // better camera position at the start + getCamera()->move(getCamera()->getDirection() * -6000); // FIXME: config setting } - mCells.insert (std::make_pair (*iter, - new Cell (mDocument.getData(), getSceneManager(), iter->getId (mWorldspace)))); - - Ogre::ManualObject* manual = getSceneManager()->createManualObject("manual" + iter->getId(mWorldspace)); - + Ogre::ManualObject* manual = + getSceneManager()->createManualObject("manual" + iter->getId(mWorldspace)); manual->begin("BaseWhite", Ogre::RenderOperation::OT_LINE_LIST); - // define start and end point (x, y, z) - // FIXME: need terrain height to get the correct starting point manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, - ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 0); + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + height); manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, - ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, 2000); + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + height+2000); // FIXME: config setting manual->end(); Ogre::MeshPtr meshPtr = manual->convertToMesh("vLine" + iter->getId(mWorldspace)); Ogre::Entity* entity = getSceneManager()->createEntity(meshPtr); @@ -142,12 +151,13 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() // keep pointers so that they can be deleted later mEntities.insert(std::make_pair(*iter, entity)); - CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); + CSVRender::TextOverlay *textDisp = + new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); textDisp->enable(true); textDisp->setCaption(iter->getId(mWorldspace)); std::string desc = cells.getRecord(index).get().mName; if(desc == "") desc = cells.getRecord(index).get().mRegion; - textDisp->setDesc(desc); + textDisp->setDesc(desc); // FIXME: config setting textDisp->update(); mTextOverlays.insert(std::make_pair(*iter, textDisp)); @@ -185,12 +195,6 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event void CSVRender::PagedWorldspaceWidget::updateOverlay() { - // better camera position at the start - if(getCamera()->getViewport() && getCamera()->getPosition().z < 1) - { - getCamera()->move(getCamera()->getDirection() * -6000); - } - Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); Ogre::Overlay* overlay = overlayMgr.getByName("CellIDPanel"); if(overlay && !mTextOverlays.empty()) From 809b8c6d5b8ad61f42915effc0b3f9628b769ddb Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Oct 2014 05:54:21 +1100 Subject: [PATCH 40/63] Conflicts: apps/opencs/view/render/pagedworldspacewidget.cpp --- .mailmap | 139 --------- apps/launcher/graphicspage.cpp | 6 +- apps/opencs/CMakeLists.txt | 5 +- apps/opencs/editor.cpp | 2 +- apps/opencs/model/doc/document.cpp | 41 +++ apps/opencs/model/doc/document.hpp | 5 + apps/opencs/model/doc/operation.cpp | 6 +- apps/opencs/model/doc/saving.cpp | 8 + apps/opencs/model/doc/savingstages.cpp | 42 +++ apps/opencs/model/doc/savingstages.hpp | 17 ++ apps/opencs/model/world/columnbase.hpp | 6 +- apps/opencs/model/world/columnimp.hpp | 283 ++++++++++++++++++ apps/opencs/model/world/columns.cpp | 28 ++ apps/opencs/model/world/columns.hpp | 16 +- apps/opencs/model/world/data.cpp | 92 +++++- apps/opencs/model/world/data.hpp | 19 ++ apps/opencs/model/world/idcollection.hpp | 11 +- apps/opencs/model/world/pathgrid.cpp | 35 +++ apps/opencs/model/world/pathgrid.hpp | 28 ++ apps/opencs/model/world/subcellcollection.hpp | 38 +++ apps/opencs/model/world/universalid.cpp | 6 + apps/opencs/model/world/universalid.hpp | 8 +- apps/opencs/view/doc/view.cpp | 27 ++ apps/opencs/view/doc/view.hpp | 6 + apps/opencs/view/doc/viewmanager.cpp | 4 +- .../view/render/pagedworldspacewidget.cpp | 3 +- apps/opencs/view/render/scenewidget.cpp | 8 +- apps/opencs/view/render/worldspacewidget.cpp | 2 +- apps/opencs/view/settings/settingwindow.cpp | 4 +- apps/opencs/view/world/subviews.cpp | 10 + apps/openmw/mwgui/container.cpp | 2 +- apps/openmw/mwgui/hud.hpp | 2 - apps/openmw/mwgui/inventorywindow.cpp | 2 + apps/openmw/mwgui/mainmenu.cpp | 3 +- apps/openmw/mwgui/spellcreationdialog.cpp | 4 + apps/openmw/mwgui/windowmanagerimp.hpp | 2 - apps/openmw/mwrender/occlusionquery.cpp | 10 +- apps/openmw/mwrender/shadows.cpp | 3 +- apps/openmw/mwrender/sky.cpp | 2 + apps/openmw/mwworld/store.hpp | 1 + components/compiler/fileparser.cpp | 1 + components/compiler/scanner.cpp | 20 +- components/compiler/scanner.hpp | 4 + components/esm/loadmgef.cpp | 201 +++++++++++++ components/esm/loadmgef.hpp | 6 + components/esm/loadpgrd.cpp | 10 + components/esm/loadpgrd.hpp | 2 + components/esm/loadsndg.cpp | 6 + components/esm/loadsndg.hpp | 2 + 49 files changed, 1001 insertions(+), 187 deletions(-) delete mode 100644 .mailmap create mode 100644 apps/opencs/model/world/pathgrid.cpp create mode 100644 apps/opencs/model/world/pathgrid.hpp create mode 100644 apps/opencs/model/world/subcellcollection.hpp diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 50ff0928d..000000000 --- a/.mailmap +++ /dev/null @@ -1,139 +0,0 @@ -Adam Hogan -Aleksandar Jovanov -Alexander Olofsson -Alex McKibben -Alex "rainChu" Haddad -Ardekantur -Armin Preiml -Artem Kotsynyak -Arthur Moore -Arthur Moore -athile -athile -Stefan Galowicz -Bret Curtis -Britt Mathis -Sandy Carter -Sandy Carter -Carl Maxwell -cc9cii -Cory F. Cohen -Chris Robinson -Cris Mihalache -darkf -Diggory Hardy -Thomas Luppi -Thomas Luppi -Dmitriy 'Endorph' Shkurskiy -Dmitry Marakasov -Douglas Diniz -Douglas Mencken -Edmondo Tommasina -Eduard Cot -Eli2 -Emanuel Guével -Leon Saunders -Fil Krynicki -John Blomberg -Gašper Sedej -Michał Bień -Joel Graff -Paul McElroy -Artem Kotsynyak -Artem Kotsynyak -gugus -guidoj -gus -Hallfaer Tuilinn -Julian Ospald -Jacob Essex -Jan Borsodi -Jan-Peter Nilsson -Jason Hooks -Jason Hooks -Jason Hooks -Jeffrey Haines -Jeffrey Haines -Jordan Ayers -Jordan Milne -Josua Grawitter -Julien Voisin -Karl-Felix Glatzer -Chris Robinson -Kevin Poitra -Roman Proskuryakov -Lars Söderberg -lazydev -lazydev -Lukasz Gromanowski -Marc Bouvier -Marcin Hulist -Marc Zinnschlag -Marek Kochanowicz -Marek Kochanowicz -Marek Kochanowicz -Mark Siewert -Mark Siewert -megaton <9megaton6@gmail.com> -Michael Mc Donnell -Michael Papageorgiou -Michal Sciubidlo -Michał Ściubidło -Nathan Jeffords -Nicolay Korslund -Nicolay Korslund -Nikolay Kasyanov -pchan3 -Pieter van der Kloet -Mateusz Kołaczek -Bret Curtis -Pieter van der Kloet -Rohit Nirmal -Roman Melnik -Radu-Marius Popovici -Sandy Carter -Scott Howard -Jannik Heller -Jannik Heller -Sebastian Wick -Sebastian Wick -Sergey Shambir -sergoz -Chris Boyce -Star-Demon -Sylvain Thesnieres -Thomas Luppi -Thomas Luppi -Thoronador -TomKoenderink -Tom Mason -Torben Carrington -Vincent Heuken -Manuel Edelmann -Manuel Edelmann -Alexander Nadeau -Michael Hogan -Jacob Essex -Yuri Krupenin -Bret Curtis - -sirherrbatka -sirherrbatka -sergei -riothamus -nobrakal -nkorslund -mrcheko -Miroslav Puda -MiroslavR -mckibbenta -jeaye -eroen -eroen -dreamer-dead -crysthala -Berulacks -Axujen -root -unknown - diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 638237f34..1c6e69023 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -33,7 +33,11 @@ QString getAspect(int x, int y) } Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent) - : mCfgMgr(cfg) + : mOgre(NULL) + , mSelectedRenderSystem(NULL) + , mOpenGLRenderSystem(NULL) + , mDirect3DRenderSystem(NULL) + , mCfgMgr(cfg) , mGraphicsSettings(graphicsSetting) , QWidget(parent) { diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ff28dfce4..eb15a953d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -26,11 +26,12 @@ opencs_units (model/world opencs_units_noqt (model/world universalid record commands columnbase scriptcontext cell refidcollection - refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope landtexture land + refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection resources resourcesmanager scope + pathgrid landtexture land ) opencs_hdrs_noqt (model/world - columnimp idcollection collection info + columnimp idcollection collection info subcellcollection ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 20763beea..63406cb86 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -21,7 +21,7 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), - mIpcServerName ("org.openmw.OpenCS") + mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) { std::pair > config = readConfig(); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 9a174d9d5..4fdfd2e5e 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2023,6 +2023,7 @@ void CSMDoc::Document::addOptionalGmsts() { ESM::GameSetting gmst; gmst.mId = sFloats[i]; + gmst.blank(); gmst.mValue.setType (ESM::VT_Float); addOptionalGmst (gmst); } @@ -2031,6 +2032,7 @@ void CSMDoc::Document::addOptionalGmsts() { ESM::GameSetting gmst; gmst.mId = sIntegers[i]; + gmst.blank(); gmst.mValue.setType (ESM::VT_Int); addOptionalGmst (gmst); } @@ -2039,6 +2041,7 @@ void CSMDoc::Document::addOptionalGmsts() { ESM::GameSetting gmst; gmst.mId = sStrings[i]; + gmst.blank(); gmst.mValue.setType (ESM::VT_String); gmst.mValue.setString (""); addOptionalGmst (gmst); @@ -2059,6 +2062,7 @@ void CSMDoc::Document::addOptionalGlobals() { ESM::Global global; global.mId = sGlobals[i]; + global.blank(); global.mValue.setType (ESM::VT_Long); if (i==0) @@ -2068,6 +2072,19 @@ void CSMDoc::Document::addOptionalGlobals() } } +void CSMDoc::Document::addOptionalMagicEffects() +{ + for (int i=ESM::MagicEffect::SummonFabricant; i<=ESM::MagicEffect::SummonCreature05; ++i) + { + ESM::MagicEffect effect; + effect.mIndex = i; + effect.mId = ESM::MagicEffect::indexToId (i); + effect.blank(); + + addOptionalMagicEffect (effect); + } +} + void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst) { if (getData().getGmsts().searchId (gmst.mId)==-1) @@ -2090,6 +2107,17 @@ void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global) } } +void CSMDoc::Document::addOptionalMagicEffect (const ESM::MagicEffect& magicEffect) +{ + if (getData().getMagicEffects().searchId (magicEffect.mId)==-1) + { + CSMWorld::Record record; + record.mBase = magicEffect; + record.mState = CSMWorld::RecordBase::State_BaseOnly; + getData().getMagicEffects().appendRecord (record); + } +} + void CSMDoc::Document::createBase() { static const char *sGlobals[] = @@ -2201,6 +2229,18 @@ void CSMDoc::Document::createBase() getData().getTopics().add (record); } + + for (int i=0; i >()), mCurrentStage(mStages.begin()), + mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered), + mFinalAlways (finalAlways), mError(false) { connect (this, SIGNAL (finished()), this, SLOT (operationDone())); } @@ -120,4 +122,4 @@ void CSMDoc::Operation::executeStage() void CSMDoc::Operation::operationDone() { emit done (mType, mError); -} \ No newline at end of file +} diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index 9c6932941..70e9e1d87 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -72,6 +72,12 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCollectionStage > (mDocument.getData().getBodyParts(), mState)); + appendStage (new WriteCollectionStage > + (mDocument.getData().getSoundGens(), mState)); + + appendStage (new WriteCollectionStage > + (mDocument.getData().getMagicEffects(), mState)); + appendStage (new WriteDialogueCollectionStage (mDocument, mState, false)); appendStage (new WriteDialogueCollectionStage (mDocument, mState, true)); @@ -82,6 +88,8 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje appendStage (new WriteCellCollectionStage (mDocument, mState)); + appendStage (new WritePathgridCollectionStage (mDocument, mState)); + // close file and clean up appendStage (new CloseSaveStage (mState)); diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index d62947df6..08f8c9eaa 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -311,6 +311,48 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) } +CSMDoc::WritePathgridCollectionStage::WritePathgridCollectionStage (Document& document, + SavingState& state) +: mDocument (document), mState (state) +{} + +int CSMDoc::WritePathgridCollectionStage::setup() +{ + return mDocument.getData().getPathgrids().getSize(); +} + +void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages) +{ + const CSMWorld::Record& pathgrid = + mDocument.getData().getPathgrids().getRecord (stage); + + if (pathgrid.mState==CSMWorld::RecordBase::State_Modified || + pathgrid.mState==CSMWorld::RecordBase::State_ModifiedOnly) + { + CSMWorld::Pathgrid record = pathgrid.get(); + + if (record.mId.substr (0, 1)=="#") + { + std::istringstream stream (record.mId.c_str()); + char ignore; + stream >> ignore >> record.mData.mX >> record.mData.mY; + } + else + record.mCell = record.mId; + + mState.getWriter().startRecord (record.sRecordId); + + record.save (mState.getWriter()); + + mState.getWriter().endRecord (record.sRecordId); + } + else if (pathgrid.mState==CSMWorld::RecordBase::State_Deleted) + { + /// \todo write record with delete flag + } +} + + CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) : mState (state) {} diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 54e877ef3..87c9ba7eb 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -183,6 +183,23 @@ namespace CSMDoc ///< Messages resulting from this stage will be appended to \a messages. }; + + class WritePathgridCollectionStage : public Stage + { + Document& mDocument; + SavingState& mState; + + public: + + WritePathgridCollectionStage (Document& document, SavingState& state); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, Messages& messages); + ///< Messages resulting from this stage will be appended to \a messages. + }; + class CloseSaveStage : public Stage { SavingState& mState; diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 45cb47ba0..db9b8b3c6 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -101,7 +101,9 @@ namespace CSMWorld Display_Texture, Display_Video, Display_Colour, - Display_ScriptLines // console context + Display_ScriptLines, // console context + Display_SoundGeneratorType, + Display_School }; int mColumnId; @@ -125,8 +127,6 @@ namespace CSMWorld template struct Column : public ColumnBase { - int mFlags; - Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) : ColumnBase (columnId, displayType, flags) {} diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index b93deccb7..a25e36fc1 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1,7 +1,9 @@ #ifndef CSM_WOLRD_COLUMNIMP_H #define CSM_WOLRD_COLUMNIMP_H +#include #include +#include #include @@ -1982,6 +1984,287 @@ namespace CSMWorld return false; } }; + + template + struct SoundColumn : public Column + { + SoundColumn() + : Column (Columns::ColumnId_Sound, ColumnBase::Display_Sound) + {} + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 (record.get().mSound.c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mSound = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct CreatureColumn : public Column + { + CreatureColumn() + : Column (Columns::ColumnId_Creature, ColumnBase::Display_Creature) + {} + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 (record.get().mCreature.c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mCreature = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct SoundGeneratorTypeColumn : public Column + { + SoundGeneratorTypeColumn() + : Column (Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType) + {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mType); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mType = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct BaseCostColumn : public Column + { + BaseCostColumn() : Column (Columns::ColumnId_BaseCost, ColumnBase::Display_Float) {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mBaseCost; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + record2.mData.mBaseCost = data.toFloat(); + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct SchoolColumn : public Column + { + SchoolColumn() + : Column (Columns::ColumnId_School, ColumnBase::Display_School) + {} + + virtual QVariant get (const Record& record) const + { + return record.get().mData.mSchool; + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + record2.mData.mSchool = data.toInt(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct EffectTextureColumn : public Column + { + EffectTextureColumn (Columns::ColumnId columnId) + : Column (columnId, ColumnBase::Display_Texture) + { + assert (this->mColumnId==Columns::ColumnId_Icon || + this->mColumnId==Columns::ColumnId_Particle); + } + + virtual QVariant get (const Record& record) const + { + return QString::fromUtf8 ( + (this->mColumnId==Columns::ColumnId_Icon ? + record.get().mIcon : record.get().mParticle).c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT record2 = record.get(); + + (this->mColumnId==Columns::ColumnId_Icon ? + record2.mIcon : record2.mParticle) + = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct EffectObjectColumn : public Column + { + EffectObjectColumn (Columns::ColumnId columnId) + : Column (columnId, columnId==Columns::ColumnId_BoltObject ? ColumnBase::Display_Weapon : ColumnBase::Display_Static) + { + assert (this->mColumnId==Columns::ColumnId_CastingObject || + this->mColumnId==Columns::ColumnId_HitObject || + this->mColumnId==Columns::ColumnId_AreaObject || + this->mColumnId==Columns::ColumnId_BoltObject); + } + + virtual QVariant get (const Record& record) const + { + const std::string *string = 0; + + switch (this->mColumnId) + { + case Columns::ColumnId_CastingObject: string = &record.get().mCasting; break; + case Columns::ColumnId_HitObject: string = &record.get().mHit; break; + case Columns::ColumnId_AreaObject: string = &record.get().mArea; break; + case Columns::ColumnId_BoltObject: string = &record.get().mBolt; break; + } + + if (!string) + throw std::logic_error ("Unsupported column ID"); + + return QString::fromUtf8 (string->c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + std::string *string = 0; + + ESXRecordT record2 = record.get(); + + switch (this->mColumnId) + { + case Columns::ColumnId_CastingObject: string = &record2.mCasting; break; + case Columns::ColumnId_HitObject: string = &record2.mHit; break; + case Columns::ColumnId_AreaObject: string = &record2.mArea; break; + case Columns::ColumnId_BoltObject: string = &record2.mBolt; break; + } + + if (!string) + throw std::logic_error ("Unsupported column ID"); + + *string = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; + + template + struct EffectSoundColumn : public Column + { + EffectSoundColumn (Columns::ColumnId columnId) + : Column (columnId, ColumnBase::Display_Sound) + { + assert (this->mColumnId==Columns::ColumnId_CastingSound || + this->mColumnId==Columns::ColumnId_HitSound || + this->mColumnId==Columns::ColumnId_AreaSound || + this->mColumnId==Columns::ColumnId_BoltSound); + } + + virtual QVariant get (const Record& record) const + { + const std::string *string = 0; + + switch (this->mColumnId) + { + case Columns::ColumnId_CastingSound: string = &record.get().mCastSound; break; + case Columns::ColumnId_HitSound: string = &record.get().mHitSound; break; + case Columns::ColumnId_AreaSound: string = &record.get().mAreaSound; break; + case Columns::ColumnId_BoltSound: string = &record.get().mBoltSound; break; + } + + if (!string) + throw std::logic_error ("Unsupported column ID"); + + return QString::fromUtf8 (string->c_str()); + } + + virtual void set (Record& record, const QVariant& data) + { + std::string *string = 0; + + ESXRecordT record2 = record.get(); + + switch (this->mColumnId) + { + case Columns::ColumnId_CastingSound: string = &record2.mCastSound; break; + case Columns::ColumnId_HitSound: string = &record2.mHitSound; break; + case Columns::ColumnId_AreaSound: string = &record2.mAreaSound; break; + case Columns::ColumnId_BoltSound: string = &record2.mBoltSound; break; + } + + if (!string) + throw std::logic_error ("Unsupported column ID"); + + *string = data.toString().toUtf8().constData(); + + record.setModified (record2); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 90af20059..8349eb515 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -186,6 +186,21 @@ namespace CSMWorld { ColumnId_GlobalProfile, "Global Profile" }, { ColumnId_RefNumCounter, "RefNum Counter" }, { ColumnId_RefNum, "RefNum" }, + { ColumnId_Creature, "Creature" }, + { ColumnId_SoundGeneratorType, "Sound Generator Type" }, + { ColumnId_AllowSpellmaking, "Allow Spellmaking" }, + { ColumnId_AllowEnchanting, "Allow Enchanting" }, + { ColumnId_BaseCost, "Base Cost" }, + { ColumnId_School, "School" }, + { ColumnId_Particle, "Particle" }, + { ColumnId_CastingObject, "Casting Object" }, + { ColumnId_HitObject, "Hit Object" }, + { ColumnId_AreaObject, "Area Object" }, + { ColumnId_BoltObject, "Bolt Object" }, + { ColumnId_CastingSound, "Casting Sound" }, + { ColumnId_HitSound, "Hit Sound" }, + { ColumnId_AreaSound, "Area Sound" }, + { ColumnId_BoltSound, "Bolt Sound" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, @@ -327,6 +342,17 @@ namespace "Skin", "Clothing", "Armour", 0 }; + static const char *sSoundGeneratorType[] = + { + "Left Foot", "Right Foot", "Swim Left", "Swim Right", "Moan", "Roar", "Scream", + "Land", 0 + }; + + static const char *sSchools[] = + { + "Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0 + }; + const char **getEnumNames (CSMWorld::Columns::ColumnId column) { switch (column) @@ -347,6 +373,8 @@ namespace case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes; case CSMWorld::Columns::ColumnId_BodyPartType: return sBodyPartTypes; case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes; + case CSMWorld::Columns::ColumnId_SoundGeneratorType: return sSoundGeneratorType; + case CSMWorld::Columns::ColumnId_School: return sSchools; default: return 0; } diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 5da1765a4..ca0326655 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -179,7 +179,21 @@ namespace CSMWorld ColumnId_GlobalProfile = 167, ColumnId_RefNumCounter = 168, ColumnId_RefNum = 169, - + ColumnId_Creature = 170, + ColumnId_SoundGeneratorType = 171, + ColumnId_AllowSpellmaking = 172, + ColumnId_AllowEnchanting = 173, + ColumnId_BaseCost = 174, + ColumnId_School = 175, + ColumnId_Particle = 176, + ColumnId_CastingObject = 177, + ColumnId_HitObject = 178, + ColumnId_AreaObject = 179, + ColumnId_BoltObject = 180, + ColumnId_CastingSound = 177, + ColumnId_HitSound = 178, + ColumnId_AreaSound = 179, + ColumnId_BoltSound = 180, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. ColumnId_UseValue1 = 0x10000, diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 78349a8db..c11594207 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -59,8 +59,8 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec } CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager) -: mEncoder (encoding), mRefs (mCells), mResourcesManager (resourcesManager), mReader (0), - mDialogue (0) +: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), + mResourcesManager (resourcesManager), mReader (0), mDialogue (0) { mGlobals.addColumn (new StringIdColumn); mGlobals.addColumn (new RecordStateColumn); @@ -71,7 +71,6 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mGmsts.addColumn (new StringIdColumn); mGmsts.addColumn (new RecordStateColumn); mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); - mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); mGmsts.addColumn (new VarTypeColumn (ColumnBase::Display_GmstVarType)); mGmsts.addColumn (new VarValueColumn); @@ -221,6 +220,40 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc mBodyParts.addColumn (new ModelColumn); mBodyParts.addColumn (new RaceColumn); + mSoundGens.addColumn (new StringIdColumn); + mSoundGens.addColumn (new RecordStateColumn); + mSoundGens.addColumn (new FixedRecordTypeColumn (UniversalId::Type_SoundGen)); + mSoundGens.addColumn (new CreatureColumn); + mSoundGens.addColumn (new SoundColumn); + mSoundGens.addColumn (new SoundGeneratorTypeColumn); + + mMagicEffects.addColumn (new StringIdColumn); + mMagicEffects.addColumn (new RecordStateColumn); + mMagicEffects.addColumn (new FixedRecordTypeColumn (UniversalId::Type_MagicEffect)); + mMagicEffects.addColumn (new SchoolColumn); + mMagicEffects.addColumn (new BaseCostColumn); + mMagicEffects.addColumn (new EffectTextureColumn (Columns::ColumnId_Icon)); + mMagicEffects.addColumn (new EffectTextureColumn (Columns::ColumnId_Particle)); + mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_CastingObject)); + mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_HitObject)); + mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_AreaObject)); + mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_BoltObject)); + mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_CastingSound)); + mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_HitSound)); + mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_AreaSound)); + mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_BoltSound)); + mMagicEffects.addColumn (new FlagColumn ( + Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking)); + mMagicEffects.addColumn (new FlagColumn ( + Columns::ColumnId_AllowEnchanting, ESM::MagicEffect::AllowEnchanting)); + mMagicEffects.addColumn (new FlagColumn ( + Columns::ColumnId_NegativeLight, ESM::MagicEffect::NegativeLight)); + mMagicEffects.addColumn (new DescriptionColumn); + + mPathgrids.addColumn (new StringIdColumn); + mPathgrids.addColumn (new RecordStateColumn); + mPathgrids.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Pathgrid)); + mRefs.addColumn (new StringIdColumn (true)); mRefs.addColumn (new RecordStateColumn); mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); @@ -291,6 +324,9 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc addModel (new IdTable (&mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); addModel (new IdTable (&mEnchantments), UniversalId::Type_Enchantment); addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); + addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen); + addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); + addModel (new IdTable (&mPathgrids), UniversalId::Type_Pathgrid); addModel (new IdTable (&mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); @@ -549,6 +585,36 @@ const CSMWorld::IdCollection& CSMWorld::Data::getLandText return mLandTextures; } +const CSMWorld::IdCollection& CSMWorld::Data::getSoundGens() const +{ + return mSoundGens; +} + +CSMWorld::IdCollection& CSMWorld::Data::getSoundGens() +{ + return mSoundGens; +} + +const CSMWorld::IdCollection& CSMWorld::Data::getMagicEffects() const +{ + return mMagicEffects; +} + +CSMWorld::IdCollection& CSMWorld::Data::getMagicEffects() +{ + return mMagicEffects; +} + +const CSMWorld::SubCellCollection& CSMWorld::Data::getPathgrids() const +{ + return mPathgrids; +} + +CSMWorld::SubCellCollection& CSMWorld::Data::getPathgrids() +{ + return mPathgrids; +} + const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const { return mResourcesManager.get (id.getType()); @@ -641,6 +707,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages) case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break; case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break; + case ESM::REC_SNDG: mSoundGens.load (*mReader, mBase); break; + case ESM::REC_MGEF: mMagicEffects.load (*mReader, mBase); break; + case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break; case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break; case ESM::REC_LAND: mLand.load(*mReader, mBase); break; @@ -794,9 +863,9 @@ bool CSMWorld::Data::hasId (const std::string& id) const getCells().searchId (id)!=-1 || getEnchantments().searchId (id)!=-1 || getBodyParts().searchId (id)!=-1 || - getReferenceables().searchId (id)!=-1 || - getLand().searchId (id) != -1 || - getLandTextures().searchId (id) != -1; + getSoundGens().searchId (id)!=-1 || + getMagicEffects().searchId (id)!=-1 || + getReferenceables().searchId (id)!=-1; } int CSMWorld::Data::count (RecordBase::State state) const @@ -816,9 +885,12 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mCells) + count (state, mEnchantments) + count (state, mBodyParts) + - count (state, mReferenceables) + count (state, mLand) + - count (state, mLandTextures); + count (state, mLandTextures) + + count (state, mSoundGens) + + count (state, mMagicEffects) + + count (state, mReferenceables) + + count (state, mPathgrids); } void CSMWorld::Data::setDescription (const std::string& description) @@ -860,9 +932,9 @@ std::vector CSMWorld::Data::getIds (bool listDeleted) const appendIds (ids, mCells, listDeleted); appendIds (ids, mEnchantments, listDeleted); appendIds (ids, mBodyParts, listDeleted); + appendIds (ids, mSoundGens, listDeleted); + appendIds (ids, mMagicEffects, listDeleted); appendIds (ids, mReferenceables, listDeleted); - appendIds (ids, mLand, listDeleted); - appendIds (ids, mLandTextures, listDeleted); std::sort (ids.begin(), ids.end()); diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index aa4e640c2..70a02656b 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -38,6 +40,8 @@ #include "refidcollection.hpp" #include "refcollection.hpp" #include "infocollection.hpp" +#include "pathgrid.hpp" +#include "subcellcollection.hpp" class QAbstractItemModel; @@ -72,7 +76,10 @@ namespace CSMWorld IdCollection mJournals; IdCollection mEnchantments; IdCollection mBodyParts; + IdCollection mMagicEffects; + SubCellCollection mPathgrids; IdCollection mDebugProfiles; + IdCollection mSoundGens; InfoCollection mTopicInfos; InfoCollection mJournalInfos; IdCollection mCells; @@ -205,6 +212,18 @@ namespace CSMWorld const IdCollection& getLandTextures() const; + const IdCollection& getSoundGens() const; + + IdCollection& getSoundGens(); + + const IdCollection& getMagicEffects() const; + + IdCollection& getMagicEffects(); + + const SubCellCollection& getPathgrids() const; + + SubCellCollection& getPathgrids(); + /// Throws an exception, if \a id does not match a resources list. const Resources& getResources (const UniversalId& id) const; diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 940181c24..0129ba3d8 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -11,6 +11,8 @@ namespace CSMWorld template > class IdCollection : public Collection { + virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); + public: void load (ESM::ESMReader& reader, bool base); @@ -26,6 +28,13 @@ namespace CSMWorld /// \return Has the ID been deleted? }; + template + void IdCollection::loadRecord (ESXRecordT& record, + ESM::ESMReader& reader) + { + record.load (reader); + } + template void IdCollection::load (ESM::ESMReader& reader, bool base) { @@ -69,7 +78,7 @@ namespace CSMWorld record = this->getRecord (index).get(); } - record.load (reader); + loadRecord (record, reader); if (index==-1) { diff --git a/apps/opencs/model/world/pathgrid.cpp b/apps/opencs/model/world/pathgrid.cpp new file mode 100644 index 000000000..1c82585df --- /dev/null +++ b/apps/opencs/model/world/pathgrid.cpp @@ -0,0 +1,35 @@ + +#include "pathgrid.hpp" + +#include + +void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, const IdCollection& cells) +{ + load (esm); + + // correct ID + if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1) + { + std::ostringstream stream; + + stream << "#" << mData.mX << " " << mData.mY; + + mId = stream.str(); + } +} + +void CSMWorld::Pathgrid::load (ESM::ESMReader &esm) +{ + ESM::Pathgrid::load (esm); + + if (mCell.empty()) + { + std::ostringstream stream; + + stream << "#" << mData.mX << " " << mData.mY; + + mId = stream.str(); + } + else + mId = mCell; +} diff --git a/apps/opencs/model/world/pathgrid.hpp b/apps/opencs/model/world/pathgrid.hpp new file mode 100644 index 000000000..3c9fcff50 --- /dev/null +++ b/apps/opencs/model/world/pathgrid.hpp @@ -0,0 +1,28 @@ +#ifndef CSM_WOLRD_PATHGRID_H +#define CSM_WOLRD_PATHGRID_H + +#include +#include + +#include + +#include "idcollection.hpp" +#include "cell.hpp" + +namespace CSMWorld +{ + /// \brief Wrapper for Pathgrid record + /// + /// \attention The mData.mX and mData.mY fields of the ESM::Pathgrid struct are not used. + /// Exterior cell coordinates are encoded in the pathgrid ID. + struct Pathgrid : public ESM::Pathgrid + { + std::string mId; + + void load (ESM::ESMReader &esm, const IdCollection& cells); + + void load (ESM::ESMReader &esm); + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp new file mode 100644 index 000000000..28f0de695 --- /dev/null +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -0,0 +1,38 @@ +#ifndef CSM_WOLRD_SUBCOLLECTION_H +#define CSM_WOLRD_SUBCOLLECTION_H + +#include "idcollection.hpp" + +namespace CSMWorld +{ + /// \brief Single type collection of top level records that are associated with cells + template > + class SubCellCollection : public IdCollection + { + const IdCollection& mCells; + + virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); + + public: + + SubCellCollection (const IdCollection& cells); + + + }; + + template + void SubCellCollection::loadRecord (ESXRecordT& record, + ESM::ESMReader& reader) + { + record.load (reader, mCells); + } + + template + SubCellCollection::SubCellCollection ( + const IdCollection& cells) + : mCells (cells) + {} + +} + +#endif diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 816dbc4fb..f2ed87d61 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -52,6 +52,9 @@ namespace { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", 0 }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_DebugProfiles, "Debug Profiles", 0 }, { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_RunLog, "Run Log", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_SoundGens, "Sound Generators", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MagicEffects, "Magic Effects", 0 }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; @@ -112,6 +115,9 @@ namespace { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_DebugProfile, "Debug Profile", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", 0 }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 0 }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 069beed4b..ce2d021d0 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -122,10 +122,16 @@ namespace CSMWorld Type_Video, Type_DebugProfiles, Type_DebugProfile, + Type_SoundGens, + Type_SoundGen, + Type_MagicEffects, + Type_MagicEffect, + Type_Pathgrids, + Type_Pathgrid, Type_RunLog }; - enum { NumberOfTypes = Type_DebugProfile+1 }; + enum { NumberOfTypes = Type_RunLog+1 }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 73beee60c..67c76d026 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -135,6 +135,10 @@ void CSVDoc::View::setupWorldMenu() connect (references, SIGNAL (triggered()), this, SLOT (addReferencesSubView())); world->addAction (references); + QAction *grid = new QAction (tr ("Pathgrid"), this); + connect (grid, SIGNAL (triggered()), this, SLOT (addPathgridSubView())); + world->addAction (grid); + world->addSeparator(); // items that don't represent single record lists follow here QAction *regionMap = new QAction (tr ("Region Map"), this); @@ -165,6 +169,10 @@ void CSVDoc::View::setupMechanicsMenu() QAction *enchantments = new QAction (tr ("Enchantments"), this); connect (enchantments, SIGNAL (triggered()), this, SLOT (addEnchantmentsSubView())); mechanics->addAction (enchantments); + + QAction *effects = new QAction (tr ("Magic Effects"), this); + connect (effects, SIGNAL (triggered()), this, SLOT (addMagicEffectsSubView())); + mechanics->addAction (effects); } void CSVDoc::View::setupCharacterMenu() @@ -220,6 +228,10 @@ void CSVDoc::View::setupAssetsMenu() connect (sounds, SIGNAL (triggered()), this, SLOT (addSoundsSubView())); assets->addAction (sounds); + QAction *soundGens = new QAction (tr ("Sound Generators"), this); + connect (soundGens, SIGNAL (triggered()), this, SLOT (addSoundGensSubView())); + assets->addAction (soundGens); + assets->addSeparator(); // resources follow here QAction *meshes = new QAction (tr ("Meshes"), this); @@ -634,6 +646,11 @@ void CSVDoc::View::addBodyPartsSubView() addSubView (CSMWorld::UniversalId::Type_BodyParts); } +void CSVDoc::View::addSoundGensSubView() +{ + addSubView (CSMWorld::UniversalId::Type_SoundGens); +} + void CSVDoc::View::addMeshesSubView() { addSubView (CSMWorld::UniversalId::Type_Meshes); @@ -654,6 +671,11 @@ void CSVDoc::View::addSoundsResSubView() addSubView (CSMWorld::UniversalId::Type_SoundsRes); } +void CSVDoc::View::addMagicEffectsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_MagicEffects); +} + void CSVDoc::View::addTexturesSubView() { addSubView (CSMWorld::UniversalId::Type_Textures); @@ -674,6 +696,11 @@ void CSVDoc::View::addRunLogSubView() addSubView (CSMWorld::UniversalId::Type_RunLog); } +void CSVDoc::View::addPathgridSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Pathgrids); +} + void CSVDoc::View::abortOperation (int type) { mDocument->abortOperation (type); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index eab274a59..e3ada1f2e 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -193,6 +193,10 @@ namespace CSVDoc void addBodyPartsSubView(); + void addSoundGensSubView(); + + void addMagicEffectsSubView(); + void addMeshesSubView(); void addIconsSubView(); @@ -209,6 +213,8 @@ namespace CSVDoc void addRunLogSubView(); + void addPathgridSubView(); + void toggleShowStatusBar (bool show); void loadErrorLog(); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 2b46eecd2..4229ab531 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -82,7 +82,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_EnchantmentType, CSMWorld::Columns::ColumnId_EnchantmentType, false }, { CSMWorld::ColumnBase::Display_BodyPartType, CSMWorld::Columns::ColumnId_BodyPartType, false }, { CSMWorld::ColumnBase::Display_MeshType, CSMWorld::Columns::ColumnId_MeshType, false }, - { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true } + { CSMWorld::ColumnBase::Display_Gender, CSMWorld::Columns::ColumnId_Gender, true }, + { CSMWorld::ColumnBase::Display_SoundGeneratorType, CSMWorld::Columns::ColumnId_SoundGeneratorType, false }, + { CSMWorld::ColumnBase::Display_School, CSMWorld::Columns::ColumnId_School, true } }; for (std::size_t i=0; i); + manager.add (CSMWorld::UniversalId::Type_MagicEffects, + new CSVDoc::SubViewFactoryWithCreator); + static const CSMWorld::UniversalId::Type sTableTypes[] = { CSMWorld::UniversalId::Type_Globals, @@ -38,6 +41,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Spells, CSMWorld::UniversalId::Type_Enchantments, CSMWorld::UniversalId::Type_BodyParts, + CSMWorld::UniversalId::Type_SoundGens, + CSMWorld::UniversalId::Type_Pathgrids, CSMWorld::UniversalId::Type_None // end marker }; @@ -116,6 +121,8 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_Faction, CSMWorld::UniversalId::Type_Enchantment, CSMWorld::UniversalId::Type_BodyPart, + CSMWorld::UniversalId::Type_SoundGen, + CSMWorld::UniversalId::Type_Pathgrid, CSMWorld::UniversalId::Type_None // end marker }; @@ -128,6 +135,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Skill, new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add (CSMWorld::UniversalId::Type_MagicEffect, + new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add (CSMWorld::UniversalId::Type_Gmst, new CSVDoc::SubViewFactoryWithCreator (false)); diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 7aac65bd3..58f23c175 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -34,7 +34,7 @@ namespace MWGui , mSourceModel(NULL) , mSourceView(NULL) , mSourceSortModel(NULL) - , mIsOnDragAndDrop(NULL) + , mIsOnDragAndDrop(false) { } diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index b41a374b6..ca68d907a 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -74,8 +74,6 @@ namespace MWGui MyGUI::TextBox* mWeaponSpellBox; MyGUI::Widget *mDrowningFrame, *mDrowningFlash; - MyGUI::Widget* mDummy; - MyGUI::Widget* mFpsBox; MyGUI::TextBox* mFpsCounter; MyGUI::TextBox* mTriangleCounter; diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 2786f6bd3..d1eeba157 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -39,6 +39,8 @@ namespace MWGui , mPreviewDirty(true) , mPreviewResize(true) , mDragAndDrop(dragAndDrop) + , mSortModel(NULL) + , mTradeModel(NULL) , mSelectedItem(-1) , mGuiMode(GM_Inventory) { diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 81b082568..bb003c481 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -29,6 +29,7 @@ namespace MWGui , mButtonBox(0), mWidth (w), mHeight (h) , mSaveGameDialog(NULL) , mBackground(NULL) + , mVideoBackground(NULL) , mVideo(NULL) { getWidget(mVersionText, "VersionText"); @@ -43,7 +44,7 @@ namespace MWGui rev = rev.substr(0,10); sstream << "\nRevision: " << rev; } - + std::string output = sstream.str(); mVersionText->setCaption(output); diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index e2fac9d6d..00cab6c45 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -447,8 +447,12 @@ namespace MWGui EffectEditorBase::EffectEditorBase(Type type) : mAddEffectDialog() + , mAvailableEffectsList(NULL) + , mUsedEffectsView(NULL) , mSelectAttributeDialog(NULL) , mSelectSkillDialog(NULL) + , mSelectedEffect(0) + , mSelectedKnownEffectId(0) , mType(type) { mAddEffectDialog.eventEffectAdded += MyGUI::newDelegate(this, &EffectEditorBase::onEffectAdded); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 1dae77641..d473988f9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -79,7 +79,6 @@ namespace MWGui class SpellCreationDialog; class EnchantingDialog; class TrainingWindow; - class Cursor; class SpellIcons; class MerchantRepair; class Repair; @@ -392,7 +391,6 @@ namespace MWGui DebugWindow* mDebugWindow; Translation::Storage& mTranslationDataStorage; - Cursor* mSoftwareCursor; CharacterCreation* mCharGen; diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 92a49acc0..2693d68b2 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -19,14 +19,14 @@ using namespace Ogre; OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0), - mDoQuery(0), mSunVisibility(0), + mBBQueryVisible(0), mBBQueryTotal(0), mSunNode(sunNode), mBBNodeReal(0), + mSunVisibility(0), mWasVisible(false), mActive(false), - mFirstFrame(true) + mFirstFrame(true), + mDoQuery(0), + mRendering(renderer) { - mRendering = renderer; - mSunNode = sunNode; - try { RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 596c6697a..5a6ccaca6 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -20,10 +20,9 @@ using namespace Ogre; using namespace MWRender; Shadows::Shadows(OEngine::Render::OgreRenderer* rend) : + mRendering(rend), mSceneMgr(rend->getScene()), mPSSMSetup(NULL), mShadowFar(1000), mFadeStart(0.9) { - mRendering = rend; - mSceneMgr = mRendering->getScene(); recreate(); } diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 8e7bd3d89..ccef74efb 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -69,6 +69,7 @@ BillboardObject::BillboardObject( const String& textureName, } BillboardObject::BillboardObject() +: mNode(NULL), mMaterial(NULL), mEntity(NULL) { } @@ -222,6 +223,7 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) , mCloudOpacity(0.0f) , mCloudSpeed(0.0f) , mStarsOpacity(0.0f) + , mLightning(NULL) , mRemainingTransitionTime(0.0f) , mGlareFade(0.0f) , mGlare(0.0f) diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 9a442387b..107db68b1 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -590,6 +590,7 @@ namespace MWWorld typedef SharedIterator iterator; Store() + : mEsmStore(NULL) {} const ESM::Cell *search(const std::string &id) const { diff --git a/components/compiler/fileparser.cpp b/components/compiler/fileparser.cpp index e90e9a8f6..37ad1f258 100644 --- a/components/compiler/fileparser.cpp +++ b/components/compiler/fileparser.cpp @@ -65,6 +65,7 @@ namespace Compiler if (mState==BeginState && keyword==Scanner::K_begin) { mState = NameState; + scanner.allowNameStartingwithDigit(); return true; } diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index dd8fb431b..e73477ee7 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -48,6 +48,9 @@ namespace Compiler bool Scanner::scanToken (Parser& parser) { + bool allowDigit = mNameStartingWithDigit; + mNameStartingWithDigit = false; + switch (mPutback) { case Putback_Special: @@ -112,6 +115,7 @@ namespace Compiler else if (isWhitespace (c)) { mLoc.mLiteral.clear(); + mNameStartingWithDigit = allowDigit; return true; } else if (c==':') @@ -120,21 +124,21 @@ namespace Compiler mLoc.mLiteral.clear(); return true; } - else if (std::isdigit (c)) + else if (std::isalpha (c) || c=='_' || c=='"' || (allowDigit && std::isdigit (c))) { bool cont = false; - if (scanInt (c, parser, cont)) + if (scanName (c, parser, cont)) { mLoc.mLiteral.clear(); return cont; } } - else if (std::isalpha (c) || c=='_' || c=='"') + else if (std::isdigit (c)) { bool cont = false; - if (scanName (c, parser, cont)) + if (scanInt (c, parser, cont)) { mLoc.mLiteral.clear(); return cont; @@ -516,7 +520,8 @@ namespace Compiler Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream, const Extensions *extensions) : mErrorHandler (errorHandler), mStream (inputStream), mExtensions (extensions), - mPutback (Putback_None), mPutbackCode(0), mPutbackInteger(0), mPutbackFloat(0) + mPutback (Putback_None), mPutbackCode(0), mPutbackInteger(0), mPutbackFloat(0), + mNameStartingWithDigit (false) { } @@ -568,4 +573,9 @@ namespace Compiler if (mExtensions) mExtensions->listKeywords (keywords); } + + void Scanner::allowNameStartingwithDigit() + { + mNameStartingWithDigit = true; + } } diff --git a/components/compiler/scanner.hpp b/components/compiler/scanner.hpp index 7f6609f76..349a8afb6 100644 --- a/components/compiler/scanner.hpp +++ b/components/compiler/scanner.hpp @@ -37,6 +37,7 @@ namespace Compiler float mPutbackFloat; std::string mPutbackName; TokenLoc mPutbackLoc; + bool mNameStartingWithDigit; public: @@ -122,6 +123,9 @@ namespace Compiler void listKeywords (std::vector& keywords); ///< Append all known keywords to \a kaywords. + + /// For the next token allow names to start with a digit. + void allowNameStartingwithDigit(); }; } diff --git a/components/esm/loadmgef.cpp b/components/esm/loadmgef.cpp index 04d55c828..cbdca3e31 100644 --- a/components/esm/loadmgef.cpp +++ b/components/esm/loadmgef.cpp @@ -1,6 +1,7 @@ #include "loadmgef.hpp" #include +#include #include @@ -10,6 +11,157 @@ namespace { + static const char *sIds[ESM::MagicEffect::Length] = + { + "WaterBreathing", + "SwiftSwim", + "WaterWalking", + "Shield", + "FireShield", + "LightningShield", + "FrostShield", + "Burden", + "Feather", + "Jump", + "Levitate", + "SlowFall", + "Lock", + "Open", + "FireDamage", + "ShockDamage", + "FrostDamage", + "DrainAttribute", + "DrainHealth", + "DrainMagicka", + "DrainFatigue", + "DrainSkill", + "DamageAttribute", + "DamageHealth", + "DamageMagicka", + "DamageFatigue", + "DamageSkill", + "Poison", + "WeaknessToFire", + "WeaknessToFrost", + "WeaknessToShock", + "WeaknessToMagicka", + "WeaknessToCommonDisease", + "WeaknessToBlightDisease", + "WeaknessToCorprusDisease", + "WeaknessToPoison", + "WeaknessToNormalWeapons", + "DisintegrateWeapon", + "DisintegrateArmor", + "Invisibility", + "Chameleon", + "Light", + "Sanctuary", + "NightEye", + "Charm", + "Paralyze", + "Silence", + "Blind", + "Sound", + "CalmHumanoid", + "CalmCreature", + "FrenzyHumanoid", + "FrenzyCreature", + "DemoralizeHumanoid", + "DemoralizeCreature", + "RallyHumanoid", + "RallyCreature", + "Dispel", + "Soultrap", + "Telekinesis", + "Mark", + "Recall", + "DivineIntervention", + "AlmsiviIntervention", + "DetectAnimal", + "DetectEnchantment", + "DetectKey", + "SpellAbsorption", + "Reflect", + "CureCommonDisease", + "CureBlightDisease", + "CureCorprusDisease", + "CurePoison", + "CureParalyzation", + "RestoreAttribute", + "RestoreHealth", + "RestoreMagicka", + "RestoreFatigue", + "RestoreSkill", + "FortifyAttribute", + "FortifyHealth", + "FortifyMagicka", + "FortifyFatigue", + "FortifySkill", + "FortifyMaximumMagicka", + "AbsorbAttribute", + "AbsorbHealth", + "AbsorbMagicka", + "AbsorbFatigue", + "AbsorbSkill", + "ResistFire", + "ResistFrost", + "ResistShock", + "ResistMagicka", + "ResistCommonDisease", + "ResistBlightDisease", + "ResistCorprusDisease", + "ResistPoison", + "ResistNormalWeapons", + "ResistParalysis", + "RemoveCurse", + "TurnUndead", + "SummonScamp", + "SummonClannfear", + "SummonDaedroth", + "SummonDremora", + "SummonAncestralGhost", + "SummonSkeletalMinion", + "SummonBonewalker", + "SummonGreaterBonewalker", + "SummonBonelord", + "SummonWingedTwilight", + "SummonHunger", + "SummonGoldenSaint", + "SummonFlameAtronach", + "SummonFrostAtronach", + "SummonStormAtronach", + "FortifyAttack", + "CommandCreature", + "CommandHumanoid", + "BoundDagger", + "BoundLongsword", + "BoundMace", + "BoundBattleAxe", + "BoundSpear", + "BoundLongbow", + "ExtraSpell", + "BoundCuirass", + "BoundHelm", + "BoundBoots", + "BoundShield", + "BoundGloves", + "Corprus", + "Vampirism", + "SummonCenturionSphere", + "SunDamage", + "StuntedMagicka", + + // Tribunal only + "SummonFabricant", + + // Bloodmoon only + "SummonWolf", + "SummonBear", + "SummonBonewolf", + "SummonCreature04", + "SummonCreature05" + }; + const int NumberOfHardcodedFlags = 143; const int HardcodedFlags[NumberOfHardcodedFlags] = { 0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0, 0x11d0, @@ -41,6 +193,8 @@ void MagicEffect::load(ESMReader &esm) { esm.getHNT(mIndex, "INDX"); + mId = indexToId (mIndex); + esm.getHNT(mData, "MEDT", 36); if (esm.getFormat() == 0) { @@ -388,4 +542,51 @@ MagicEffect::MagnitudeDisplayType MagicEffect::getMagnitudeDisplayType() const { return MDT_Points; } + void MagicEffect::blank() + { + mData.mSchool = 0; + mData.mBaseCost = 0; + mData.mFlags = 0; + mData.mRed = 0; + mData.mGreen = 0; + mData.mBlue = 0; + mData.mSpeed = 0; + + mIcon.clear(); + mParticle.clear(); + mCasting.clear(); + mHit.clear(); + mArea.clear(); + mBolt.clear(); + mCastSound.clear(); + mBoltSound.clear(); + mHitSound.clear(); + mAreaSound.clear(); + mDescription.clear(); + } + + std::string MagicEffect::indexToId (int index) + { + std::ostringstream stream; + + if (index!=-1) + { + stream << "#"; + + if (index<100) + { + stream << "0"; + + if (index<10) + stream << "0"; + } + + stream << index; + + if (index>=0 && index Date: Sun, 12 Oct 2014 21:15:50 +1100 Subject: [PATCH 41/63] Various fixes as per feedback comments. --- CMakeLists.txt | 3 +- .../view/render/pagedworldspacewidget.cpp | 49 ++++++------ apps/opencs/view/render/scenewidget.cpp | 14 ++-- apps/opencs/view/render/scenewidget.hpp | 2 +- apps/opencs/view/render/textoverlay.cpp | 74 ++++++++++--------- apps/opencs/view/render/textoverlay.hpp | 3 +- cmake/FindOGRE.cmake | 3 + 7 files changed, 79 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c1ebc524..fc7cb3c98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,7 +272,8 @@ endif () endif(OGRE_STATIC) include_directories("." - ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR}/Overlay + ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} + ${OGRE_INCLUDE_DIR}/Ogre/Overlay ${OGRE_INCLUDE_DIR}/OGRE/Overlay ${OGRE_Overlay_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 4514aa57e..b58100a08 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -8,13 +8,13 @@ #include #include #include -#include -#include +#include +#include #include #include #include -#include "../../../../components/esm/loadland.hpp" +#include #include "textoverlay.hpp" #include "../../model/world/tablemimedata.hpp" @@ -195,24 +195,13 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event void CSVRender::PagedWorldspaceWidget::updateOverlay() { - Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); - Ogre::Overlay* overlay = overlayMgr.getByName("CellIDPanel"); - if(overlay && !mTextOverlays.empty()) + if(getCamera()->getViewport()) { - if(getCamera()->getViewport()) - { - if((uint32_t)getCamera()->getViewport()->getVisibilityMask() - & (uint32_t)CSVRender::Element_CellMarker) - { - mDisplayCellCoord = true; - overlay->show(); - } - else - { - mDisplayCellCoord = false; - overlay->hide(); - } - } + if((uint32_t)getCamera()->getViewport()->getVisibilityMask() + & (uint32_t)CSVRender::Element_CellMarker) + mDisplayCellCoord = true; + else + mDisplayCellCoord = false; } if(!mTextOverlays.empty()) @@ -220,6 +209,7 @@ void CSVRender::PagedWorldspaceWidget::updateOverlay() std::map::iterator it = mTextOverlays.begin(); for(; it != mTextOverlays.end(); ++it) { + it->second->enable(mDisplayCellCoord); it->second->update(); } } @@ -324,14 +314,21 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { delete iter->second; - std::map::iterator it = mEntities.find(iter->first); - if(it != mEntities.end()) - { - getSceneManager()->destroyEntity(it->second); - mEntities.erase(it); - } getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); } + + for (std::map::iterator iter (mEntities.begin()); + iter != mEntities.end(); ++iter) + { + getSceneManager()->destroyEntity(iter->second); + mEntities.erase(iter); + } + + for (std::map::iterator iter (mTextOverlays.begin()); + iter != mTextOverlays.end(); ++iter) + { + delete iter->second; + } } void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 42d3ae36a..15471d655 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" @@ -21,6 +21,8 @@ namespace CSVRender { + Ogre::OverlaySystem *SceneWidget::mOverlaySystem = NULL; + SceneWidget::SceneWidget(QWidget *parent) : QWidget(parent) , mCamera(NULL) @@ -60,7 +62,8 @@ namespace CSVRender setLighting (&mLightingDay); - Ogre::OverlaySystem *mOverlaySystem = new Ogre::OverlaySystem(); + if(!mOverlaySystem) + mOverlaySystem = new Ogre::OverlaySystem(); mSceneMgr->addRenderQueueListener(mOverlaySystem); QTimer *timer = new QTimer (this); @@ -164,11 +167,8 @@ namespace CSVRender if (mWindow) Ogre::Root::getSingleton().destroyRenderTarget (mWindow); - if (mOverlaySystem) - { - if (mSceneMgr) - mSceneMgr->removeRenderQueueListener (mOverlaySystem); - } + if (mSceneMgr) + mSceneMgr->removeRenderQueueListener (mOverlaySystem); if (mSceneMgr) Ogre::Root::getSingleton().destroySceneManager (mSceneMgr); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 05d5c7621..07804007a 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -90,7 +90,7 @@ namespace CSVRender Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; - Ogre::OverlaySystem *mOverlaySystem; + static Ogre::OverlaySystem *mOverlaySystem; Navigation *mNavigation; Lighting *mLighting; diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 117a57193..d26dda507 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -4,10 +4,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include @@ -27,18 +27,19 @@ namespace CSVRender // http://www.ogre3d.org/tikiwiki/Creating+dynamic+textures // http://www.ogre3d.org/tikiwiki/ManualObject TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String& id) - : mOverlay(0), mCaption(""), mDesc(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id), mOnScreen(false) - , mFontHeight(16) // FIXME: make font height configurable + : mOverlay(0), mCaption(""), mDesc(""), mEnabled(true), mCamera(camera), mObj(obj), mId(id) + , mOnScreen(false) , mInstance(0), mFontHeight(16) // FIXME: make font height configurable { if(id == "" || !camera || !obj) throw std::runtime_error("TextOverlay could not be created."); // setup font - if (Ogre::FontManager::getSingleton().resourceExists("DejaVuLGC")) - mFont = Ogre::FontManager::getSingleton().getByName("DejaVuLGC","General"); + Ogre::FontManager &fontMgr = Ogre::FontManager::getSingleton(); + if (fontMgr.resourceExists("DejaVuLGC")) + mFont = fontMgr.getByName("DejaVuLGC","General"); else { - mFont = Ogre::FontManager::getSingleton().create("DejaVuLGC","General"); + mFont = fontMgr.create("DejaVuLGC","General"); mFont->setType(Ogre::FT_TRUETYPE); mFont->setSource("DejaVuLGCSansMono.ttf"); mFont->setTrueTypeSize(mFontHeight); @@ -51,9 +52,13 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam // setup overlay Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); - mOverlay = overlayMgr.getByName("CellIDPanel"); - if(!mOverlay) - mOverlay = overlayMgr.create("CellIDPanel"); + mOverlay = overlayMgr.getByName("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance)); + while(mOverlay != NULL) + { + mInstance++; + mOverlay = overlayMgr.getByName("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance)); + } + mOverlay = overlayMgr.create("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance)); // create texture Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("DynamicTransBlue"); @@ -93,24 +98,32 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam } // setup material for containers - Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().create("TransOverlayMaterial", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true ); - Ogre::Pass *pass = mQuadMaterial->getTechnique( 0 )->getPass( 0 ); - pass->setLightingEnabled( false ); - pass->setDepthWriteEnabled( false ); - pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA ); + Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().getByName( + "TransOverlayMaterial"); + if(mQuadMaterial.isNull()) + { + Ogre::MaterialPtr mQuadMaterial = Ogre::MaterialManager::getSingleton().create( + "TransOverlayMaterial", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true ); + Ogre::Pass *pass = mQuadMaterial->getTechnique( 0 )->getPass( 0 ); + pass->setLightingEnabled( false ); + pass->setDepthWriteEnabled( false ); + pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA ); - Ogre::TextureUnitState *tex = pass->createTextureUnitState("MyCustomState", 0); - tex->setTextureName("DynamicTransBlue"); - tex->setTextureFiltering( Ogre::TFO_ANISOTROPIC ); - mQuadMaterial->load(); + Ogre::TextureUnitState *tex = pass->createTextureUnitState("MyCustomState", 0); + tex->setTextureName("DynamicTransBlue"); + tex->setTextureFiltering( Ogre::TFO_ANISOTROPIC ); + mQuadMaterial->load(); + } - mContainer = static_cast(overlayMgr.createOverlayElement("Panel", "container"+mId)); + mContainer = static_cast(overlayMgr.createOverlayElement( + "Panel", "container"+mId +"#"+Ogre::StringConverter::toString(mInstance))); mContainer->setMaterialName("TransOverlayMaterial"); mOverlay->add2D(mContainer); // setup text area overlay element - mElement = static_cast(overlayMgr.createOverlayElement("TextArea", "text"+mId)); + mElement = static_cast(overlayMgr.createOverlayElement( + "TextArea", "text"+mId +"#"+Ogre::StringConverter::toString(mInstance))); mElement->setMetricsMode(Ogre::GMM_RELATIVE); mElement->setDimensions(1.0, 1.0); mElement->setMetricsMode(Ogre::GMM_PIXELS); @@ -197,10 +210,8 @@ TextOverlay::~TextOverlay() mOverlay->hide(); Ogre::OverlayManager *overlayMgr = Ogre::OverlayManager::getSingletonPtr(); - mContainer->removeChild("text"+mId); + mContainer->removeChild("text"+mId+"#"+Ogre::StringConverter::toString(mInstance)); mOverlay->remove2D(mContainer); - overlayMgr->destroyOverlayElement(mElement); - overlayMgr->destroyOverlayElement(mContainer); if(!iter.hasMoreElements()) overlayMgr->destroy(mOverlay); @@ -208,14 +219,14 @@ TextOverlay::~TextOverlay() void TextOverlay::enable(bool enable) { - if(enable == mContainer->isVisible()) + if(enable == mOverlay->isVisible()) return; mEnabled = enable; if (enable) - mContainer->show(); + mOverlay->show(); else - mContainer->hide(); + mOverlay->hide(); } bool TextOverlay::isEnabled() @@ -282,7 +293,6 @@ void TextOverlay::update() { mOnScreen = false; mContainer->hide(); - Ogre::Root::getSingleton().renderOneFrame(); return; } @@ -306,8 +316,6 @@ void TextOverlay::update() mContainer->setDimensions(relTextWidth, relTextHeight); mPos = QRect(posX*viewportWidth, posY*viewportHeight, width, height); - - Ogre::Root::getSingleton().renderOneFrame(); } QRect TextOverlay::container() diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 17530a010..75c5ba2ed 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace Ogre { @@ -36,6 +36,7 @@ namespace CSVRender bool mEnabled; bool mOnScreen; // not used + int mInstance; Ogre::FontPtr getFont(); int textWidth(); diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 24a26ccc7..514b25260 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -364,6 +364,9 @@ macro(ogre_find_component COMPONENT HEADER) make_library_set(OGRE_${COMPONENT}_LIBRARY) findpkg_finish(OGRE_${COMPONENT}) if (OGRE_${COMPONENT}_FOUND) + if (OGRE_${COMPONENT}_INCLUDE_DIR) + set(OGRE_${COMPONENT}_INCLUDE_DIRS ${OGRE_${COMPONENT}_INCLUDE_DIR}) + endif() # find binaries if (NOT OGRE_STATIC) if (WIN32) From 971b0de4fa939555505662ffa49461639b8cd78a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Oct 2014 21:48:49 +1100 Subject: [PATCH 42/63] An attempt to make osx to find the ogre overlay headers. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc7cb3c98..fe5b3f086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,7 @@ endif(OGRE_STATIC) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} - ${OGRE_INCLUDE_DIR}/Ogre/Overlay ${OGRE_INCLUDE_DIR}/OGRE/Overlay ${OGRE_Overlay_INCLUDE_DIRS} + ${OGRE_INCLUDE_DIR}/Ogre/Overlay ${OGRE_INCLUDE_DIR}/OGRE/Overlay ${OGRE_Overlay_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} From f459adf11782484e1d2b79efe9b592985d1f2865 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 12 Oct 2014 22:30:08 +1100 Subject: [PATCH 43/63] Revert CMake changes (didn't work for osx anyway) --- CMakeLists.txt | 2 +- cmake/FindOGRE.cmake | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe5b3f086..26bfcb5e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,7 @@ endif(OGRE_STATIC) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_INCLUDE_DIRS} ${OGRE_PLUGIN_INCLUDE_DIRS} - ${OGRE_INCLUDE_DIR}/Ogre/Overlay ${OGRE_INCLUDE_DIR}/OGRE/Overlay ${OGRE_Overlay_INCLUDE_DIR} + ${OGRE_INCLUDE_DIR}/Overlay ${OGRE_Overlay_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 514b25260..24a26ccc7 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -364,9 +364,6 @@ macro(ogre_find_component COMPONENT HEADER) make_library_set(OGRE_${COMPONENT}_LIBRARY) findpkg_finish(OGRE_${COMPONENT}) if (OGRE_${COMPONENT}_FOUND) - if (OGRE_${COMPONENT}_INCLUDE_DIR) - set(OGRE_${COMPONENT}_INCLUDE_DIRS ${OGRE_${COMPONENT}_INCLUDE_DIR}) - endif() # find binaries if (NOT OGRE_STATIC) if (WIN32) From 47c5bc9a19acb1ab65d35e4fcf8714d16e3c680b Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 07:42:43 +1100 Subject: [PATCH 44/63] Set bounding box on manual objects rather than creating meshes. --- .../view/render/pagedworldspacewidget.cpp | 34 ++++++------------- .../view/render/pagedworldspacewidget.hpp | 1 - 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index b58100a08..eed481c12 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "textoverlay.hpp" @@ -53,13 +52,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() mTextOverlays.erase(itOverlay); } - // destroy manual objects and entities - std::map::iterator itEntity = mEntities.find(iter->first); - if(itEntity != mEntities.end()) - { - getSceneManager()->destroyEntity(itEntity->second); - mEntities.erase(itEntity); - } + // destroy manual objects getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); iter++; @@ -143,16 +136,18 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, height+2000); // FIXME: config setting manual->end(); - Ogre::MeshPtr meshPtr = manual->convertToMesh("vLine" + iter->getId(mWorldspace)); - Ogre::Entity* entity = getSceneManager()->createEntity(meshPtr); - getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(entity); - entity->setVisible(false); - - // keep pointers so that they can be deleted later - mEntities.insert(std::make_pair(*iter, entity)); + manual->setBoundingBox(Ogre::AxisAlignedBox( + ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + height, + ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, + ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, + height+2000)); + getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual); + manual->setVisible(false); CSVRender::TextOverlay *textDisp = - new CSVRender::TextOverlay(entity, getCamera(), iter->getId(mWorldspace)); + new CSVRender::TextOverlay(manual, getCamera(), iter->getId(mWorldspace)); textDisp->enable(true); textDisp->setCaption(iter->getId(mWorldspace)); std::string desc = cells.getRecord(index).get().mName; @@ -317,13 +312,6 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); } - for (std::map::iterator iter (mEntities.begin()); - iter != mEntities.end(); ++iter) - { - getSceneManager()->destroyEntity(iter->second); - mEntities.erase(iter); - } - for (std::map::iterator iter (mTextOverlays.begin()); iter != mTextOverlays.end(); ++iter) { diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 611ebd04b..10b2e29b0 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -24,7 +24,6 @@ namespace CSVRender CSVWidget::SceneToolToggle *mControlElements; bool mDisplayCellCoord; std::map mTextOverlays; - std::map mEntities; private: From e58e5c2bf5903ae56d973ecf72ce2f73d623f594 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 15:57:01 +1100 Subject: [PATCH 45/63] Update overlays independently from multiple viewports. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/overlaymask.cpp | 52 +++++++++++++++++++ apps/opencs/view/render/overlaymask.hpp | 42 +++++++++++++++ .../view/render/pagedworldspacewidget.cpp | 12 ++++- .../view/render/pagedworldspacewidget.hpp | 2 + apps/opencs/view/render/scenewidget.cpp | 18 +++++++ apps/opencs/view/render/scenewidget.hpp | 9 +++- apps/opencs/view/render/textoverlay.cpp | 10 +++- apps/opencs/view/render/textoverlay.hpp | 5 +- 9 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/render/overlaymask.cpp create mode 100644 apps/opencs/view/render/overlaymask.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index eb15a953d..c14caa7f7 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -82,7 +82,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell textoverlay + lightingbright object cell textoverlay overlaymask ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/overlaymask.cpp b/apps/opencs/view/render/overlaymask.cpp new file mode 100644 index 000000000..885beeff4 --- /dev/null +++ b/apps/opencs/view/render/overlaymask.cpp @@ -0,0 +1,52 @@ +#include "overlaymask.hpp" + +#include +#include + +#include "textoverlay.hpp" +#include "../../model/world/cellcoordinates.hpp" + +namespace CSVRender +{ + +// ideas from http://www.ogre3d.org/forums/viewtopic.php?f=5&t=44828#p486334 +OverlayMask::OverlayMask(std::map &overlays, Ogre::Viewport* viewport) + : mTextOverlays(overlays), mViewport(viewport) +{ +} + +OverlayMask::~OverlayMask() +{ +} + +void OverlayMask::setViewport(Ogre::Viewport *viewport) +{ + mViewport = viewport; +} + +void OverlayMask::preViewportUpdate(const Ogre::RenderTargetViewportEvent &event) +{ + if(event.source == mViewport) + { + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); + for(Ogre::OverlayManager::OverlayMapIterator iter = overlayMgr.getOverlayIterator(); + iter.hasMoreElements();) + { + Ogre::Overlay* item = iter.getNext(); + for(Ogre::Overlay::Overlay2DElementsIterator it = item->get2DElementsIterator(); + it.hasMoreElements();) + { + Ogre::OverlayContainer* container = it.getNext(); + container->hide(); + } + } + + std::map::iterator it = mTextOverlays.begin(); + for(; it != mTextOverlays.end(); ++it) + { + it->second->show(true); + } + } +} + +} diff --git a/apps/opencs/view/render/overlaymask.hpp b/apps/opencs/view/render/overlaymask.hpp new file mode 100644 index 000000000..3a006b1d9 --- /dev/null +++ b/apps/opencs/view/render/overlaymask.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCS_VIEW_OVERLAYMASK_H +#define OPENCS_VIEW_OVERLAYMASK_H + +#include + +namespace Ogre +{ + class Viewport; + class RendertargetViewportEvent; +} + +namespace CSMWorld +{ + class CellCoordinates; +} + +namespace CSVRender +{ + class TextOverlay; + + class OverlayMask : public Ogre::RenderTargetListener + { + + std::map &mTextOverlays; + Ogre::Viewport* mViewport; + + public: + + OverlayMask(std::map &overlays, + Ogre::Viewport* viewport); + + virtual ~OverlayMask(); + + void setViewport(Ogre::Viewport *viewport); + + protected: + + virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent &event) override; + }; +} + +#endif // OPENCS_VIEW_OVERLAYMASK_H diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index eed481c12..83694bff6 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -15,6 +15,7 @@ #include #include "textoverlay.hpp" +#include "overlaymask.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/world/idtable.hpp" @@ -89,6 +90,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() it->second->setDesc(region); it->second->update(); } + modified = true; } ++iter; } @@ -155,6 +157,11 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() textDisp->setDesc(desc); // FIXME: config setting textDisp->update(); mTextOverlays.insert(std::make_pair(*iter, textDisp)); + if(!mOverlayMask) + { + mOverlayMask = new OverlayMask(mTextOverlays, getViewport()); + addRenderTargetListener(mOverlayMask); + } modified = true; } @@ -289,7 +296,7 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) : WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"), - mControlElements(NULL), mDisplayCellCoord(true) + mControlElements(NULL), mDisplayCellCoord(true), mOverlayMask(NULL) { QAbstractItemModel *cells = document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); @@ -317,6 +324,9 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { delete iter->second; } + + removeRenderTargetListener(mOverlayMask); + delete mOverlayMask; } void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index 10b2e29b0..17b6d10c5 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -12,6 +12,7 @@ namespace CSVRender { class TextOverlay; + class OverlayMask; class PagedWorldspaceWidget : public WorldspaceWidget { @@ -24,6 +25,7 @@ namespace CSVRender CSVWidget::SceneToolToggle *mControlElements; bool mDisplayCellCoord; std::map mTextOverlays; + OverlayMask *mOverlayMask; private: diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 15471d655..5e5a929ec 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -190,6 +190,24 @@ namespace CSVRender } } + void SceneWidget::addRenderTargetListener(Ogre::RenderTargetListener *listener) + { + mWindow->addListener(listener); + } + + void SceneWidget::removeRenderTargetListener(Ogre::RenderTargetListener *listener) + { + mWindow->removeListener(listener); + } + + Ogre::Viewport *SceneWidget::getViewport() + { + if (!mWindow) + updateOgreWindow(); + + return mViewport; + } + Ogre::SceneManager *SceneWidget::getSceneManager() { return mSceneMgr; diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 07804007a..f53e935f4 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -16,6 +16,7 @@ namespace Ogre class RenderWindow; class Viewport; class OverlaySystem; + class RenderTargetListener; } namespace CSVWidget @@ -51,6 +52,12 @@ namespace CSVRender void setNavigation (Navigation *navigation); ///< \attention The ownership of \a navigation is not transferred to *this. + void addRenderTargetListener(Ogre::RenderTargetListener *listener); + + void removeRenderTargetListener(Ogre::RenderTargetListener *listener); + + Ogre::Viewport *getViewport(); + Ogre::SceneManager *getSceneManager(); Ogre::Camera *getCamera(); @@ -86,7 +93,7 @@ namespace CSVRender void setLighting (Lighting *lighting); ///< \attention The ownership of \a lighting is not transferred to *this. - Ogre::Camera* mCamera; + Ogre::Camera* mCamera; Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index d26dda507..e64ff51e3 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -217,13 +217,21 @@ TextOverlay::~TextOverlay() overlayMgr->destroy(mOverlay); } +void TextOverlay::show(bool show) +{ + if(show) + mContainer->show(); + else + mContainer->hide(); +} + void TextOverlay::enable(bool enable) { if(enable == mOverlay->isVisible()) return; mEnabled = enable; - if (enable) + if(enable) mOverlay->show(); else mOverlay->hide(); diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index 75c5ba2ed..c44fd9d1f 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -49,12 +49,13 @@ namespace CSVRender TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* camera, const Ogre::String &id); virtual ~TextOverlay(); - void enable(bool enable); + void enable(bool enable); // controlled from scene widget toolbar visibility mask + void show(bool show); // for updating from render target listener bool isEnabled(); void setCaption(const Ogre::String& text); void setDesc(const Ogre::String& text); void update(); - QRect container(); + QRect container(); // for detection of mouse click on the overlay Ogre::String getCaption() { return mCaption; } // FIXME: debug Ogre::String getDesc() { return mDesc; } }; From 43838ccf019f3d30cb78344a2e56571f6a51f274 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 16:42:50 +1100 Subject: [PATCH 46/63] Remove override (c++11) --- apps/opencs/view/render/overlaymask.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/overlaymask.hpp b/apps/opencs/view/render/overlaymask.hpp index 3a006b1d9..ec050cac4 100644 --- a/apps/opencs/view/render/overlaymask.hpp +++ b/apps/opencs/view/render/overlaymask.hpp @@ -35,7 +35,7 @@ namespace CSVRender protected: - virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent &event) override; + virtual void preViewportUpdate(const Ogre::RenderTargetViewportEvent &event); }; } From f29227629a451050488b8c5a0ac9153b21fa8024 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 18:55:30 +1100 Subject: [PATCH 47/63] Experimenting with FindOGRE for osx. --- cmake/FindOGRE.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 24a26ccc7..6da396a5f 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -378,6 +378,11 @@ endmacro() # look for Paging component ogre_find_component(Paging OgrePaging.h) # look for Overlay component +if(APPLE) + ogre_find_component(OgreOverlay OgreOverlaySystem.h) +else() + ogre_find_component(Overlay OgreOverlaySystem.h) +endif() ogre_find_component(Overlay OgreOverlay.h) # look for Terrain component ogre_find_component(Terrain OgreTerrain.h) From c7e57e8d888e48c04161f8a8df359a810c8ea10e Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 18:59:15 +1100 Subject: [PATCH 48/63] Another attempt for osx build. --- cmake/FindOGRE.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 6da396a5f..6fe5f5a6d 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -379,7 +379,7 @@ endmacro() ogre_find_component(Paging OgrePaging.h) # look for Overlay component if(APPLE) - ogre_find_component(OgreOverlay OgreOverlaySystem.h) + ogre_find_component(Overlay OgreOverlay/OgreOverlaySystem.h) else() ogre_find_component(Overlay OgreOverlaySystem.h) endif() From 0171bde3633fcbcb1fd5983e463b341e7ab5fb19 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 19:15:17 +1100 Subject: [PATCH 49/63] Another variation. --- cmake/FindOGRE.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 6fe5f5a6d..7d36b6299 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -379,7 +379,7 @@ endmacro() ogre_find_component(Paging OgrePaging.h) # look for Overlay component if(APPLE) - ogre_find_component(Overlay OgreOverlay/OgreOverlaySystem.h) + ogre_find_component(Overlay Overlay/OgreOverlaySystem.h) else() ogre_find_component(Overlay OgreOverlaySystem.h) endif() From 6b9b02dc1a6a22c6d8dbee55db2bcd29c0757559 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 19:31:38 +1100 Subject: [PATCH 50/63] Giving up, revert CMake changes. --- cmake/FindOGRE.cmake | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 7d36b6299..87f4be631 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -378,11 +378,7 @@ endmacro() # look for Paging component ogre_find_component(Paging OgrePaging.h) # look for Overlay component -if(APPLE) - ogre_find_component(Overlay Overlay/OgreOverlaySystem.h) -else() - ogre_find_component(Overlay OgreOverlaySystem.h) -endif() +ogre_find_component(Overlay OgreOverlaySystem.h) ogre_find_component(Overlay OgreOverlay.h) # look for Terrain component ogre_find_component(Terrain OgreTerrain.h) From 961867e39f058addd3e0411eb0cf7f7d57960fc5 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Mon, 13 Oct 2014 20:58:07 +1100 Subject: [PATCH 51/63] Hide overlay if off screen. --- apps/opencs/view/render/textoverlay.cpp | 2 +- apps/opencs/view/render/textoverlay.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index e64ff51e3..8e28ec1b5 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -219,7 +219,7 @@ TextOverlay::~TextOverlay() void TextOverlay::show(bool show) { - if(show) + if(show && mOnScreen) mContainer->show(); else mContainer->hide(); diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index c44fd9d1f..c9620b435 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -35,7 +35,7 @@ namespace CSVRender QRect mPos; bool mEnabled; - bool mOnScreen; // not used + bool mOnScreen; int mInstance; Ogre::FontPtr getFont(); From 57b337d36874490c7ca064ac5a9cc622e5211795 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 14 Oct 2014 11:43:56 +1100 Subject: [PATCH 52/63] Fix corruption issue when the initial scenewidget is closed before subsequent ones. Also place the label closer to the terrain height at the center of the cell, should reduce the perception of the label jumping around too much. --- apps/opencs/view/render/overlaymask.cpp | 2 +- apps/opencs/view/render/pagedworldspacewidget.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/overlaymask.cpp b/apps/opencs/view/render/overlaymask.cpp index 885beeff4..09f020354 100644 --- a/apps/opencs/view/render/overlaymask.cpp +++ b/apps/opencs/view/render/overlaymask.cpp @@ -37,7 +37,7 @@ void OverlayMask::preViewportUpdate(const Ogre::RenderTargetViewportEvent &event it.hasMoreElements();) { Ogre::OverlayContainer* container = it.getNext(); - container->hide(); + if(container) container->hide(); } } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 83694bff6..26781bfd9 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -136,7 +136,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() height); manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, - height+2000); // FIXME: config setting + height+20); // FIXME: config setting manual->end(); manual->setBoundingBox(Ogre::AxisAlignedBox( ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, @@ -144,7 +144,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() height, ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, - height+2000)); + height+20)); getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual); manual->setVisible(false); From 994420aa5785dccc7517207b4a0c27121b2a0310 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 14 Oct 2014 13:21:43 +1100 Subject: [PATCH 53/63] Singleton wrapper for Ogre OverlaySystem. --- apps/opencs/view/render/overlaysystem.hpp | 36 +++++++++++++++++++++++ apps/opencs/view/render/scenewidget.cpp | 7 ++--- apps/opencs/view/render/scenewidget.hpp | 2 +- 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/render/overlaysystem.hpp diff --git a/apps/opencs/view/render/overlaysystem.hpp b/apps/opencs/view/render/overlaysystem.hpp new file mode 100644 index 000000000..64f95975e --- /dev/null +++ b/apps/opencs/view/render/overlaysystem.hpp @@ -0,0 +1,36 @@ +#ifndef OPENCS_VIEW_OVERLAYSYSTEM_H +#define OPENCS_VIEW_OVERLAYSYSTEM_H + +#include + +namespace CSVRender +{ + class OverlaySystem + { + Ogre::OverlaySystem *mOverlaySystem; + + OverlaySystem() { + mOverlaySystem = new Ogre::OverlaySystem(); + } + + ~OverlaySystem() { + delete mOverlaySystem; + } + + OverlaySystem(OverlaySystem const&); + void operator=(OverlaySystem const&); + + public: + + static OverlaySystem &instance() { + static OverlaySystem mInstance; + return mInstance; + } + + Ogre::OverlaySystem *get() { + return mOverlaySystem; + } + }; +} + +#endif // OPENCS_VIEW_OVERLAYSYSTEM_H diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5e5a929ec..2c0893ce0 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,18 +11,16 @@ #include #include #include -#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" #include "navigation.hpp" #include "lighting.hpp" +#include "overlaysystem.hpp" namespace CSVRender { - Ogre::OverlaySystem *SceneWidget::mOverlaySystem = NULL; - SceneWidget::SceneWidget(QWidget *parent) : QWidget(parent) , mCamera(NULL) @@ -62,8 +60,7 @@ namespace CSVRender setLighting (&mLightingDay); - if(!mOverlaySystem) - mOverlaySystem = new Ogre::OverlaySystem(); + mOverlaySystem = OverlaySystem::instance().get(); mSceneMgr->addRenderQueueListener(mOverlaySystem); QTimer *timer = new QTimer (this); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index f53e935f4..1adbf3f17 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -97,7 +97,7 @@ namespace CSVRender Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Ogre::Viewport *mViewport; - static Ogre::OverlaySystem *mOverlaySystem; + Ogre::OverlaySystem *mOverlaySystem; Navigation *mNavigation; Lighting *mLighting; From 8cebfc411b3452102083f7fc8db3ab129573b5f2 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Tue, 14 Oct 2014 17:34:10 +1100 Subject: [PATCH 54/63] Minor visual improvements. --- .../view/render/pagedworldspacewidget.cpp | 4 +- apps/opencs/view/render/textoverlay.cpp | 59 +++++++++++++------ apps/opencs/view/render/textoverlay.hpp | 3 +- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 26781bfd9..d1f259402 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -136,7 +136,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() height); manual-> position(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, - height+20); // FIXME: config setting + height+200); // FIXME: config setting manual->end(); manual->setBoundingBox(Ogre::AxisAlignedBox( ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, @@ -144,7 +144,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() height, ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2, ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, - height+20)); + height+200)); getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual); manual->setVisible(false); diff --git a/apps/opencs/view/render/textoverlay.cpp b/apps/opencs/view/render/textoverlay.cpp index 8e28ec1b5..12831be9a 100644 --- a/apps/opencs/view/render/textoverlay.cpp +++ b/apps/opencs/view/render/textoverlay.cpp @@ -53,6 +53,7 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam // setup overlay Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); mOverlay = overlayMgr.getByName("CellIDPanel"+mId+Ogre::StringConverter::toString(mInstance)); + // FIXME: this logic is badly broken as it is possible to delete an earlier instance while(mOverlay != NULL) { mInstance++; @@ -147,35 +148,47 @@ void TextOverlay::getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real y = ((hcsPosition.y * 0.5f) + 0.5f); // 0 <= y <= 1 // bottom := 0,top := 1 } -void TextOverlay::getMinMaxEdgesOfTopAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY) +void TextOverlay::getMinMaxEdgesOfAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY, + bool top) { MinX = 0, MinY = 0, MaxX = 0, MaxY = 0; float X[4]; // the 2D dots of the AABB in screencoordinates float Y[4]; - if (!mObj->isInScene()) + if(!mObj->isInScene()) return; const Ogre::AxisAlignedBox &AABB = mObj->getWorldBoundingBox(true); // the AABB of the target - const Ogre::Vector3 CornersOfTopAABB[4] = { AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_TOP), - AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_TOP), - AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_TOP), - AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_TOP)}; + Ogre::Vector3 cornersOfAABB[4]; + if(top) + { + cornersOfAABB[0] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_TOP); + cornersOfAABB[1] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_TOP); + cornersOfAABB[2] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_TOP); + cornersOfAABB[3] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_TOP); + } + else + { + cornersOfAABB[0] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_LEFT_BOTTOM); + cornersOfAABB[1] = AABB.getCorner(Ogre::AxisAlignedBox::FAR_RIGHT_BOTTOM); + cornersOfAABB[2] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_LEFT_BOTTOM); + cornersOfAABB[3] = AABB.getCorner(Ogre::AxisAlignedBox::NEAR_RIGHT_BOTTOM); + } - //The normal vector of the plaine.this points directly infront of the cam - Ogre::Vector3 CameraPlainNormal = mCamera->getDerivedOrientation().zAxis(); + //The normal vector of the plane. This points directly infront of the camera. + Ogre::Vector3 cameraPlainNormal = mCamera->getDerivedOrientation().zAxis(); - //the plaine that devides the space bevor and behin the cam - Ogre::Plane CameraPlain = Ogre::Plane(CameraPlainNormal, mCamera->getDerivedPosition()); + //the plane that devides the space before and behind the camera. + Ogre::Plane CameraPlane = Ogre::Plane(cameraPlainNormal, mCamera->getDerivedPosition()); for (int i = 0; i < 4; i++) { X[i] = 0; Y[i] = 0; - getScreenCoordinates(CornersOfTopAABB[i],X[i],Y[i]); // transfor into 2d dots + getScreenCoordinates(cornersOfAABB[i],X[i],Y[i]); // transfor into 2d dots - if (CameraPlain.getSide(CornersOfTopAABB[i]) == Ogre::Plane::NEGATIVE_SIDE) + if (CameraPlane.getSide(cornersOfAABB[i]) == Ogre::Plane::NEGATIVE_SIDE) { if (i == 0) // accept the first set of values, no matter how bad it might be. { @@ -270,11 +283,21 @@ int TextOverlay::textWidth() float captionWidth = 0; float descWidth = 0; - // NOTE: assumed fixed width font, i.e. no compensation for narrow glyphs for(Ogre::String::const_iterator i = mCaption.begin(); i < mCaption.end(); ++i) - captionWidth += getFont()->getGlyphAspectRatio(*i); + { + if(*i == 0x0020) + captionWidth += getFont()->getGlyphAspectRatio(0x0030); + else + captionWidth += getFont()->getGlyphAspectRatio(*i); + } + for(Ogre::String::const_iterator i = mDesc.begin(); i < mDesc.end(); ++i) - descWidth += getFont()->getGlyphAspectRatio(*i); + { + if(*i == 0x0020) + descWidth += getFont()->getGlyphAspectRatio(0x0030); + else + descWidth += getFont()->getGlyphAspectRatio(*i); + } captionWidth *= fontHeight(); descWidth *= fontHeight(); @@ -290,7 +313,7 @@ int TextOverlay::fontHeight() void TextOverlay::update() { float min_x, max_x, min_y, max_y; - getMinMaxEdgesOfTopAABBIn2D(min_x, min_y, max_x, max_y); + getMinMaxEdgesOfAABBIn2D(min_x, min_y, max_x, max_y, false); if ((min_x>0.0) && (max_x<1.0) && (min_y>0.0) && (max_y<1.0)) { @@ -304,11 +327,13 @@ void TextOverlay::update() return; } + getMinMaxEdgesOfAABBIn2D(min_x, min_y, max_x, max_y); + Ogre::OverlayManager &overlayMgr = Ogre::OverlayManager::getSingleton(); float viewportWidth = std::max(overlayMgr.getViewportWidth(), 1); // zero at the start float viewportHeight = std::max(overlayMgr.getViewportHeight(), 1); // zero at the start - int width = fontHeight()/3 + textWidth() + fontHeight()/3; + int width = fontHeight()*2/3 + textWidth() + fontHeight()*2/3; // add margins int height = fontHeight()/3 + fontHeight() + fontHeight()/3; if(mDesc != "") height = fontHeight()/3 + 2*fontHeight() + fontHeight()/3; diff --git a/apps/opencs/view/render/textoverlay.hpp b/apps/opencs/view/render/textoverlay.hpp index c9620b435..dbb347e56 100644 --- a/apps/opencs/view/render/textoverlay.hpp +++ b/apps/opencs/view/render/textoverlay.hpp @@ -42,7 +42,8 @@ namespace CSVRender int textWidth(); int fontHeight(); void getScreenCoordinates(const Ogre::Vector3& position, Ogre::Real& x, Ogre::Real& y); - void getMinMaxEdgesOfTopAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY); + void getMinMaxEdgesOfAABBIn2D(float& MinX, float& MinY, float& MaxX, float& MaxY, + bool top = true); public: From 1d0ac3b4df9b0e71f63020755457a78b24a13f9a Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 15 Oct 2014 07:02:19 +1100 Subject: [PATCH 55/63] Delete Ogre::OverlaySystem before Ogre::Root --- apps/opencs/editor.cpp | 6 ++++++ apps/opencs/editor.hpp | 1 + apps/opencs/view/render/overlaysystem.hpp | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 63406cb86..8007207aa 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -18,6 +18,7 @@ #include "model/doc/document.hpp" #include "model/world/data.hpp" +#include "view/render/overlaysystem.hpp" CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), @@ -65,6 +66,11 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) this, SLOT (createNewGame (const boost::filesystem::path&))); } +CS::Editor::~Editor () +{ + CSVRender::OverlaySystem::instance().destroy(); // destruct before Ogre::Root +} + void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) { for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index c87e24e77..88479f68c 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -64,6 +64,7 @@ namespace CS public: Editor (OgreInit::OgreInit& ogreInit); + ~Editor (); bool makeIPCServer(); void connectToIPCServer(); diff --git a/apps/opencs/view/render/overlaysystem.hpp b/apps/opencs/view/render/overlaysystem.hpp index 64f95975e..087d414ff 100644 --- a/apps/opencs/view/render/overlaysystem.hpp +++ b/apps/opencs/view/render/overlaysystem.hpp @@ -14,7 +14,7 @@ namespace CSVRender } ~OverlaySystem() { - delete mOverlaySystem; + if(mOverlaySystem) delete mOverlaySystem; } OverlaySystem(OverlaySystem const&); @@ -30,6 +30,11 @@ namespace CSVRender Ogre::OverlaySystem *get() { return mOverlaySystem; } + + void destroy() { + delete mOverlaySystem; + mOverlaySystem = NULL; + } }; } From 142a825ad6c4b1ac1f9bc32f1373fd0c7f52fa12 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 15 Oct 2014 09:51:20 +1100 Subject: [PATCH 56/63] For OSX support. --- cmake/FindOGRE.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 87f4be631..6d8d70b3d 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -356,7 +356,7 @@ set(OGRE_COMPONENT_SEARCH_PATH_DBG macro(ogre_find_component COMPONENT HEADER) findpkg_begin(OGRE_${COMPONENT}) - find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${COMPONENT} OGRE/${COMPONENT} Components/${COMPONENT}/include) + find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR}/Ogre${COMPONENT} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${COMPONENT} OGRE/${COMPONENT} Components/${COMPONENT}/include) set(OGRE_${COMPONENT}_LIBRARY_NAMES "Ogre${COMPONENT}${OGRE_LIB_SUFFIX}") get_debug_names(OGRE_${COMPONENT}_LIBRARY_NAMES) find_library(OGRE_${COMPONENT}_LIBRARY_REL NAMES ${OGRE_${COMPONENT}_LIBRARY_NAMES} HINTS ${OGRE_LIBRARY_DIR_REL} PATH_SUFFIXES "" "release" "relwithdebinfo" "minsizerel") @@ -364,6 +364,9 @@ macro(ogre_find_component COMPONENT HEADER) make_library_set(OGRE_${COMPONENT}_LIBRARY) findpkg_finish(OGRE_${COMPONENT}) if (OGRE_${COMPONENT}_FOUND) + if (APPLE) + include_directories("${OGRE_INCLUDE_DIR}/${COMPONENT}") + endif() # find binaries if (NOT OGRE_STATIC) if (WIN32) From 5889fd5bd9c0027c91a139caa22108b876798733 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 15 Oct 2014 16:42:05 +1100 Subject: [PATCH 57/63] Try hard coding OSX paths. --- cmake/FindOGRE.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 6d8d70b3d..51589698f 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -356,7 +356,7 @@ set(OGRE_COMPONENT_SEARCH_PATH_DBG macro(ogre_find_component COMPONENT HEADER) findpkg_begin(OGRE_${COMPONENT}) - find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR}/Ogre${COMPONENT} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${COMPONENT} OGRE/${COMPONENT} Components/${COMPONENT}/include) + find_path(OGRE_${COMPONENT}_INCLUDE_DIR NAMES ${HEADER} HINTS ${OGRE_INCLUDE_DIRS} ${OGRE_INCLUDE_DIR}/OGRE/${COMPONENT} ${OGRE_PREFIX_SOURCE} PATH_SUFFIXES ${COMPONENT} OGRE/${COMPONENT} Components/${COMPONENT}/include) set(OGRE_${COMPONENT}_LIBRARY_NAMES "Ogre${COMPONENT}${OGRE_LIB_SUFFIX}") get_debug_names(OGRE_${COMPONENT}_LIBRARY_NAMES) find_library(OGRE_${COMPONENT}_LIBRARY_REL NAMES ${OGRE_${COMPONENT}_LIBRARY_NAMES} HINTS ${OGRE_LIBRARY_DIR_REL} PATH_SUFFIXES "" "release" "relwithdebinfo" "minsizerel") @@ -365,7 +365,7 @@ macro(ogre_find_component COMPONENT HEADER) findpkg_finish(OGRE_${COMPONENT}) if (OGRE_${COMPONENT}_FOUND) if (APPLE) - include_directories("${OGRE_INCLUDE_DIR}/${COMPONENT}") + include_directories("${OGRE_INCLUDE_DIR}/OGRE/${COMPONENT}") endif() # find binaries if (NOT OGRE_STATIC) From aff6f6fdb26373b6c291c069bf2f8337feaa8b62 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 15 Oct 2014 18:48:01 +1100 Subject: [PATCH 58/63] Setup OverlaySystem after Ogre::Root but before initialisation as per the API documentation. --- apps/opencs/editor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 8007207aa..a8fc6cd57 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -275,6 +275,9 @@ std::auto_ptr CS::Editor::setupGraphics() Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName(renderSystem)); + // Initialise Ogre::OverlaySystem after Ogre::Root but before initialisation + CSVRender::OverlaySystem::instance(); + Ogre::Root::getSingleton().initialise(false); // Create a hidden background window to keep resources From 094f04608718acb35e81336d82cc16c982245681 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 16 Oct 2014 07:29:46 +1100 Subject: [PATCH 59/63] Convert OverlaySystem to a OpenCS style singleton. --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/editor.cpp | 3 +- apps/opencs/editor.hpp | 2 ++ apps/opencs/view/render/overlaysystem.cpp | 40 +++++++++++++++++++++++ apps/opencs/view/render/overlaysystem.hpp | 34 ++++++------------- apps/opencs/view/render/scenewidget.cpp | 1 + 6 files changed, 55 insertions(+), 27 deletions(-) create mode 100644 apps/opencs/view/render/overlaysystem.cpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 0336f51db..e2e5aa2e5 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -82,7 +82,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight - lightingbright object cell terrainstorage textoverlay overlaymask + lightingbright object cell terrainstorage textoverlay overlaymask overlaysystem ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index a8fc6cd57..ba1cbb8fa 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -18,7 +18,6 @@ #include "model/doc/document.hpp" #include "model/world/data.hpp" -#include "view/render/overlaysystem.hpp" CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), @@ -276,7 +275,7 @@ std::auto_ptr CS::Editor::setupGraphics() Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName(renderSystem)); // Initialise Ogre::OverlaySystem after Ogre::Root but before initialisation - CSVRender::OverlaySystem::instance(); + mOverlaySystem.get(); Ogre::Root::getSingleton().initialise(false); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 88479f68c..f252748c4 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -27,6 +27,7 @@ #include "view/doc/newgame.hpp" #include "view/settings/dialog.hpp" +#include "view/render/overlaysystem.hpp" namespace OgreInit { @@ -42,6 +43,7 @@ namespace CS Nif::Cache mNifCache; Files::ConfigurationManager mCfgMgr; CSMSettings::UserSettings mUserSettings; + CSVRender::OverlaySystem mOverlaySystem; CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; diff --git a/apps/opencs/view/render/overlaysystem.cpp b/apps/opencs/view/render/overlaysystem.cpp new file mode 100644 index 000000000..d72fd35ed --- /dev/null +++ b/apps/opencs/view/render/overlaysystem.cpp @@ -0,0 +1,40 @@ +#include "overlaysystem.hpp" + +#include + +namespace CSVRender +{ + OverlaySystem *OverlaySystem::mOverlaySystemInstance = 0; + + OverlaySystem::OverlaySystem() : mOverlaySystem(NULL) + { + assert(!mOverlaySystemInstance); + mOverlaySystemInstance = this; + } + + OverlaySystem::~OverlaySystem() + { + if(mOverlaySystem) + delete mOverlaySystem; + } + + OverlaySystem &OverlaySystem::instance() + { + assert(mOverlaySystemInstance); + return *mOverlaySystemInstance; + } + + Ogre::OverlaySystem *OverlaySystem::get() + { + if(!mOverlaySystem) + mOverlaySystem = new Ogre::OverlaySystem(); + return mOverlaySystem; + } + + void OverlaySystem::destroy() + { + delete mOverlaySystem; + mOverlaySystem = NULL; + } +} + diff --git a/apps/opencs/view/render/overlaysystem.hpp b/apps/opencs/view/render/overlaysystem.hpp index 087d414ff..c9bc533c1 100644 --- a/apps/opencs/view/render/overlaysystem.hpp +++ b/apps/opencs/view/render/overlaysystem.hpp @@ -1,40 +1,26 @@ #ifndef OPENCS_VIEW_OVERLAYSYSTEM_H #define OPENCS_VIEW_OVERLAYSYSTEM_H -#include +namespace Ogre +{ + class OverlaySystem; +} namespace CSVRender { class OverlaySystem { Ogre::OverlaySystem *mOverlaySystem; - - OverlaySystem() { - mOverlaySystem = new Ogre::OverlaySystem(); - } - - ~OverlaySystem() { - if(mOverlaySystem) delete mOverlaySystem; - } - - OverlaySystem(OverlaySystem const&); - void operator=(OverlaySystem const&); + static OverlaySystem *mOverlaySystemInstance; public: - static OverlaySystem &instance() { - static OverlaySystem mInstance; - return mInstance; - } + OverlaySystem(); + ~OverlaySystem(); + static OverlaySystem &instance(); - Ogre::OverlaySystem *get() { - return mOverlaySystem; - } - - void destroy() { - delete mOverlaySystem; - mOverlaySystem = NULL; - } + Ogre::OverlaySystem *get(); + void destroy(); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 2c0893ce0..3171e0496 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../widget/scenetoolmode.hpp" #include "../../model/settings/usersettings.hpp" From 7cdab415013ee5582db00845ed66e58c3ec34fd9 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Thu, 16 Oct 2014 07:36:47 +1100 Subject: [PATCH 60/63] Don't allow viewing non-existent cells from the regionmap. --- apps/opencs/view/world/regionmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 9497e4054..822efbbd4 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -61,7 +61,7 @@ void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) menu.addAction (mViewInTableAction); } - if (selectionModel()->selectedIndexes().size()>0) + if (selectionModel()->selectedIndexes().size()>0 && selectedNonExistentCells!=1) menu.addAction (mViewAction); menu.exec (event->globalPos()); @@ -400,7 +400,7 @@ void CSVWorld::RegionMap::dropEvent (QDropEvent* event) QModelIndex index2(cellsModel->getModelIndex (cellId, cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region))); - mDocument.getUndoStack().push(new CSMWorld::ModifyCommand + mDocument.getUndoStack().push(new CSMWorld::ModifyCommand (*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); mRegionId = record.getId(); From ba46bcad40ffa8216cd31c9ea1776dbb149bf6f2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Oct 2014 13:52:21 +0200 Subject: [PATCH 61/63] Revert "Don't allow viewing non-existent cells from the regionmap." This reverts commit 7cdab415013ee5582db00845ed66e58c3ec34fd9. --- apps/opencs/view/world/regionmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 822efbbd4..9497e4054 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -61,7 +61,7 @@ void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) menu.addAction (mViewInTableAction); } - if (selectionModel()->selectedIndexes().size()>0 && selectedNonExistentCells!=1) + if (selectionModel()->selectedIndexes().size()>0) menu.addAction (mViewAction); menu.exec (event->globalPos()); @@ -400,7 +400,7 @@ void CSVWorld::RegionMap::dropEvent (QDropEvent* event) QModelIndex index2(cellsModel->getModelIndex (cellId, cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region))); - mDocument.getUndoStack().push(new CSMWorld::ModifyCommand + mDocument.getUndoStack().push(new CSMWorld::ModifyCommand (*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); mRegionId = record.getId(); From 8a05c0e5c080c16026c9fe8503a9050cce54efca Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Oct 2014 14:23:27 +0200 Subject: [PATCH 62/63] fixed overlay singleton --- apps/opencs/editor.cpp | 9 +++++---- apps/opencs/editor.hpp | 2 +- apps/opencs/view/render/overlaysystem.cpp | 16 +++++----------- apps/opencs/view/render/overlaysystem.hpp | 1 - 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index ba1cbb8fa..982fc20d5 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -20,7 +20,8 @@ #include "model/world/data.hpp" CS::Editor::Editor (OgreInit::OgreInit& ogreInit) -: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), +: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr), + mViewManager (mDocumentManager), mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) { std::pair > config = readConfig(); @@ -32,6 +33,8 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); + mOverlaySystem.reset (new CSVRender::OverlaySystem); + Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, mFsStrict); @@ -66,9 +69,7 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) } CS::Editor::~Editor () -{ - CSVRender::OverlaySystem::instance().destroy(); // destruct before Ogre::Root -} +{} void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) { diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index f252748c4..cd39d53a4 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -43,7 +43,7 @@ namespace CS Nif::Cache mNifCache; Files::ConfigurationManager mCfgMgr; CSMSettings::UserSettings mUserSettings; - CSVRender::OverlaySystem mOverlaySystem; + std::auto_ptr mOverlaySystem; CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; diff --git a/apps/opencs/view/render/overlaysystem.cpp b/apps/opencs/view/render/overlaysystem.cpp index d72fd35ed..f565f5af0 100644 --- a/apps/opencs/view/render/overlaysystem.cpp +++ b/apps/opencs/view/render/overlaysystem.cpp @@ -1,21 +1,23 @@ #include "overlaysystem.hpp" +#include + #include namespace CSVRender { OverlaySystem *OverlaySystem::mOverlaySystemInstance = 0; - OverlaySystem::OverlaySystem() : mOverlaySystem(NULL) + OverlaySystem::OverlaySystem() { assert(!mOverlaySystemInstance); mOverlaySystemInstance = this; + mOverlaySystem = new Ogre::OverlaySystem(); } OverlaySystem::~OverlaySystem() { - if(mOverlaySystem) - delete mOverlaySystem; + delete mOverlaySystem; } OverlaySystem &OverlaySystem::instance() @@ -26,15 +28,7 @@ namespace CSVRender Ogre::OverlaySystem *OverlaySystem::get() { - if(!mOverlaySystem) - mOverlaySystem = new Ogre::OverlaySystem(); return mOverlaySystem; } - - void OverlaySystem::destroy() - { - delete mOverlaySystem; - mOverlaySystem = NULL; - } } diff --git a/apps/opencs/view/render/overlaysystem.hpp b/apps/opencs/view/render/overlaysystem.hpp index c9bc533c1..f8a78f329 100644 --- a/apps/opencs/view/render/overlaysystem.hpp +++ b/apps/opencs/view/render/overlaysystem.hpp @@ -20,7 +20,6 @@ namespace CSVRender static OverlaySystem &instance(); Ogre::OverlaySystem *get(); - void destroy(); }; } From 994159fafd8834a477b04ab9b48cbc3d5f8d67bf Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Oct 2014 14:23:37 +0200 Subject: [PATCH 63/63] fixed broken iterator --- apps/opencs/view/render/pagedworldspacewidget.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d1f259402..8b143e93f 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -42,9 +42,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() if (!mSelection.has (iter->first) || index==-1 || cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted) { - delete iter->second; - mCells.erase (iter); - // delete overlays std::map::iterator itOverlay = mTextOverlays.find(iter->first); if(itOverlay != mTextOverlays.end()) @@ -56,7 +53,9 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() // destroy manual objects getSceneManager()->destroyManualObject("manual"+iter->first.getId(mWorldspace)); - iter++; + delete iter->second; + mCells.erase (iter++); + modified = true; } else