1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "Layer.h"
21 
22 #include "Model/Brush.h"
23 #include "Model/Group.h"
24 #include "Model/Entity.h"
25 #include "Model/IssueGenerator.h"
26 #include "Model/NodeVisitor.h"
27 
28 namespace TrenchBroom {
29     namespace Model {
Layer(const String & name,const BBox3 & worldBounds)30         Layer::Layer(const String& name, const BBox3& worldBounds) :
31         m_name(name),
32         m_octree(worldBounds, static_cast<FloatType>(64.0f)) {}
33 
setName(const String & name)34         void Layer::setName(const String& name) {
35             m_name = name;
36         }
37 
doGetName() const38         const String& Layer::doGetName() const {
39             return m_name;
40         }
41 
doGetBounds() const42         const BBox3& Layer::doGetBounds() const {
43             return m_octree.bounds();
44         }
45 
doClone(const BBox3 & worldBounds) const46         Node* Layer::doClone(const BBox3& worldBounds) const {
47             Layer* layer = new Layer(m_name, worldBounds);
48             cloneAttributes(layer);
49             layer->addChildren(clone(worldBounds, children()));
50             return layer;
51         }
52 
53         class CanAddChildToLayer : public ConstNodeVisitor, public NodeQuery<bool> {
54         private:
doVisit(const World * world)55             void doVisit(const World* world)   { setResult(false); }
doVisit(const Layer * layer)56             void doVisit(const Layer* layer)   { setResult(false); }
doVisit(const Group * group)57             void doVisit(const Group* group)   { setResult(true); }
doVisit(const Entity * entity)58             void doVisit(const Entity* entity) { setResult(true); }
doVisit(const Brush * brush)59             void doVisit(const Brush* brush)   { setResult(true); }
60         };
61 
doCanAddChild(const Node * child) const62         bool Layer::doCanAddChild(const Node* child) const {
63             CanAddChildToLayer visitor;
64             child->accept(visitor);
65             return visitor.result();
66         }
67 
doCanRemoveChild(const Node * child) const68         bool Layer::doCanRemoveChild(const Node* child) const {
69             return true;
70         }
71 
doRemoveIfEmpty() const72         bool Layer::doRemoveIfEmpty() const {
73             return false;
74         }
75 
76         class Layer::AddNodeToOctree : public NodeVisitor {
77         private:
78             NodeTree& m_octree;
79         public:
AddNodeToOctree(NodeTree & octree)80             AddNodeToOctree(NodeTree& octree) :
81             m_octree(octree) {}
82         private:
doVisit(World * world)83             void doVisit(World* world)   {}
doVisit(Layer * layer)84             void doVisit(Layer* layer)   {}
doVisit(Group * group)85             void doVisit(Group* group)   { m_octree.addObject(group->bounds(), group); }
doVisit(Entity * entity)86             void doVisit(Entity* entity) { m_octree.addObject(entity->bounds(), entity); }
doVisit(Brush * brush)87             void doVisit(Brush* brush)   { m_octree.addObject(brush->bounds(), brush); }
88         };
89 
90         class Layer::RemoveNodeFromOctree : public NodeVisitor {
91         private:
92             NodeTree& m_octree;
93         public:
RemoveNodeFromOctree(NodeTree & octree)94             RemoveNodeFromOctree(NodeTree& octree) :
95             m_octree(octree) {}
96         private:
doVisit(World * world)97             void doVisit(World* world)   {}
doVisit(Layer * layer)98             void doVisit(Layer* layer)   {}
doVisit(Group * group)99             void doVisit(Group* group)   { m_octree.removeObject(group); }
doVisit(Entity * entity)100             void doVisit(Entity* entity) { m_octree.removeObject(entity); }
doVisit(Brush * brush)101             void doVisit(Brush* brush)   { m_octree.removeObject(brush); }
102         };
103 
104         class Layer::UpdateNodeInOctree : public NodeVisitor {
105         private:
106             NodeTree& m_octree;
107         public:
UpdateNodeInOctree(NodeTree & octree)108             UpdateNodeInOctree(NodeTree& octree) :
109             m_octree(octree) {}
110         private:
doVisit(World * world)111             void doVisit(World* world)   {}
doVisit(Layer * layer)112             void doVisit(Layer* layer)   {}
doVisit(Group * group)113             void doVisit(Group* group)   { m_octree.updateObject(group->bounds(), group); }
doVisit(Entity * entity)114             void doVisit(Entity* entity) { m_octree.updateObject(entity->bounds(), entity); }
doVisit(Brush * brush)115             void doVisit(Brush* brush)   { m_octree.updateObject(brush->bounds(), brush); }
116         };
117 
doChildWasAdded(Node * node)118         void Layer::doChildWasAdded(Node* node) {
119             AddNodeToOctree visitor(m_octree);
120             node->accept(visitor);
121         }
122 
doChildWillBeRemoved(Node * node)123         void Layer::doChildWillBeRemoved(Node* node) {
124             RemoveNodeFromOctree visitor(m_octree);
125             node->accept(visitor);
126         }
127 
doChildBoundsDidChange(Node * node)128         void Layer::doChildBoundsDidChange(Node* node) {
129             UpdateNodeInOctree visitor(m_octree);
130             node->accept(visitor);
131         }
132 
doSelectable() const133         bool Layer::doSelectable() const {
134             return false;
135         }
136 
doGenerateIssues(const IssueGenerator * generator,IssueList & issues)137         void Layer::doGenerateIssues(const IssueGenerator* generator, IssueList& issues) {
138             generator->generate(this, issues);
139         }
140 
doAccept(NodeVisitor & visitor)141         void Layer::doAccept(NodeVisitor& visitor) {
142             visitor.visit(this);
143         }
144 
doAccept(ConstNodeVisitor & visitor) const145         void Layer::doAccept(ConstNodeVisitor& visitor) const {
146             visitor.visit(this);
147         }
148 
doPick(const Ray3 & ray,PickResult & pickResult) const149         void Layer::doPick(const Ray3& ray, PickResult& pickResult) const {
150             const Model::NodeList candidates = m_octree.findObjects(ray);
151             NodeList::const_iterator it, end;
152             for (it = candidates.begin(), end = candidates.end(); it != end; ++it) {
153                 const Node* node = *it;
154                 node->pick(ray, pickResult);
155             }
156         }
157 
doFindNodesContaining(const Vec3 & point,NodeList & result)158         void Layer::doFindNodesContaining(const Vec3& point, NodeList& result) {
159             const Model::NodeList candidates = m_octree.findObjects(point);
160             NodeList::const_iterator it, end;
161             for (it = candidates.begin(), end = candidates.end(); it != end; ++it) {
162                 Node* node = *it;
163                 node->findNodesContaining(point, result);
164             }
165         }
166 
doIntersectWithRay(const Ray3 & ray) const167         FloatType Layer::doIntersectWithRay(const Ray3& ray) const {
168             return Math::nan<FloatType>();
169         }
170     }
171 }
172