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
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
-#include "BVHStaticLeaf.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
#include "BVHStaticGeometry.hxx"
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)); }
#include <osg/PolygonOffset>
#include <osg/PrimitiveSet>
#include <osg/MatrixTransform>
-#include <osg/PositionAttitudeTransform>
#include <osg/ShapeDrawable>
#include <osg/Shape>
#include <osg/Depth>
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
-#include "BVHStaticLeaf.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
{
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);
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);
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
-#include "BVHStaticLeaf.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
node.traverse(*this, data, _lineSegment.getStart());
}
-void
-BVHLineSegmentVisitor::apply(const BVHStaticLeaf& node,
- const BVHStaticData& data)
-{
-}
-
void
BVHLineSegmentVisitor::apply(const BVHStaticTriangle& triangle,
const BVHStaticData& data)
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:
--- /dev/null
+// 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
{
}
-void
-BVHStaticLeaf::accept(BVHVisitor& visitor, const BVHStaticData& data) const
-{
- visitor.apply(*this, data);
-}
-
}
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;
#include "BVHStaticData.hxx"
#include "BVHStaticNode.hxx"
-#include "BVHStaticLeaf.hxx"
#include "BVHStaticTriangle.hxx"
#include "BVHStaticBinary.hxx"
#include "BVHStaticGeometry.hxx"
}
}
-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)
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)
class BVHLineGeometry;
class BVHStaticBinary;
-class BVHStaticLeaf;
class BVHStaticTriangle;
class BVHVisitor {
// 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;
};
BVHLineSegmentVisitor.hxx \
BVHLineGeometry.hxx \
BVHMotionTransform.hxx \
+ BVHNearestPointVisitor.hxx \
BVHNode.hxx \
BVHStaticBinary.hxx \
BVHStaticData.hxx \
#include "BVHBoundingBoxVisitor.hxx"
#include "BVHSubTreeCollector.hxx"
#include "BVHLineSegmentVisitor.hxx"
+#include "BVHNearestPointVisitor.hxx"
using namespace simgear;
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;
}