]> git.mxchange.org Git - simgear.git/blob - simgear/scene/bvh/BVHDebugCollectVisitor.hxx
Make the debug geometry stuff work with a time argument.
[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/ShapeDrawable>
29 #include <osg/Shape>
30 #include <osg/Depth>
31 #include <osg/BlendFunc>
32 #include <osg/StateSet>
33
34 #include <simgear/math/SGGeometry.hxx>
35
36 #include "BVHVisitor.hxx"
37 #include "BVHNode.hxx"
38 #include "BVHGroup.hxx"
39 #include "BVHTransform.hxx"
40 #include "BVHMotionTransform.hxx"
41 #include "BVHStaticGeometry.hxx"
42
43 #include "BVHStaticData.hxx"
44
45 #include "BVHStaticNode.hxx"
46 #include "BVHStaticTriangle.hxx"
47 #include "BVHStaticBinary.hxx"
48
49 #include "BVHBoundingBoxVisitor.hxx"
50
51 namespace simgear {
52
53 class BVHNode;
54 class BVHStaticNode;
55
56 class BVHDebugCollectVisitor : public BVHVisitor {
57 public:
58     BVHDebugCollectVisitor(const double& time, unsigned level = ~0u) :
59         _group(new osg::Group),
60         _time(time),
61         _level(level),
62         _currentLevel(0)
63     {
64         osg::StateSet* stateSet = _group->getOrCreateStateSet();
65         stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
66         stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
67         stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false));
68         osg::BlendFunc *blendFunc;
69         blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
70                                        osg::BlendFunc::DST_ALPHA);
71         stateSet->setAttributeAndModes(blendFunc);
72         osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1);
73         stateSet->setAttributeAndModes(polygonOffset);
74     }
75     virtual ~BVHDebugCollectVisitor()
76     { }
77
78     virtual void apply(BVHGroup& node)
79     {
80         addNodeSphere(node);
81         ++_currentLevel;
82         node.traverse(*this);
83         --_currentLevel;
84     }
85     virtual void apply(BVHTransform& node)
86     {
87         addNodeSphere(node);
88         osg::ref_ptr<osg::Group> oldGroup = _group;
89         osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
90         transform->setMatrix(osg::Matrix(node.getToWorldTransform().data()));
91         _group = transform;
92         ++_currentLevel;
93         node.traverse(*this);
94         --_currentLevel;
95         _group = oldGroup;
96         if (transform->getNumChildren())
97             _group->addChild(transform.get());
98     }
99     virtual void apply(BVHMotionTransform& node)
100     {
101         addNodeSphere(node);
102         osg::ref_ptr<osg::Group> oldGroup = _group;
103         osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
104         transform->setMatrix(osg::Matrix(node.getToWorldTransform(_time).data()));
105         _group = transform;
106         ++_currentLevel;
107         node.traverse(*this);
108         --_currentLevel;
109         _group = oldGroup;
110         if (transform->getNumChildren())
111             _group->addChild(transform.get());
112     }
113     virtual void apply(BVHLineGeometry&)
114     {
115     }
116     virtual void apply(BVHStaticGeometry& node)
117     {
118         addNodeSphere(node);
119         ++_currentLevel;
120         node.traverse(*this);
121         --_currentLevel;
122     }
123
124     virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
125     {
126         addNodeBox(node, data);
127         ++_currentLevel;
128         node.traverse(*this, data);
129         --_currentLevel;
130     }
131     virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
132     {
133         addNodeBox(node, data);
134         addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2));
135     }
136
137     osg::Node* getNode() const { return _group.get(); }
138
139     static unsigned allLevels() { return ~0u; }
140     static unsigned triangles() { return ~0u - 1; }
141
142 private:
143     void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color)
144     {
145         if (_level != triangles())
146             return;
147         
148         osg::Geometry* geometry = new osg::Geometry;
149         
150         osg::Vec3Array* vertices = new osg::Vec3Array;
151         vertices->push_back(triangle.getVertex(0).osg());
152         vertices->push_back(triangle.getVertex(1).osg());
153         vertices->push_back(triangle.getVertex(2).osg());
154         
155         osg::Vec4Array* colors = new osg::Vec4Array;
156         colors->push_back(color);
157         
158         geometry->setVertexArray(vertices);
159         geometry->setColorArray(colors);
160         geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
161         
162         geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3));
163         
164         osg::Geode* geode = new osg::Geode;
165         geode->addDrawable(geometry);
166         _group->addChild(geode);
167     }
168     
169     void addNodeSphere(const BVHNode& node)
170     {
171         if (_level != ~0u && _level != _currentLevel)
172             return;
173         SGSphered sphere = node.getBoundingSphere();
174         osg::Sphere* shape = new osg::Sphere;
175         shape->setCenter(SGVec3f(sphere.getCenter()).osg());
176         shape->setRadius(sphere.getRadius());
177         addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
178     }
179     
180     void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data)
181     {
182         if (_level != ~0u && _level != _currentLevel)
183             return;
184         BVHBoundingBoxVisitor bbv;
185         node.accept(bbv, data);
186         osg::Box* shape = new osg::Box;
187         shape->setCenter(bbv.getBox().getCenter().osg());
188         shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg());
189         addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
190     }
191     
192     void addShape(osg::Shape* shape, const osg::Vec4& color)
193     {
194         osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable;
195         shapeDrawable->setColor(color);
196         shapeDrawable->setShape(shape);
197         osg::Geode* geode = new osg::Geode;
198         geode->addDrawable(shapeDrawable);
199         _group->addChild(geode);
200     }
201     
202     osg::ref_ptr<osg::Group> _group;
203     const double _time;
204     const unsigned _level;
205     unsigned _currentLevel;
206 };
207
208 }
209
210 #endif