]> git.mxchange.org Git - simgear.git/blob - simgear/scene/bvh/BVHDebugCollectVisitor.hxx
Initial commit of the bounding volume tree implementation.
[simgear.git] / simgear / scene / bvh / BVHDebugCollectVisitor.hxx
1 // Copyright (C) 2008 - 2009  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef BVHDebugCollectVisitor_hxx
19 #define BVHDebugCollectVisitor_hxx
20
21 #include <osg/ref_ptr>
22 #include <osg/Geode>
23 #include <osg/Geometry>
24 #include <osg/Group>
25 #include <osg/PolygonOffset>
26 #include <osg/PrimitiveSet>
27 #include <osg/MatrixTransform>
28 #include <osg/PositionAttitudeTransform>
29 #include <osg/ShapeDrawable>
30 #include <osg/Shape>
31 #include <osg/Depth>
32 #include <osg/BlendFunc>
33 #include <osg/StateSet>
34
35 #include <simgear/math/SGGeometry.hxx>
36
37 #include "BVHVisitor.hxx"
38 #include "BVHNode.hxx"
39 #include "BVHGroup.hxx"
40 #include "BVHTransform.hxx"
41 #include "BVHMotionTransform.hxx"
42 #include "BVHStaticGeometry.hxx"
43
44 #include "BVHStaticData.hxx"
45
46 #include "BVHStaticNode.hxx"
47 #include "BVHStaticLeaf.hxx"
48 #include "BVHStaticTriangle.hxx"
49 #include "BVHStaticBinary.hxx"
50
51 #include "BVHBoundingBoxVisitor.hxx"
52
53 namespace simgear {
54
55 class BVHNode;
56 class BVHStaticNode;
57
58 class BVHDebugCollectVisitor : public BVHVisitor {
59 public:
60     BVHDebugCollectVisitor(unsigned level = ~0u) :
61         _group(new osg::Group),
62         _level(level),
63         _currentLevel(0)
64     {
65         osg::StateSet* stateSet = _group->getOrCreateStateSet();
66         stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
67         stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
68         stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false));
69         osg::BlendFunc *blendFunc;
70         blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
71                                        osg::BlendFunc::DST_ALPHA);
72         stateSet->setAttributeAndModes(blendFunc);
73         osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1);
74         stateSet->setAttributeAndModes(polygonOffset);
75     }
76     virtual ~BVHDebugCollectVisitor()
77     { }
78
79     virtual void apply(BVHGroup& node)
80     {
81         addNodeSphere(node);
82         ++_currentLevel;
83         node.traverse(*this);
84         --_currentLevel;
85     }
86     virtual void apply(BVHTransform& node)
87     {
88         addNodeSphere(node);
89         osg::ref_ptr<osg::Group> oldGroup = _group;
90         osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
91         transform->setMatrix(osg::Matrix(node.getToWorldTransform().data()));
92         _group = transform;
93         ++_currentLevel;
94         node.traverse(*this);
95         --_currentLevel;
96         _group = oldGroup;
97         if (transform->getNumChildren())
98             _group->addChild(transform.get());
99     }
100     virtual void apply(BVHMotionTransform& node)
101     {
102         addNodeSphere(node);
103         osg::ref_ptr<osg::Group> oldGroup = _group;
104         osg::ref_ptr<osg::PositionAttitudeTransform> transform;
105         transform = new osg::PositionAttitudeTransform;
106         double tt = node.getReferenceTime() - node.getEndTime();
107         tt = 100*tt;
108         tt += node.getReferenceTime();
109 //     transform->setPosition(node.getPosition(node.getEndTime()).osg());
110         transform->setPosition(node.getPosition().osg());
111         transform->setAttitude(inverse(node.getOrientation(tt)).osg());
112 //     transform->setPosition(node.getPosition().osg());
113 //     transform->setAttitude(inverse(node.getOrientation()).osg());
114         _group = transform;
115         ++_currentLevel;
116         node.traverse(*this);
117         --_currentLevel;
118         _group = oldGroup;
119         if (transform->getNumChildren())
120             _group->addChild(transform.get());
121     }
122     virtual void apply(BVHLineGeometry&)
123     {
124     }
125     virtual void apply(BVHStaticGeometry& node)
126     {
127         addNodeSphere(node);
128         ++_currentLevel;
129         node.traverse(*this);
130         --_currentLevel;
131     }
132
133     virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
134     {
135         addNodeBox(node, data);
136         ++_currentLevel;
137         node.traverse(*this, data);
138         --_currentLevel;
139     }
140     virtual void apply(const BVHStaticLeaf& node, const BVHStaticData& data)
141     {
142         addNodeBox(node, data);
143     }
144     virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
145     {
146         addNodeBox(node, data);
147         addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2));
148     }
149
150     osg::Node* getNode() const { return _group.get(); }
151
152     static unsigned allLevels() { return ~0u; }
153     static unsigned triangles() { return ~0u - 1; }
154
155 private:
156     void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color)
157     {
158         if (_level != triangles())
159             return;
160         
161         osg::Geometry* geometry = new osg::Geometry;
162         
163         osg::Vec3Array* vertices = new osg::Vec3Array;
164         vertices->push_back(triangle.getVertex(0).osg());
165         vertices->push_back(triangle.getVertex(1).osg());
166         vertices->push_back(triangle.getVertex(2).osg());
167         
168         osg::Vec4Array* colors = new osg::Vec4Array;
169         colors->push_back(color);
170         
171         geometry->setVertexArray(vertices);
172         geometry->setColorArray(colors);
173         geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
174         
175         geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3));
176         
177         osg::Geode* geode = new osg::Geode;
178         geode->addDrawable(geometry);
179         _group->addChild(geode);
180     }
181     
182     void addNodeSphere(const BVHNode& node)
183     {
184         if (_level != ~0u && _level != _currentLevel)
185             return;
186         SGSphered sphere = node.getBoundingSphere();
187         osg::Sphere* shape = new osg::Sphere;
188         shape->setCenter(SGVec3f(sphere.getCenter()).osg());
189         shape->setRadius(sphere.getRadius());
190         addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
191     }
192     
193     void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data)
194     {
195         if (_level != ~0u && _level != _currentLevel)
196             return;
197         BVHBoundingBoxVisitor bbv;
198         node.accept(bbv, data);
199         osg::Box* shape = new osg::Box;
200         shape->setCenter(bbv.getBox().getCenter().osg());
201         shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg());
202         addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
203     }
204     
205     void addShape(osg::Shape* shape, const osg::Vec4& color)
206     {
207         osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable;
208         shapeDrawable->setColor(color);
209         shapeDrawable->setShape(shape);
210         osg::Geode* geode = new osg::Geode;
211         geode->addDrawable(shapeDrawable);
212         _group->addChild(geode);
213     }
214     
215     osg::ref_ptr<osg::Group> _group;
216     const unsigned _level;
217     unsigned _currentLevel;
218 };
219
220 }
221
222 #endif