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