00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef BVHDebugCollectVisitor_hxx
00019 #define BVHDebugCollectVisitor_hxx
00020
00021 #include <osg/ref_ptr>
00022 #include <osg/Geode>
00023 #include <osg/Geometry>
00024 #include <osg/Group>
00025 #include <osg/PolygonOffset>
00026 #include <osg/PrimitiveSet>
00027 #include <osg/MatrixTransform>
00028 #include <osg/ShapeDrawable>
00029 #include <osg/Shape>
00030 #include <osg/Depth>
00031 #include <osg/BlendFunc>
00032 #include <osg/StateSet>
00033
00034 #include <simgear/math/SGGeometry.hxx>
00035
00036 #include "BVHVisitor.hxx"
00037 #include "BVHNode.hxx"
00038 #include "BVHGroup.hxx"
00039 #include "BVHTransform.hxx"
00040 #include "BVHMotionTransform.hxx"
00041 #include "BVHStaticGeometry.hxx"
00042
00043 #include "BVHStaticData.hxx"
00044
00045 #include "BVHStaticNode.hxx"
00046 #include "BVHStaticTriangle.hxx"
00047 #include "BVHStaticBinary.hxx"
00048
00049 #include "BVHBoundingBoxVisitor.hxx"
00050
00051 namespace simgear {
00052
00053 class BVHNode;
00054 class BVHStaticNode;
00055
00056 class BVHDebugCollectVisitor : public BVHVisitor {
00057 public:
00058 BVHDebugCollectVisitor(const double& time, unsigned level = ~0u) :
00059 _group(new osg::Group),
00060 _time(time),
00061 _level(level),
00062 _currentLevel(0)
00063 {
00064 osg::StateSet* stateSet = _group->getOrCreateStateSet();
00065 stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
00066 stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
00067 stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false));
00068 osg::BlendFunc *blendFunc;
00069 blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
00070 osg::BlendFunc::DST_ALPHA);
00071 stateSet->setAttributeAndModes(blendFunc);
00072 osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1);
00073 stateSet->setAttributeAndModes(polygonOffset);
00074 }
00075 virtual ~BVHDebugCollectVisitor()
00076 { }
00077
00078 virtual void apply(BVHGroup& node)
00079 {
00080 addNodeSphere(node);
00081 ++_currentLevel;
00082 node.traverse(*this);
00083 --_currentLevel;
00084 }
00085 virtual void apply(BVHTransform& node)
00086 {
00087 addNodeSphere(node);
00088 osg::ref_ptr<osg::Group> oldGroup = _group;
00089 osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
00090 transform->setMatrix(osg::Matrix(node.getToWorldTransform().data()));
00091 _group = transform;
00092 ++_currentLevel;
00093 node.traverse(*this);
00094 --_currentLevel;
00095 _group = oldGroup;
00096 if (transform->getNumChildren())
00097 _group->addChild(transform.get());
00098 }
00099 virtual void apply(BVHMotionTransform& node)
00100 {
00101 addNodeSphere(node);
00102 osg::ref_ptr<osg::Group> oldGroup = _group;
00103 osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
00104 transform->setMatrix(osg::Matrix(node.getToWorldTransform(_time).data()));
00105 _group = transform;
00106 ++_currentLevel;
00107 node.traverse(*this);
00108 --_currentLevel;
00109 _group = oldGroup;
00110 if (transform->getNumChildren())
00111 _group->addChild(transform.get());
00112 }
00113 virtual void apply(BVHLineGeometry&)
00114 {
00115 }
00116 virtual void apply(BVHStaticGeometry& node)
00117 {
00118 addNodeSphere(node);
00119 ++_currentLevel;
00120 node.traverse(*this);
00121 --_currentLevel;
00122 }
00123
00124 virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
00125 {
00126 addNodeBox(node, data);
00127 ++_currentLevel;
00128 node.traverse(*this, data);
00129 --_currentLevel;
00130 }
00131 virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data)
00132 {
00133 addNodeBox(node, data);
00134 addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2));
00135 }
00136
00137 osg::Node* getNode() const { return _group.get(); }
00138
00139 static unsigned allLevels() { return ~0u; }
00140 static unsigned triangles() { return ~0u - 1; }
00141
00142 private:
00143 void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color)
00144 {
00145 if (_level != triangles())
00146 return;
00147
00148 osg::Geometry* geometry = new osg::Geometry;
00149
00150 osg::Vec3Array* vertices = new osg::Vec3Array;
00151 vertices->push_back(triangle.getVertex(0).osg());
00152 vertices->push_back(triangle.getVertex(1).osg());
00153 vertices->push_back(triangle.getVertex(2).osg());
00154
00155 osg::Vec4Array* colors = new osg::Vec4Array;
00156 colors->push_back(color);
00157
00158 geometry->setVertexArray(vertices);
00159 geometry->setColorArray(colors);
00160 geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
00161
00162 geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3));
00163
00164 osg::Geode* geode = new osg::Geode;
00165 geode->addDrawable(geometry);
00166 _group->addChild(geode);
00167 }
00168
00169 void addNodeSphere(const BVHNode& node)
00170 {
00171 if (_level != ~0u && _level != _currentLevel)
00172 return;
00173 SGSphered sphere = node.getBoundingSphere();
00174 osg::Sphere* shape = new osg::Sphere;
00175 shape->setCenter(SGVec3f(sphere.getCenter()).osg());
00176 shape->setRadius(sphere.getRadius());
00177 addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
00178 }
00179
00180 void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data)
00181 {
00182 if (_level != ~0u && _level != _currentLevel)
00183 return;
00184 BVHBoundingBoxVisitor bbv;
00185 node.accept(bbv, data);
00186 osg::Box* shape = new osg::Box;
00187 shape->setCenter(bbv.getBox().getCenter().osg());
00188 shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg());
00189 addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
00190 }
00191
00192 void addShape(osg::Shape* shape, const osg::Vec4& color)
00193 {
00194 osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable;
00195 shapeDrawable->setColor(color);
00196 shapeDrawable->setShape(shape);
00197 osg::Geode* geode = new osg::Geode;
00198 geode->addDrawable(shapeDrawable);
00199 _group->addChild(geode);
00200 }
00201
00202 osg::ref_ptr<osg::Group> _group;
00203 const double _time;
00204 const unsigned _level;
00205 unsigned _currentLevel;
00206 };
00207
00208 }
00209
00210 #endif