diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt index 7ef0a11bf..4681c5d8b 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/CMakeLists.txt @@ -11,6 +11,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin. SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h landscape_editor_window.h + landscape_scene_base.h landscape_scene.h list_zones_model.h list_zones_widget.h diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h index 789af03f7..d16008a5f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone.h @@ -19,6 +19,7 @@ #define BUILDER_ZONE_H // Project includes +#include "builder_zone_base.h" #include "builder_zone_region.h" #include "zone_region_editor.h" #include "pixmap_database.h" @@ -46,29 +47,6 @@ class ListZonesWidget; class LandscapeScene; class UndoScanRegionCommand; -// Data -struct ZonePosition -{ - // Absolute position - sint32 x; - sint32 y; - int region; - - ZonePosition() - { - x = 0xffffffff; - y = 0xffffffff; - region = -1; - } - - ZonePosition(const sint32 posX, const sint32 posY, const int id) - { - x = posX; - y = posY; - region = id; - } -}; - /** @class ZoneBuilder @brief ZoneBuilder contains all the shared data between the tools and the engine. diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp new file mode 100644 index 000000000..a8fc40cab --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.cpp @@ -0,0 +1,301 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "builder_zone_base.h" +#include "list_zones_widget.h" +#include "landscape_actions.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include + +namespace LandscapeEditor +{ +int NewLandId = 0; + +ZoneBuilderBase::ZoneBuilderBase(LandscapeScene *landscapeScene) + : m_currentZoneRegion(-1), + m_pixmapDatabase(0), + m_landscapeScene(landscapeScene) +{ + nlassert(m_landscapeScene); + m_pixmapDatabase = new PixmapDatabase(); + m_lastPathName = ""; +} + +ZoneBuilderBase::~ZoneBuilderBase() +{ + delete m_pixmapDatabase; +} + +bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress) +{ + if (pathName.isEmpty()) + return false; + if (pathName != m_lastPathName) + { + m_lastPathName = pathName; + QString zoneBankPath = pathName; + zoneBankPath += "/zoneligos/"; + + // Init the ZoneBank + m_zoneBank.reset(); + if (!initZoneBank (zoneBankPath)) + { + m_zoneBank.reset(); + return false; + } + // Construct the DataBase from the ZoneBank + QString zoneBitmapPath = pathName; + zoneBitmapPath += "/zonebitmaps/"; + m_pixmapDatabase->reset(); + if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress)) + { + m_zoneBank.reset(); + return false; + } + } + return true; +} + +int ZoneBuilderBase::createZoneRegion() +{ + LandscapeItem landItem; + landItem.zoneRegionObject = new ZoneRegionObject(); +// landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter); +// landItem.builderZoneRegion->init(this); + landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + + m_landscapeMap.insert(NewLandId, landItem); + if (m_currentZoneRegion == -1) + setCurrentZoneRegion(NewLandId); + + calcMask(); + return NewLandId++; +} + +int ZoneBuilderBase::createZoneRegion(const QString &fileName) +{ + LandscapeItem landItem; + landItem.zoneRegionObject = new ZoneRegionObject(); + landItem.zoneRegionObject->load(fileName.toStdString()); + + if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion())) + { + delete landItem.zoneRegionObject; + return -1; + } +// landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter); +// landItem.builderZoneRegion->init(this); + + m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion()); + landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion()); + m_landscapeMap.insert(NewLandId, landItem); + + if (m_currentZoneRegion == -1) + setCurrentZoneRegion(NewLandId); + + calcMask(); + return NewLandId++; +} + +void ZoneBuilderBase::deleteZoneRegion(int id) +{ + if (m_landscapeMap.contains(id)) + { + if (m_landscapeMap.value(id).rectItem != 0) + delete m_landscapeMap.value(id).rectItem; + m_landscapeScene->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion()); + delete m_landscapeMap.value(id).zoneRegionObject; +// delete m_landscapeMap.value(id).builderZoneRegion; + m_landscapeMap.remove(id); + calcMask(); + } + else + nlwarning("Landscape (id %i) not found", id); +} + +void ZoneBuilderBase::setCurrentZoneRegion(int id) +{ + if (m_landscapeMap.contains(id)) + { + if (currentIdZoneRegion() != -1) + { + NLLIGO::CZoneRegion &ligoRegion = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion(); + m_landscapeMap[m_currentZoneRegion].rectItem = m_landscapeScene->createLayerBlackout(ligoRegion); + } + delete m_landscapeMap.value(id).rectItem; + m_landscapeMap[id].rectItem = 0; + m_currentZoneRegion = id; + calcMask(); + } + else + nlwarning("Landscape (id %i) not found", id); +} + +int ZoneBuilderBase::currentIdZoneRegion() const +{ + return m_currentZoneRegion; +} + +ZoneRegionObject *ZoneBuilderBase::currentZoneRegion() const +{ + return m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject; +} + +int ZoneBuilderBase::countZoneRegion() const +{ + return m_landscapeMap.size(); +} + +ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const +{ + return m_landscapeMap.value(id).zoneRegionObject; +} + +void ZoneBuilderBase::ligoData(LigoData &data, const ZonePosition &zonePos) +{ + m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y); +} + +void ZoneBuilderBase::setLigoData(LigoData &data, const ZonePosition &zonePos) +{ + m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y); +} + +bool ZoneBuilderBase::initZoneBank (const QString &pathName) +{ + QDir *dir = new QDir(pathName); + QStringList filters; + filters << "*.ligozone"; + + // Find all ligozone files in dir + QStringList listFiles = dir->entryList(filters, QDir::Files); + + std::string error; + Q_FOREACH(QString file, listFiles) + { + //nlinfo(file.toStdString().c_str()); + if (!m_zoneBank.addElement((pathName + file).toStdString(), error)) + QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok); + } + delete dir; + return true; +} + +PixmapDatabase *ZoneBuilderBase::pixmapDatabase() const +{ + return m_pixmapDatabase; +} + +QString ZoneBuilderBase::dataPath() const +{ + return m_lastPathName; +} + +bool ZoneBuilderBase::getZoneMask(sint32 x, sint32 y) +{ + if ((x < m_minX) || (x > m_maxX) || + (y < m_minY) || (y > m_maxY)) + { + return true; + } + else + { + return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)]; + } +} + +void ZoneBuilderBase::calcMask() +{ + sint32 x, y; + + m_minY = m_minX = 1000000; + m_maxY = m_maxX = -1000000; + + if (m_landscapeMap.size() == 0) + return; + + QMapIterator i(m_landscapeMap); + while (i.hasNext()) + { + i.next(); + const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion(); + + if (m_minX > region.getMinX()) + m_minX = region.getMinX(); + if (m_minY > region.getMinY()) + m_minY = region.getMinY(); + if (m_maxX < region.getMaxX()) + m_maxX = region.getMaxX(); + if (m_maxY < region.getMaxY()) + m_maxY = region.getMaxY(); + } + + m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY)); + sint32 stride = (1 + m_maxX - m_minX); + for (y = m_minY; y <= m_maxY; ++y) + for (x = m_minX; x <= m_maxX; ++x) + { + m_zoneMask[x - m_minX + (y - m_minY) * stride] = true; + + QMapIterator it(m_landscapeMap); + while (it.hasNext()) + { + it.next(); + if (int(it.key()) != m_currentZoneRegion) + { + const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion(); + + const std::string &rSZone = region.getName (x, y); + if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED)) + { + m_zoneMask[x - m_minX + (y - m_minY) * stride] = false; + } + } + } + } +} + +bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion) +{ + QMapIterator it(m_landscapeMap); + while (it.hasNext()) + { + it.next(); + const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion(); + for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y) + for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x) + { + const std::string &refZoneName = zoneRegion.getName(x, y); + if (refZoneName != STRING_UNUSED) + { + const std::string &zoneName = newZoneRegion.getName(x, y); + if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND)) + return false; + } + } + } + return true; +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h new file mode 100644 index 000000000..509181c94 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/builder_zone_base.h @@ -0,0 +1,139 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef BUILDER_ZONE_BASE_H +#define BUILDER_ZONE_BASE_H + +// Project includes +#include "zone_region_editor.h" +#include "pixmap_database.h" +#include "landscape_editor_global.h" + +// NeL includes +#include +#include + +// STL includes +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include + +namespace LandscapeEditor +{ +class LandscapeScene; + +// Data +struct ZonePosition +{ + // Absolute position + sint32 x; + sint32 y; + int region; + + ZonePosition() + { + x = 0xffffffff; + y = 0xffffffff; + region = -1; + } + + ZonePosition(const sint32 posX, const sint32 posY, const int id) + { + x = posX; + y = posY; + region = id; + } +}; + +/** +@class ZoneBuilder +@brief ZoneBuilder contains all the shared data between the tools and the engine. +@details ZoneBank contains the macro zones that is composed of several zones plus a mask. +PixmapDatabase contains the graphics for the zones +*/ +class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase +{ +public: + ZoneBuilderBase(LandscapeScene *landscapeScene); + virtual ~ZoneBuilderBase(); + + /// Init zoneBank and init zone pixmap database + bool init(const QString &pathName, bool displayProgress = false); + + void calcMask(); + bool getZoneMask (sint32 x, sint32 y); + + /// Zone Region + /// @{ + int createZoneRegion(); + int createZoneRegion(const QString &fileName); + void deleteZoneRegion(int id); + void setCurrentZoneRegion(int id); + int currentIdZoneRegion() const; + ZoneRegionObject *currentZoneRegion() const; + int countZoneRegion() const; + ZoneRegionObject *zoneRegion(int id) const; + void ligoData(LigoData &data, const ZonePosition &zonePos); + void setLigoData(LigoData &data, const ZonePosition &zonePos); + /// @} + + // Accessors + NLLIGO::CZoneBank &getZoneBank() + { + return m_zoneBank; + } + + PixmapDatabase *pixmapDatabase() const; + + QString dataPath() const; + +private: + + /// Scan ./zoneligos dir and add all *.ligozone files to zoneBank + bool initZoneBank (const QString &path); + + bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion); + + struct LandscapeItem + { + ZoneRegionObject *zoneRegionObject; + QGraphicsRectItem *rectItem; + }; + + sint32 m_minX, m_maxX, m_minY, m_maxY; + std::vector m_zoneMask; + + QString m_lastPathName; + + int m_currentZoneRegion; + QMap m_landscapeMap; + + PixmapDatabase *m_pixmapDatabase; + NLLIGO::CZoneBank m_zoneBank; + LandscapeScene *m_landscapeScene; +}; + +} /* namespace LandscapeEditor */ + +#endif // BUILDER_ZONE_BASE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h index 8a31ed15d..612eaca76 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene.h @@ -38,7 +38,7 @@ namespace LandscapeEditor @brief @details */ -class LANDSCAPE_EDITOR_EXPORT LandscapeScene : public QGraphicsScene +class LandscapeScene : public QGraphicsScene { Q_OBJECT diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp new file mode 100644 index 000000000..64d2f1af9 --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.cpp @@ -0,0 +1,320 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Project includes +#include "landscape_scene_base.h" +#include "pixmap_database.h" + +// NeL includes +#include + +// Qt includes +#include +#include +#include +#include + +namespace LandscapeEditor +{ + +static const int ZONE_NAME = 0; +static const int LAYER_ZONES = 2; +static const int LAYER_EMPTY_ZONES = 3; + +// TODO: delete +const char * const LAYER_BLACKOUT_NAME = "blackout"; + +const int MAX_SCENE_WIDTH = 256; +const int MAX_SCENE_HEIGHT = 256; + +LandscapeSceneBase::LandscapeSceneBase(int sizeCell, QObject *parent) + : QGraphicsScene(parent), + m_cellSize(sizeCell), + m_zoneBuilder(0) +{ + setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize)); +} + +LandscapeSceneBase::~LandscapeSceneBase() +{ +} + +int LandscapeSceneBase::cellSize() const +{ + return m_cellSize; +} + +void LandscapeSceneBase::setZoneBuilder(ZoneBuilder *zoneBuilder) +{ + m_zoneBuilder = zoneBuilder; +} + +QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const ZonePosition &zonePos) +{ + if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y))) + return 0; + + if (data.zoneName == STRING_UNUSED) + return createItemEmptyZone(zonePos); + + if ((m_zoneBuilder == 0) || (data.zoneName.empty())) + return 0; + + // Get image from pixmap database + QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str())); + if (pixmap == 0) + return 0; + + // Rotate the image counter clockwise + QMatrix matrix; + matrix.rotate(-data.rot * 90.0); + + QGraphicsPixmapItem *item; + + if (data.flip == 0) + { + item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation)); + } + else + { + // mirror image + QImage mirrorImage = pixmap->toImage(); + QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false)); + item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation)); + } + // Enable bilinear filtering + item->setTransformationMode(Qt::SmoothTransformation); + + NLLIGO::CZoneBankElement *zoneBankItem = m_zoneBuilder->getZoneBank().getElementByZoneName(data.zoneName); + + sint32 deltaX = 0, deltaY = 0; + + // Calculate offset for graphics item (for items with size that are larger than 1) + if ((zoneBankItem->getSizeX() > 1) || (zoneBankItem->getSizeY() > 1)) + { + sint32 sizeX = zoneBankItem->getSizeX(), sizeY = zoneBankItem->getSizeY(); + if (data.flip == 0) + { + switch (data.rot) + { + case 0: + deltaX = -data.posX; + deltaY = -data.posY + sizeY - 1; + break; + case 1: + deltaX = -(sizeY - 1 - data.posY); + deltaY = -data.posX + sizeX - 1; + break; + case 2: + deltaX = -(sizeX - 1 - data.posX); + deltaY = data.posY; + break; + case 3: + deltaX = -data.posY; + deltaY = data.posX; + break; + } + } + else + { + switch (data.rot) + { + case 0: + deltaX = -(sizeX - 1 - data.posX); + deltaY = -data.posY + sizeY - 1; + break; + case 1: + deltaX = -(sizeY - 1 - data.posY); + deltaY = +data.posX; + break; + case 2: + deltaX = -data.posX; + deltaY = data.posY; + break; + case 3: + deltaX = -data.posY; + deltaY = -data.posX + sizeX - 1; + break; + } + } + } + + // Set position graphics item with offset for large piece + item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize); + + // The size graphics item should be equal or proportional m_cellSize + item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); + + item->setData(ZONE_NAME, QString(data.zoneName.c_str())); + + // for not full item zone + item->setZValue(LAYER_ZONES); + + return item; +} + +QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zonePos) +{ + if (m_zoneBuilder == 0) + return 0; + + if (checkUnderZone(zonePos.x, zonePos.y)) + return 0; + + // Get image from pixmap database + QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED)); + if (pixmap == 0) + return 0; + + QGraphicsPixmapItem *item = addPixmap(*pixmap); + + // Enable bilinear filtering + item->setTransformationMode(Qt::SmoothTransformation); + + // Set position graphics item + item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize); + + // The size graphics item should be equal or proportional m_cellSize + item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize()); + + // for not full item zone + item->setZValue(LAYER_EMPTY_ZONES); + + return item; +} + +void LandscapeSceneBase::deleteItemZone(const ZonePosition &zonePos) +{ + QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize); + + // TODO: delete LAYER_BLACKOUT_NAME + if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME))) + { + removeItem(item); + delete item; + } +} + +void LandscapeSceneBase::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +{ + for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i) + { + for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) + { + + std::string zoneName = zoneRegion.getName(i, j); + if (zoneName == STRING_UNUSED) + { + ZonePosition zonePos(i, j, -1); + QGraphicsItem *item = createItemEmptyZone(zonePos); + } + else if (!zoneName.empty()) + { + LigoData data; + ZonePosition zonePos(i, j, -1); + data.zoneName = zoneName; + data.rot = zoneRegion.getRot(i, j); + data.flip = zoneRegion.getFlip(i, j); + data.posX = zoneRegion.getPosX(i, j); + data.posY = zoneRegion.getPosY(i, j); + QGraphicsItem *item = createItemZone(data, zonePos); + } + } + } +} + +void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion) +{ + for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i) + { + for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j) + { + deleteItemZone(ZonePosition(i, -j, -1)); + } + } +} + +void LandscapeSceneBase::snapshot(const QString &fileName, int width, int height, const QRectF &landRect) +{ + if (m_zoneBuilder == 0) + return; + + // Create image + QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888); + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing, true); + + // Add white background + painter.setBrush(QBrush(Qt::white)); + painter.setPen(Qt::NoPen); + painter.drawRect(0, 0, landRect.width(), landRect.height()); + + // Paint landscape + render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect); + + QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + scaledImage.save(fileName); +} + +QString LandscapeSceneBase::zoneNameFromMousePos() const +{ + if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) || + (m_posX < 0) || (m_posX > MAX_SCENE_WIDTH)) + return "NOT A VALID ZONE"; + + return QString("%1_%2%3 %4 %5 ").arg(-m_posY).arg(QChar('A' + (m_posX/26))). + arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2); +} + +void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + QGraphicsScene::mousePressEvent(mouseEvent); + + qreal x = mouseEvent->scenePos().x(); + qreal y = mouseEvent->scenePos().y(); + m_posX = sint32(floor(x / m_cellSize)); + m_posY = sint32(-floor(y / m_cellSize)); + + m_mouseButton = mouseEvent->button(); +} + +void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) +{ + m_mouseX = mouseEvent->scenePos().x(); + m_mouseY = mouseEvent->scenePos().y() - m_cellSize; + + m_posX = sint32(floor(m_mouseX / m_cellSize)); + m_posY = sint32(-floor(m_mouseY / m_cellSize)); + + QGraphicsScene::mouseMoveEvent(mouseEvent); +} + +void LandscapeSceneBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) +{ + QGraphicsScene::mouseReleaseEvent(mouseEvent); + m_mouseButton = Qt::NoButton; +} + +bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY) +{ + // TODO: it will not work correctly in world editor + QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize); + if (item != 0) + return true; + return false; +} + +} /* namespace LandscapeEditor */ diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h new file mode 100644 index 000000000..45d4d13bf --- /dev/null +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_scene_base.h @@ -0,0 +1,81 @@ +// Object Viewer Qt - MMORPG Framework +// Copyright (C) 2011 Dzmitry Kamiahin +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef LANDSCAPE_SCENE_BASE_H +#define LANDSCAPE_SCENE_BASE_H + +// Project includes +#include "zone_region_editor.h" +#include "builder_zone.h" +#include "landscape_editor_global.h" + +// NeL includes +#include + +// Qt includes +#include +#include + +namespace LandscapeEditor +{ + +/** +@class LandscapeSceneBase +@brief +@details +*/ +class LANDSCAPE_EDITOR_EXPORT LandscapeSceneBase : public QGraphicsScene +{ + Q_OBJECT + +public: + LandscapeSceneBase(int sizeCell = 160, QObject *parent = 0); + virtual ~LandscapeSceneBase(); + + int cellSize() const; + virtual void setZoneBuilder(ZoneBuilder *zoneBuilder); + + QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos); + QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos); + void deleteItemZone(const ZonePosition &zonePos); + + void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion); + + void snapshot(const QString &fileName, int width, int height, const QRectF &landRect); + + QString zoneNameFromMousePos() const; + +public Q_SLOTS: + +protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); + +private: + bool checkUnderZone(const int posX, const int posY); + + int m_cellSize; + qreal m_mouseX, m_mouseY; + sint32 m_posX, m_posY; + Qt::MouseButton m_mouseButton; + ZoneBuilder *m_zoneBuilder; +}; + +} /* namespace LandscapeEditor */ + +#endif // LANDSCAPE_SCENE_BASE_H diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h index abb93ab81..e6b2b950a 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/project_settings_dialog.h @@ -20,13 +20,14 @@ // Project includes #include "ui_project_settings_dialog.h" +#include "landscape_editor_global.h" // Qt includes namespace LandscapeEditor { -class ProjectSettingsDialog: public QDialog +class LANDSCAPE_EDITOR_EXPORT ProjectSettingsDialog: public QDialog { Q_OBJECT