From addf47600d24c793e77470cae34f133fe9199c23 Mon Sep 17 00:00:00 2001 From: frohlich Date: Mon, 2 Mar 2009 18:02:50 +0000 Subject: [PATCH] Remove the StaticLeaf visitor slot. Add a nearest point visitor. Modified Files: BVHBoundingBoxVisitor.hxx BVHDebugCollectVisitor.hxx BVHLineSegmentVisitor.cxx BVHLineSegmentVisitor.hxx BVHStaticGeometryBuilder.hxx BVHStaticLeaf.cxx BVHStaticLeaf.hxx BVHSubTreeCollector.cxx BVHSubTreeCollector.hxx BVHVisitor.hxx Makefile.am bvhtest.cxx Added Files: BVHNearestPointVisitor.hxx --- simgear/scene/bvh/BVHBoundingBoxVisitor.hxx | 3 - simgear/scene/bvh/BVHDebugCollectVisitor.hxx | 17 +- simgear/scene/bvh/BVHLineSegmentVisitor.cxx | 7 - simgear/scene/bvh/BVHLineSegmentVisitor.hxx | 1 - simgear/scene/bvh/BVHNearestPointVisitor.hxx | 161 +++++++++++++++++++ simgear/scene/bvh/BVHStaticLeaf.cxx | 6 - simgear/scene/bvh/BVHStaticLeaf.hxx | 2 +- simgear/scene/bvh/BVHSubTreeCollector.cxx | 10 -- simgear/scene/bvh/BVHSubTreeCollector.hxx | 1 - simgear/scene/bvh/BVHVisitor.hxx | 2 - simgear/scene/bvh/Makefile.am | 1 + simgear/scene/bvh/bvhtest.cxx | 24 +++ 12 files changed, 189 insertions(+), 46 deletions(-) create mode 100644 simgear/scene/bvh/BVHNearestPointVisitor.hxx diff --git a/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx b/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx index 8fc9db9f..d37779c3 100644 --- a/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx +++ b/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx @@ -30,7 +30,6 @@ #include "BVHStaticData.hxx" #include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" #include "BVHStaticTriangle.hxx" #include "BVHStaticBinary.hxx" #include "BVHStaticGeometry.hxx" @@ -57,8 +56,6 @@ public: virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) { expandBy(node.getBoundingBox()); } - virtual void apply(const BVHStaticLeaf& node, const BVHStaticData& data) - { expandBy(node.computeBoundingBox(data)); } virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) { expandBy(node.computeBoundingBox(data)); } diff --git a/simgear/scene/bvh/BVHDebugCollectVisitor.hxx b/simgear/scene/bvh/BVHDebugCollectVisitor.hxx index 540ee45f..11bbd9f1 100644 --- a/simgear/scene/bvh/BVHDebugCollectVisitor.hxx +++ b/simgear/scene/bvh/BVHDebugCollectVisitor.hxx @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -44,7 +43,6 @@ #include "BVHStaticData.hxx" #include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" #include "BVHStaticTriangle.hxx" #include "BVHStaticBinary.hxx" @@ -101,16 +99,9 @@ public: { addNodeSphere(node); osg::ref_ptr oldGroup = _group; - osg::ref_ptr transform; - transform = new osg::PositionAttitudeTransform; + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrix(node.getToWorldReferenceTransform().data())); double tt = node.getReferenceTime() - node.getEndTime(); - tt = 100*tt; - tt += node.getReferenceTime(); -// transform->setPosition(node.getPosition(node.getEndTime()).osg()); - transform->setPosition(node.getPosition().osg()); - transform->setAttitude(inverse(node.getOrientation(tt)).osg()); -// transform->setPosition(node.getPosition().osg()); -// transform->setAttitude(inverse(node.getOrientation()).osg()); _group = transform; ++_currentLevel; node.traverse(*this); @@ -137,10 +128,6 @@ public: node.traverse(*this, data); --_currentLevel; } - virtual void apply(const BVHStaticLeaf& node, const BVHStaticData& data) - { - addNodeBox(node, data); - } virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) { addNodeBox(node, data); diff --git a/simgear/scene/bvh/BVHLineSegmentVisitor.cxx b/simgear/scene/bvh/BVHLineSegmentVisitor.cxx index d4dbd194..6475ce2b 100644 --- a/simgear/scene/bvh/BVHLineSegmentVisitor.cxx +++ b/simgear/scene/bvh/BVHLineSegmentVisitor.cxx @@ -31,7 +31,6 @@ #include "BVHStaticData.hxx" #include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" #include "BVHStaticTriangle.hxx" #include "BVHStaticBinary.hxx" @@ -131,12 +130,6 @@ BVHLineSegmentVisitor::apply(const BVHStaticBinary& node, node.traverse(*this, data, _lineSegment.getStart()); } -void -BVHLineSegmentVisitor::apply(const BVHStaticLeaf& node, - const BVHStaticData& data) -{ -} - void BVHLineSegmentVisitor::apply(const BVHStaticTriangle& triangle, const BVHStaticData& data) diff --git a/simgear/scene/bvh/BVHLineSegmentVisitor.hxx b/simgear/scene/bvh/BVHLineSegmentVisitor.hxx index db3508bc..5801e5d3 100644 --- a/simgear/scene/bvh/BVHLineSegmentVisitor.hxx +++ b/simgear/scene/bvh/BVHLineSegmentVisitor.hxx @@ -62,7 +62,6 @@ public: virtual void apply(BVHStaticGeometry& node); virtual void apply(const BVHStaticBinary&, const BVHStaticData&); - virtual void apply(const BVHStaticLeaf&, const BVHStaticData&); virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); protected: diff --git a/simgear/scene/bvh/BVHNearestPointVisitor.hxx b/simgear/scene/bvh/BVHNearestPointVisitor.hxx new file mode 100644 index 00000000..c5f1add8 --- /dev/null +++ b/simgear/scene/bvh/BVHNearestPointVisitor.hxx @@ -0,0 +1,161 @@ +// Copyright (C) 2008 - 2009 Mathias Froehlich - Mathias.Froehlich@web.de +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef BVHNearestPointVisitor_hxx +#define BVHNearestPointVisitor_hxx + +#include + +#include "BVHVisitor.hxx" + +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" +#include "BVHLineGeometry.hxx" +#include "BVHStaticGeometry.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" + +namespace simgear { + +class BVHNearestPointVisitor : public BVHVisitor { +public: + BVHNearestPointVisitor(const SGSphered& sphere, const double& t) : + _sphere(sphere), + _time(t), + _material(0), + _havePoint(false) + { } + + virtual void apply(BVHGroup& leaf) + { + if (!intersects(_sphere, leaf.getBoundingSphere())) + return; + leaf.traverse(*this); + } + virtual void apply(BVHTransform& transform) + { + if (!intersects(_sphere, transform.getBoundingSphere())) + return; + + SGSphered sphere = _sphere; + _sphere = transform.sphereToLocal(sphere); + bool havePoint = _havePoint; + _havePoint = false; + + transform.traverse(*this); + + if (_havePoint) { + _point = transform.ptToWorld(_point); + _linearVelocity = transform.vecToWorld(_linearVelocity); + _angularVelocity = transform.vecToWorld(_angularVelocity); + } + _havePoint |= havePoint; + _sphere.setCenter(sphere.getCenter()); + } + virtual void apply(BVHMotionTransform& transform) + { + if (!intersects(_sphere, transform.getBoundingSphere())) + return; + + SGSphered sphere = _sphere; + _sphere = transform.sphereToLocal(sphere, _time); + bool havePoint = _havePoint; + _havePoint = false; + + transform.traverse(*this); + + if (_havePoint) { + SGMatrixd toWorld = transform.getToWorldTransform(_time); + SGVec3d localCenter = _sphere.getCenter(); + _linearVelocity += transform.getLinearVelocityAt(localCenter); + _angularVelocity += transform.getAngularVelocity(); + _linearVelocity = toWorld.xformVec(_linearVelocity); + _angularVelocity = toWorld.xformVec(_angularVelocity); + _point = toWorld.xformPt(_point); + } + _havePoint |= havePoint; + _sphere.setCenter(sphere.getCenter()); + } + virtual void apply(BVHLineGeometry& node) + { } + virtual void apply(BVHStaticGeometry& node) + { + if (!intersects(_sphere, node.getBoundingSphere())) + return; + node.traverse(*this); + } + + virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) + { + if (!intersects(_sphere, node.getBoundingBox())) + return; + node.traverse(*this, data, _sphere.getCenter()); + } + virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) + { + SGVec3f center(_sphere.getCenter()); + SGVec3d closest(closestPoint(node.getTriangle(data), center)); + if (!intersects(_sphere, closest)) + return; + _point = closest; + _linearVelocity = SGVec3d::zeros(); + _angularVelocity = SGVec3d::zeros(); + _material = data.getMaterial(node.getMaterialIndex()); + // The trick is to decrease the radius of the search sphere. + _sphere.setRadius(length(closest - _sphere.getCenter())); + _havePoint = true; + } + + void setSphere(const SGSphered& sphere) + { _sphere = sphere; } + const SGSphered& getSphere() const + { return _sphere; } + + const SGVec3d& getPoint() const + { return _point; } + const SGVec3d& getLinearVelocity() const + { return _linearVelocity; } + const SGVec3d& getAngularVelocity() const + { return _angularVelocity; } + const SGMaterial* getMaterial() const + { return _material; } + + bool getHavePoint() const + { return _havePoint; } + bool empty() const + { return !_havePoint; } + +private: + SGSphered _sphere; + double _time; + + SGVec3d _point; + SGVec3d _linearVelocity; + SGVec3d _angularVelocity; + const SGMaterial* _material; + + bool _havePoint; +}; + +} + +#endif diff --git a/simgear/scene/bvh/BVHStaticLeaf.cxx b/simgear/scene/bvh/BVHStaticLeaf.cxx index 67137530..29c2e04f 100644 --- a/simgear/scene/bvh/BVHStaticLeaf.cxx +++ b/simgear/scene/bvh/BVHStaticLeaf.cxx @@ -24,10 +24,4 @@ BVHStaticLeaf::~BVHStaticLeaf() { } -void -BVHStaticLeaf::accept(BVHVisitor& visitor, const BVHStaticData& data) const -{ - visitor.apply(*this, data); -} - } diff --git a/simgear/scene/bvh/BVHStaticLeaf.hxx b/simgear/scene/bvh/BVHStaticLeaf.hxx index 3a7682f7..99d2959d 100644 --- a/simgear/scene/bvh/BVHStaticLeaf.hxx +++ b/simgear/scene/bvh/BVHStaticLeaf.hxx @@ -27,7 +27,7 @@ class BVHStaticLeaf : public BVHStaticNode { public: virtual ~BVHStaticLeaf(); - virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const; + virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const = 0; virtual SGBoxf computeBoundingBox(const BVHStaticData&) const = 0; virtual SGVec3f computeCenter(const BVHStaticData&) const = 0; diff --git a/simgear/scene/bvh/BVHSubTreeCollector.cxx b/simgear/scene/bvh/BVHSubTreeCollector.cxx index cc7596be..d8c6017f 100644 --- a/simgear/scene/bvh/BVHSubTreeCollector.cxx +++ b/simgear/scene/bvh/BVHSubTreeCollector.cxx @@ -26,7 +26,6 @@ #include "BVHStaticData.hxx" #include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" #include "BVHStaticTriangle.hxx" #include "BVHStaticBinary.hxx" #include "BVHStaticGeometry.hxx" @@ -180,15 +179,6 @@ BVHSubTreeCollector::apply(const BVHStaticBinary& node, } } -void -BVHSubTreeCollector::apply(const BVHStaticLeaf& node, - const BVHStaticData& data) -{ - if (!intersects(_sphere, node.computeBoundingBox(data))) - return; - _staticNode = &node; -} - void BVHSubTreeCollector::apply(const BVHStaticTriangle& node, const BVHStaticData& data) diff --git a/simgear/scene/bvh/BVHSubTreeCollector.hxx b/simgear/scene/bvh/BVHSubTreeCollector.hxx index b29d6274..aa3e1124 100644 --- a/simgear/scene/bvh/BVHSubTreeCollector.hxx +++ b/simgear/scene/bvh/BVHSubTreeCollector.hxx @@ -49,7 +49,6 @@ public: virtual void apply(BVHStaticGeometry&); virtual void apply(const BVHStaticBinary&, const BVHStaticData&); - virtual void apply(const BVHStaticLeaf&, const BVHStaticData&); virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); void setSphere(const SGSphered& sphere) diff --git a/simgear/scene/bvh/BVHVisitor.hxx b/simgear/scene/bvh/BVHVisitor.hxx index 058cf27c..f74f4456 100644 --- a/simgear/scene/bvh/BVHVisitor.hxx +++ b/simgear/scene/bvh/BVHVisitor.hxx @@ -29,7 +29,6 @@ class BVHStaticGeometry; class BVHLineGeometry; class BVHStaticBinary; -class BVHStaticLeaf; class BVHStaticTriangle; class BVHVisitor { @@ -49,7 +48,6 @@ public: // Static tree nodes to handle virtual void apply(const BVHStaticBinary&, const BVHStaticData&) = 0; - virtual void apply(const BVHStaticLeaf&, const BVHStaticData&) = 0; virtual void apply(const BVHStaticTriangle&, const BVHStaticData&) = 0; }; diff --git a/simgear/scene/bvh/Makefile.am b/simgear/scene/bvh/Makefile.am index 0b1be985..c880a313 100644 --- a/simgear/scene/bvh/Makefile.am +++ b/simgear/scene/bvh/Makefile.am @@ -17,6 +17,7 @@ include_HEADERS = \ BVHLineSegmentVisitor.hxx \ BVHLineGeometry.hxx \ BVHMotionTransform.hxx \ + BVHNearestPointVisitor.hxx \ BVHNode.hxx \ BVHStaticBinary.hxx \ BVHStaticData.hxx \ diff --git a/simgear/scene/bvh/bvhtest.cxx b/simgear/scene/bvh/bvhtest.cxx index 797299cb..0f01e7f0 100644 --- a/simgear/scene/bvh/bvhtest.cxx +++ b/simgear/scene/bvh/bvhtest.cxx @@ -33,6 +33,7 @@ #include "BVHBoundingBoxVisitor.hxx" #include "BVHSubTreeCollector.hxx" #include "BVHLineSegmentVisitor.hxx" +#include "BVHNearestPointVisitor.hxx" using namespace simgear; @@ -109,10 +110,33 @@ testLineIntersections() return true; } +bool +testNearestPoint() +{ + SGVec3f v1(-1, -1, 0); + SGVec3f v2(1, -1, 0); + SGVec3f v3(-1, 1, 0); + SGSharedPtr node = buildSingleTriangle(v1, v2, v3); + + SGSphered sphere(SGVec3d(0, 0, -1), 2); + { + BVHNearestPointVisitor nearestPointVisitor(sphere, 0); + node->accept(nearestPointVisitor); + if (nearestPointVisitor.empty()) + return false; + if (!equivalent(nearestPointVisitor.getPoint(), SGVec3d(0, 0, 0))) + return false; + } + + return true; +} + int main(int argc, char** argv) { if (!testLineIntersections()) return EXIT_FAILURE; + if (!testNearestPoint()) + return EXIT_FAILURE; return EXIT_SUCCESS; } -- 2.39.5