File indexing completed on 2024-11-17 04:17:26
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOSMINDOORMAP_SCENEGRAPH_H 0008 #define KOSMINDOORMAP_SCENEGRAPH_H 0009 0010 #include "kosmindoormap_export.h" 0011 0012 #include "scenegraphitem.h" 0013 0014 #include <KOSM/Element> 0015 0016 #include <QColor> 0017 0018 #include <memory> 0019 #include <vector> 0020 0021 class QPointF; 0022 0023 namespace KOSMIndoorMap { 0024 0025 class SceneGraphItem; 0026 0027 /** Scene graph of the currently displayed level. */ 0028 class KOSMINDOORMAP_EXPORT SceneGraph 0029 { 0030 public: 0031 explicit SceneGraph(); 0032 SceneGraph(const SceneGraph&) = delete; 0033 SceneGraph(SceneGraph&&); 0034 ~SceneGraph(); 0035 0036 SceneGraph& operator=(const SceneGraph&) = delete; 0037 SceneGraph& operator=(SceneGraph &&other); 0038 0039 /** Clears all data from the scene graph. */ 0040 void clear(); 0041 0042 // scene builder interface 0043 void beginSwap(); 0044 void addItem(SceneGraphItem &&item); 0045 template <typename T> 0046 std::unique_ptr<SceneGraphItemPayload> findOrCreatePayload(OSM::Element e, int level, LayerSelectorKey layerSelector); 0047 void zSort(); 0048 void endSwap(); 0049 0050 // dirty state tracking 0051 int zoomLevel() const; 0052 void setZoomLevel(int zoom); 0053 int currentFloorLevel() const; 0054 void setCurrentFloorLevel(int level); 0055 0056 /** Canvas background color. */ 0057 QColor backgroundColor() const; 0058 void setBackgroundColor(const QColor &bg); 0059 0060 // renderer interface 0061 typedef std::pair<std::size_t, std::size_t> LayerOffset; 0062 const std::vector<LayerOffset>& layerOffsets() const; 0063 0064 typedef std::vector<SceneGraphItem>::const_iterator SceneGraphItemIter; 0065 SceneGraphItemIter itemsBegin(LayerOffset layer) const; 0066 SceneGraphItemIter itemsEnd(LayerOffset layer) const; 0067 0068 // hit detector interface 0069 const std::vector<SceneGraphItem>& items() const; 0070 0071 private: 0072 void recomputeLayerIndex(); 0073 0074 static bool itemPoolCompare(const SceneGraphItem &lhs, const SceneGraphItem &rhs); 0075 static bool zOrderCompare(const SceneGraphItem &lhs, const SceneGraphItem &rhs); 0076 0077 std::vector<SceneGraphItem> m_items; 0078 std::vector<SceneGraphItem> m_previousItems; 0079 std::vector<std::pair<std::size_t, std::size_t>> m_layerOffsets; 0080 QColor m_bgColor; 0081 0082 int m_zoomLevel = 0; 0083 int m_floorLevel = 0; 0084 }; 0085 0086 0087 template<typename T> 0088 std::unique_ptr<SceneGraphItemPayload> SceneGraph::findOrCreatePayload(OSM::Element e, int level, LayerSelectorKey layerSelector) 0089 { 0090 SceneGraphItem ref; 0091 ref.element = e; 0092 ref.level = level; 0093 auto it = std::lower_bound(m_previousItems.begin(), m_previousItems.end(), ref, SceneGraph::itemPoolCompare); 0094 for (;it != m_previousItems.end() && (*it).element.type() == e.type() && (*it).element.id() == e.id() && (*it).layerSelector == layerSelector && (*it).level == level && (*it).payload; ++it) { 0095 if (dynamic_cast<T*>((*it).payload.get())) { 0096 return std::move((*it).payload); 0097 } 0098 } 0099 return std::make_unique<T>(); 0100 } 0101 0102 } 0103 0104 #endif // KOSMINDOORMAP_SCENEGRAPH_H