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
This commit is contained in:
frohlich
2009-03-02 18:02:50 +00:00
committed by Tim Moore
parent 7f534a7966
commit addf47600d
12 changed files with 189 additions and 46 deletions

View File

@@ -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)); }

View File

@@ -25,7 +25,6 @@
#include <osg/PolygonOffset>
#include <osg/PrimitiveSet>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/ShapeDrawable>
#include <osg/Shape>
#include <osg/Depth>
@@ -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<osg::Group> oldGroup = _group;
osg::ref_ptr<osg::PositionAttitudeTransform> transform;
transform = new osg::PositionAttitudeTransform;
osg::ref_ptr<osg::MatrixTransform> 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);

View File

@@ -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)

View File

@@ -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:

View File

@@ -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 <simgear/math/SGGeometry.hxx>
#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

View File

@@ -24,10 +24,4 @@ BVHStaticLeaf::~BVHStaticLeaf()
{
}
void
BVHStaticLeaf::accept(BVHVisitor& visitor, const BVHStaticData& data) const
{
visitor.apply(*this, data);
}
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;
};

View File

@@ -17,6 +17,7 @@ include_HEADERS = \
BVHLineSegmentVisitor.hxx \
BVHLineGeometry.hxx \
BVHMotionTransform.hxx \
BVHNearestPointVisitor.hxx \
BVHNode.hxx \
BVHStaticBinary.hxx \
BVHStaticData.hxx \

View File

@@ -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<BVHNode> 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;
}