From: Mathias Froehlich Date: Fri, 24 Aug 2012 19:20:40 +0000 (+0200) Subject: bvh: Move the basic bounding volume tree functionality into core. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=22878b6f897abb5895cd7054f4ea666666fa6778;p=simgear.git bvh: Move the basic bounding volume tree functionality into core. The basic boundignvolume implementation does only need math and geometry. As such it is agnostic to the scenegraph being used. Only the parts building this query structure from terrain depend on the implementation of the terrain. So, move this into the simgear core component. --- diff --git a/simgear/CMakeLists.txt b/simgear/CMakeLists.txt index 1ab291e3..a613805f 100644 --- a/simgear/CMakeLists.txt +++ b/simgear/CMakeLists.txt @@ -3,6 +3,7 @@ file(WRITE ${PROJECT_BINARY_DIR}/simgear/version.h "#define SIMGEAR_VERSION ${SI foreach( mylibfolder bucket + bvh debug ephemeris io diff --git a/simgear/bvh/.gitignore b/simgear/bvh/.gitignore new file mode 100644 index 00000000..8a0ce98b --- /dev/null +++ b/simgear/bvh/.gitignore @@ -0,0 +1,2 @@ +bvhtest + diff --git a/simgear/bvh/BVHBoundingBoxVisitor.hxx b/simgear/bvh/BVHBoundingBoxVisitor.hxx new file mode 100644 index 00000000..d37779c3 --- /dev/null +++ b/simgear/bvh/BVHBoundingBoxVisitor.hxx @@ -0,0 +1,80 @@ +// 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 BVHBoundingBoxVisitor_hxx +#define BVHBoundingBoxVisitor_hxx + +#include + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" +#include "BVHMotionTransform.hxx" +#include "BVHLineGeometry.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" +#include "BVHStaticGeometry.hxx" + +namespace simgear { + +class BVHBoundingBoxVisitor : public BVHVisitor { +public: + virtual ~BVHBoundingBoxVisitor() {} + + void clear() + { _box.clear(); } + + virtual void apply(BVHGroup& node) + { expandBy(node.getBoundingSphere()); } + virtual void apply(BVHTransform& node) + { expandBy(node.getBoundingSphere()); } + virtual void apply(BVHMotionTransform& node) + { expandBy(node.getBoundingSphere()); } + virtual void apply(BVHLineGeometry& node) + { expandBy(node.getBoundingSphere()); } + virtual void apply(BVHStaticGeometry& node) + { expandBy(node.getBoundingSphere()); } + + virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) + { expandBy(node.getBoundingBox()); } + virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) + { expandBy(node.computeBoundingBox(data)); } + + const SGBoxf& getBox() const + { return _box; } + +private: + void expandBy(const SGSphered& sphere) + { + SGVec3f v0(sphere.getCenter() - sphere.getRadius()*SGVec3d(1, 1, 1)); + SGVec3f v1(sphere.getCenter() + sphere.getRadius()*SGVec3d(1, 1, 1)); + _box.expandBy(SGBoxf(v0, v1)); + } + void expandBy(const SGBoxf& box) + { _box.expandBy(box); } + + SGBoxf _box; +}; + +} + +#endif diff --git a/simgear/bvh/BVHGroup.cxx b/simgear/bvh/BVHGroup.cxx new file mode 100644 index 00000000..d444791c --- /dev/null +++ b/simgear/bvh/BVHGroup.cxx @@ -0,0 +1,92 @@ +// 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. +// + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "BVHGroup.hxx" + +#include + +namespace simgear { + +BVHGroup::BVHGroup() +{ +} + +BVHGroup::~BVHGroup() +{ + ChildList::iterator i; + for (i = _children.begin(); i != _children.end(); ++i) { + (*i)->removeParent(this); + *i = 0; + } +} + +void +BVHGroup::accept(BVHVisitor& visitor) +{ + visitor.apply(*this); +} + +void +BVHGroup::clear() +{ + _children.clear(); + invalidateBound(); +} + +void +BVHGroup::addChild(BVHNode* child) +{ + if (!child) + return; + ChildList::iterator i; + i = std::find(_children.begin(), _children.end(), child); + if (i != _children.end()) + return; + invalidateBound(); + child->addParent(this); + _children.push_back(child); +} + +void +BVHGroup::removeChild(BVHNode* child) +{ + if (!child) + return; + ChildList::iterator i; + i = std::find(_children.begin(), _children.end(), child); + if (i == _children.end()) + return; + invalidateBound(); + child->removeParent(this); + _children.erase(i); +} + +SGSphered +BVHGroup::computeBoundingSphere() const +{ + SGSphered sphere; + ChildList::const_iterator i; + for (i = _children.begin(); i != _children.end(); ++i) + sphere.expandBy((*i)->getBoundingSphere()); + return sphere; +} + +} diff --git a/simgear/bvh/BVHGroup.hxx b/simgear/bvh/BVHGroup.hxx new file mode 100644 index 00000000..d0b58363 --- /dev/null +++ b/simgear/bvh/BVHGroup.hxx @@ -0,0 +1,61 @@ +// 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 BVHGroup_hxx +#define BVHGroup_hxx + +#include +#include "BVHNode.hxx" +#include "BVHVisitor.hxx" + +namespace simgear { + +class BVHGroup : public BVHNode { +public: + BVHGroup(); + virtual ~BVHGroup(); + + virtual void accept(BVHVisitor& visitor); + + void traverse(BVHVisitor& visitor) + { + ChildList::const_iterator i; + for (i = _children.begin(); i != _children.end(); ++i) + (*i)->accept(visitor); + } + + void clear(); + void addChild(BVHNode* child); + void removeChild(BVHNode* child); + + unsigned getNumChildren() const + { return _children.size(); } + const BVHNode* getChild(unsigned i) const + { if (_children.size() <= i) return 0; return _children[i]; } + BVHNode* getChild(unsigned i) + { if (_children.size() <= i) return 0; return _children[i]; } + + virtual SGSphered computeBoundingSphere() const; + +private: + typedef std::vector > ChildList; + ChildList _children; +}; + +} + +#endif diff --git a/simgear/bvh/BVHLineGeometry.cxx b/simgear/bvh/BVHLineGeometry.cxx new file mode 100644 index 00000000..679a4675 --- /dev/null +++ b/simgear/bvh/BVHLineGeometry.cxx @@ -0,0 +1,49 @@ +// 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. +// + +#include "BVHLineGeometry.hxx" + +#include "BVHVisitor.hxx" + +namespace simgear { + +BVHLineGeometry::BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type) : + _lineSegment(lineSegment), + _type(type) +{ +} + +BVHLineGeometry::~BVHLineGeometry() +{ +} + +void +BVHLineGeometry::accept(BVHVisitor& visitor) +{ + visitor.apply(*this); +} + +SGSphered +BVHLineGeometry::computeBoundingSphere() const +{ + SGSphered sphere; + sphere.expandBy(SGVec3d(_lineSegment.getStart())); + sphere.expandBy(SGVec3d(_lineSegment.getEnd())); + return sphere; +} + +} diff --git a/simgear/bvh/BVHLineGeometry.hxx b/simgear/bvh/BVHLineGeometry.hxx new file mode 100644 index 00000000..d0d87211 --- /dev/null +++ b/simgear/bvh/BVHLineGeometry.hxx @@ -0,0 +1,53 @@ +// 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 BVHLineGeometry_hxx +#define BVHLineGeometry_hxx + +#include +#include "BVHNode.hxx" + +namespace simgear { + +class BVHLineGeometry : public BVHNode { +public: + enum Type { + CarrierCatapult, + CarrierWire + }; + + BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type); + virtual ~BVHLineGeometry(); + + virtual void accept(BVHVisitor& visitor); + + const SGLineSegmentf& getLineSegment() const + { return _lineSegment; } + + Type getType() const + { return _type; } + + virtual SGSphered computeBoundingSphere() const; + +private: + SGLineSegmentf _lineSegment; + Type _type; +}; + +} + +#endif diff --git a/simgear/bvh/BVHLineSegmentVisitor.cxx b/simgear/bvh/BVHLineSegmentVisitor.cxx new file mode 100644 index 00000000..1b93cd09 --- /dev/null +++ b/simgear/bvh/BVHLineSegmentVisitor.cxx @@ -0,0 +1,157 @@ +// 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. +// + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "BVHLineSegmentVisitor.hxx" + +#include + +#include "BVHVisitor.hxx" + +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" +#include "BVHMotionTransform.hxx" +#include "BVHLineGeometry.hxx" +#include "BVHStaticGeometry.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" + +namespace simgear { + +void +BVHLineSegmentVisitor::apply(BVHGroup& group) +{ + if (!intersects(_lineSegment, group.getBoundingSphere())) + return; + group.traverse(*this); +} + +void +BVHLineSegmentVisitor::apply(BVHTransform& transform) +{ + if (!intersects(_lineSegment, transform.getBoundingSphere())) + return; + + bool haveHit = _haveHit; + _haveHit = false; + + // Push the line segment + SGLineSegmentd lineSegment = getLineSegment(); + _lineSegment = transform.lineSegmentToLocal(lineSegment); + + transform.traverse(*this); + + if (_haveHit) { + _linearVelocity = transform.vecToWorld(_linearVelocity); + _angularVelocity = transform.vecToWorld(_angularVelocity); + SGVec3d point(transform.ptToWorld(_lineSegment.getEnd())); + _lineSegment.set(lineSegment.getStart(), point); + _normal = transform.vecToWorld(_normal); + } else { + _lineSegment = lineSegment; + _haveHit = haveHit; + } +} + +void +BVHLineSegmentVisitor::apply(BVHMotionTransform& transform) +{ + if (!intersects(_lineSegment, transform.getBoundingSphere())) + return; + + bool haveHit = _haveHit; + _haveHit = false; + + // Push the line segment + SGLineSegmentd lineSegment = getLineSegment(); + SGMatrixd toLocal = transform.getToLocalTransform(_time); + _lineSegment = lineSegment.transform(toLocal); + + transform.traverse(*this); + + if (_haveHit) { + SGMatrixd toWorld = transform.getToWorldTransform(_time); + SGVec3d localStart = _lineSegment.getStart(); + _linearVelocity += transform.getLinearVelocityAt(localStart); + _angularVelocity += transform.getAngularVelocity(); + _linearVelocity = toWorld.xformVec(_linearVelocity); + _angularVelocity = toWorld.xformVec(_angularVelocity); + SGVec3d localEnd = _lineSegment.getEnd(); + _lineSegment.set(lineSegment.getStart(), toWorld.xformPt(localEnd)); + _normal = toWorld.xformVec(_normal); + if (!_id) + _id = transform.getId(); + } else { + _lineSegment = lineSegment; + _haveHit = haveHit; + } +} + +void +BVHLineSegmentVisitor::apply(BVHLineGeometry&) +{ +} + +void +BVHLineSegmentVisitor::apply(BVHStaticGeometry& node) +{ + if (!intersects(_lineSegment, node.getBoundingSphere())) + return; + node.traverse(*this); +} + +void +BVHLineSegmentVisitor::apply(const BVHStaticBinary& node, + const BVHStaticData& data) +{ + if (!intersects(SGLineSegmentf(_lineSegment), node.getBoundingBox())) + return; + + // The first box to enter is the one the startpoint is in. + // this increases the probability, that on exit of that box we do not + // even need to walk the other one, since the line segment is + // then already short enough to not intersect the other one anymore. + node.traverse(*this, data, _lineSegment.getStart()); +} + +void +BVHLineSegmentVisitor::apply(const BVHStaticTriangle& triangle, + const BVHStaticData& data) +{ + SGTrianglef tri = triangle.getTriangle(data); + SGVec3f point; + if (!intersects(point, tri, SGLineSegmentf(_lineSegment), 1e-4f)) + return; + setLineSegmentEnd(SGVec3d(point)); + _normal = SGVec3d(tri.getNormal()); + _linearVelocity = SGVec3d::zeros(); + _angularVelocity = SGVec3d::zeros(); + _material = data.getMaterial(triangle.getMaterialIndex()); + _id = 0; + _haveHit = true; +} + + +} diff --git a/simgear/bvh/BVHLineSegmentVisitor.hxx b/simgear/bvh/BVHLineSegmentVisitor.hxx new file mode 100644 index 00000000..cca02588 --- /dev/null +++ b/simgear/bvh/BVHLineSegmentVisitor.hxx @@ -0,0 +1,98 @@ +// 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 BVHLineSegmentVisitor_hxx +#define BVHLineSegmentVisitor_hxx + +#include +#include +#include + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" + +namespace simgear { + +class BVHLineSegmentVisitor : public BVHVisitor { +public: + BVHLineSegmentVisitor(const SGLineSegmentd& lineSegment, + const double& t = 0) : + _lineSegment(lineSegment), + _time(t), + _material(0), + _id(0), + _haveHit(false) + { } + virtual ~BVHLineSegmentVisitor() + { } + + bool empty() const + { return !_haveHit; } + + const SGLineSegmentd& getLineSegment() const + { return _lineSegment; } + + SGVec3d getPoint() const + { return _lineSegment.getEnd(); } + const SGVec3d& getNormal() const + { return _normal; } + const SGVec3d& getLinearVelocity() const + { return _linearVelocity; } + const SGVec3d& getAngularVelocity() const + { return _angularVelocity; } + const SGMaterial* getMaterial() const + { return _material; } + BVHNode::Id getId() const + { return _id; } + + virtual void apply(BVHGroup& group); + virtual void apply(BVHTransform& transform); + virtual void apply(BVHMotionTransform& transform); + virtual void apply(BVHLineGeometry&); + virtual void apply(BVHStaticGeometry& node); + + virtual void apply(const BVHStaticBinary&, const BVHStaticData&); + virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); + +protected: + void setLineSegmentEnd(const SGVec3d& end) + { + // Ok, you need to make sure that the new end is in the previous + // direction and that the line segment is not enlarged by that call. +#ifndef _NDEBUG + // FIXME insert code to check this... +#endif + _lineSegment.set(_lineSegment.getStart(), end); + } + +private: + SGLineSegmentd _lineSegment; + double _time; + + // belongs in a derived class + SGVec3d _normal; + SGVec3d _linearVelocity; + SGVec3d _angularVelocity; + const SGMaterial* _material; + BVHNode::Id _id; + + bool _haveHit; +}; + +} + +#endif diff --git a/simgear/bvh/BVHMotionTransform.cxx b/simgear/bvh/BVHMotionTransform.cxx new file mode 100644 index 00000000..249c0784 --- /dev/null +++ b/simgear/bvh/BVHMotionTransform.cxx @@ -0,0 +1,120 @@ +// 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. +// + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "BVHMotionTransform.hxx" + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" + +namespace simgear { + +BVHMotionTransform::BVHMotionTransform() : + _toWorldReference(SGMatrixd::unit()), + _toLocalReference(SGMatrixd::unit()), + _toWorldAmplification(1), + _toLocalAmplification(1), + _linearVelocity(0, 0, 0), + _angularVelocity(0, 0, 0), + _referenceTime(0), + _startTime(0), + _endTime(0), + _id(0) +{ +} + +BVHMotionTransform::~BVHMotionTransform() +{ +} + +void +BVHMotionTransform::accept(BVHVisitor& visitor) +{ + visitor.apply(*this); +} + +void +BVHMotionTransform::setTransform(const BVHMotionTransform& transform) +{ + _toWorldReference = transform._toWorldReference; + _toLocalReference = transform._toLocalReference; + _toWorldAmplification = transform._toWorldAmplification; + _toLocalAmplification = transform._toLocalAmplification; + _linearVelocity = transform._linearVelocity; + _angularVelocity = transform._angularVelocity; + _referenceTime = transform._referenceTime; + _startTime = transform._startTime; + _endTime = transform._endTime; + _id = transform._id; + invalidateParentBound(); +} + +void +BVHMotionTransform::setToWorldTransform(const SGMatrixd& transform) +{ + _toWorldReference = transform; + invert(_toLocalReference, transform); + updateAmplificationFactors(); + invalidateParentBound(); +} + +void +BVHMotionTransform::setToLocalTransform(const SGMatrixd& transform) +{ + _toLocalReference = transform; + invert(_toWorldReference, transform); + updateAmplificationFactors(); + invalidateParentBound(); +} + +SGSphered +BVHMotionTransform::computeBoundingSphere() const +{ + SGSphered sphere(BVHGroup::computeBoundingSphere()); + if (sphere.empty()) + return sphere; + SGMatrixd toWorldStart = getToWorldTransform(_startTime); + SGVec3d centerStart = toWorldStart.xformPt(sphere.getCenter()); + SGMatrixd toWorldEnd = getToWorldTransform(_endTime); + SGVec3d centerEnd = toWorldEnd.xformPt(sphere.getCenter()); + double rad = 0.5*length(centerStart - centerEnd) + sphere.getRadius(); + rad *= _toWorldAmplification; + return SGSphered(0.5*(centerStart + centerEnd), rad); +} + +void +BVHMotionTransform::updateAmplificationFactors() +{ + // Hmm, this is just a hint, true? + // But anyway, almost all transforms in a scenegraph will + // have them equal to 1 ... + double r = norm(_toWorldReference.xformVec(SGVec3d(1, 0, 0))); + r = SGMiscd::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 1, 0)))); + r = SGMiscd::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 0, 1)))); + _toWorldAmplification = r; + + r = norm(_toLocalReference.xformVec(SGVec3d(1, 0, 0))); + r = SGMiscd::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 1, 0)))); + r = SGMiscd::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 0, 1)))); + _toLocalAmplification = r; +} + +} diff --git a/simgear/bvh/BVHMotionTransform.hxx b/simgear/bvh/BVHMotionTransform.hxx new file mode 100644 index 00000000..d1a401e3 --- /dev/null +++ b/simgear/bvh/BVHMotionTransform.hxx @@ -0,0 +1,126 @@ +// 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 BVHMotionTransform_hxx +#define BVHMotionTransform_hxx + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" + +namespace simgear { + +class BVHMotionTransform : public BVHGroup { +public: + BVHMotionTransform(); + virtual ~BVHMotionTransform(); + + virtual void accept(BVHVisitor& visitor); + + void setTransform(const BVHMotionTransform& transform); + void setToWorldTransform(const SGMatrixd& transform); + void setToLocalTransform(const SGMatrixd& transform); + + void setLinearVelocity(const SGVec3d& linearVelocity) + { _linearVelocity = linearVelocity; } + const SGVec3d& getLinearVelocity() const + { return _linearVelocity; } + + void setAngularVelocity(const SGVec3d& angularVelocity) + { _angularVelocity = angularVelocity; } + const SGVec3d& getAngularVelocity() const + { return _angularVelocity; } + + void setReferenceTime(const double& referenceTime) + { _referenceTime = referenceTime; } + const double& getReferenceTime() const + { return _referenceTime; } + + void setStartTime(const double& startTime) + { _startTime = startTime; } + const double& getStartTime() const + { return _startTime; } + + void setEndTime(const double& endTime) + { _endTime = endTime; } + const double& getEndTime() const + { return _endTime; } + + SGMatrixd getToWorldTransform(const double& t) const + { + if (t == _referenceTime) + return _toWorldReference; + double dt = t - _referenceTime; + SGMatrixd matrix(_toWorldReference); + matrix.postMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity)); + matrix.postMultTranslate(dt*_linearVelocity); + return matrix; + } + SGMatrixd getToLocalTransform(const double& t) const + { + if (t == _referenceTime) + return _toLocalReference; + double dt = _referenceTime - t; + SGMatrixd matrix(_toLocalReference); + matrix.preMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity)); + matrix.preMultTranslate(dt*_linearVelocity); + return matrix; + } + + const SGMatrixd& getToWorldReferenceTransform() const + { return _toWorldReference; } + const SGMatrixd& getToLocalReferenceTransform() const + { return _toLocalReference; } + + SGVec3d getLinearVelocityAt(const SGVec3d& reference) const + { return _linearVelocity + cross(_angularVelocity, reference); } + + SGSphered sphereToLocal(const SGSphered& sphere, const double& t) const + { + SGMatrixd matrix = getToLocalTransform(t); + SGVec3d center = matrix.xformPt(sphere.getCenter()); + double radius = _toLocalAmplification*sphere.getRadius(); + return SGSphered(center, radius); + } + + void setId(Id id) + { _id = id; } + Id getId() const + { return _id; } + +private: + virtual SGSphered computeBoundingSphere() const; + void updateAmplificationFactors(); + + SGMatrixd _toWorldReference; + SGMatrixd _toLocalReference; + double _toWorldAmplification; + double _toLocalAmplification; + + SGVec3d _linearVelocity; + SGVec3d _angularVelocity; + + double _referenceTime; + double _startTime; + double _endTime; + + Id _id; +}; + +} + +#endif diff --git a/simgear/bvh/BVHNearestPointVisitor.hxx b/simgear/bvh/BVHNearestPointVisitor.hxx new file mode 100644 index 00000000..1c07c66a --- /dev/null +++ b/simgear/bvh/BVHNearestPointVisitor.hxx @@ -0,0 +1,166 @@ +// 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), + _id(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); + if (!_id) + _id = transform.getId(); + } + _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; + _id = 0; + } + + 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; } + BVHNode::Id getId() const + { return _id; } + + bool empty() const + { return !_havePoint; } + +private: + SGSphered _sphere; + double _time; + + SGVec3d _point; + SGVec3d _linearVelocity; + SGVec3d _angularVelocity; + const SGMaterial* _material; + BVHNode::Id _id; + + bool _havePoint; +}; + +} + +#endif diff --git a/simgear/bvh/BVHNode.cxx b/simgear/bvh/BVHNode.cxx new file mode 100644 index 00000000..d4b1ca5f --- /dev/null +++ b/simgear/bvh/BVHNode.cxx @@ -0,0 +1,80 @@ +// 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. +// + +#include "BVHNode.hxx" + +#include +#include +#include + +namespace simgear { + +BVHNode::BVHNode() : + _dirtyBoundingSphere(true) +{ +} + +BVHNode::~BVHNode() +{ +} + +BVHNode::Id +BVHNode::getNewId() +{ + static SGAtomic id(0); + return ++id; +} + +void +BVHNode::addParent(BVHNode* parent) +{ + // should not happen, but be paranoid ... + ParentList::iterator i; + i = std::find(_parents.begin(), _parents.end(), parent); + if (i != _parents.end()) + return; + // add to the parents list ... + _parents.push_back(parent); +} + +void +BVHNode::removeParent(BVHNode* parent) +{ + ParentList::iterator i; + i = std::find(_parents.begin(), _parents.end(), parent); + if (i == _parents.end()) + return; + _parents.erase(i); +} + +void +BVHNode::invalidateParentBound() +{ + for (ParentList::iterator i = _parents.begin(); i != _parents.end(); ++i) + (*i)->invalidateBound(); +} + +void +BVHNode::invalidateBound() +{ + if (_dirtyBoundingSphere) + return; + invalidateParentBound(); + _dirtyBoundingSphere = true; +} + +} diff --git a/simgear/bvh/BVHNode.hxx b/simgear/bvh/BVHNode.hxx new file mode 100644 index 00000000..10a0a957 --- /dev/null +++ b/simgear/bvh/BVHNode.hxx @@ -0,0 +1,74 @@ +// 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 BVHNode_hxx +#define BVHNode_hxx + +#include +#include +#include + +namespace simgear { + +class BVHGroup; +class BVHVisitor; + +// Base for the tree nodes +class BVHNode : public SGReferenced { +public: + BVHNode(); + virtual ~BVHNode(); + + // visitors ... + virtual void accept(BVHVisitor& visitor) = 0; + + const SGSphered& getBoundingSphere() const + { + if (_dirtyBoundingSphere) { + _boundingSphere = computeBoundingSphere(); + _dirtyBoundingSphere = false; + } + return _boundingSphere; + } + virtual SGSphered computeBoundingSphere() const = 0; + + /// A unique id for some kind of BVHNodes. + /// Currently only motions transforms. + typedef unsigned Id; + + // Factory to get a new id + static Id getNewId(); + +protected: + friend class BVHGroup; + void addParent(BVHNode* parent); + void removeParent(BVHNode* parent); + + void invalidateParentBound(); + virtual void invalidateBound(); + +private: + mutable bool _dirtyBoundingSphere; + mutable SGSphered _boundingSphere; + + typedef std::vector ParentList; + ParentList _parents; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticBinary.cxx b/simgear/bvh/BVHStaticBinary.cxx new file mode 100644 index 00000000..d98a35e0 --- /dev/null +++ b/simgear/bvh/BVHStaticBinary.cxx @@ -0,0 +1,45 @@ +// 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. +// + +#include "BVHStaticBinary.hxx" + +#include "BVHVisitor.hxx" + +namespace simgear { + +BVHStaticBinary::BVHStaticBinary(unsigned splitAxis, + const BVHStaticNode* leftChild, + const BVHStaticNode* rightChild, + const SGBoxf& boundingBox) : + _splitAxis(splitAxis), + _leftChild(leftChild), + _rightChild(rightChild), + _boundingBox(boundingBox) +{ +} + +BVHStaticBinary::~BVHStaticBinary() +{ +} + +void +BVHStaticBinary::accept(BVHVisitor& visitor, const BVHStaticData& data) const +{ + visitor.apply(*this, data); +} + +} diff --git a/simgear/bvh/BVHStaticBinary.hxx b/simgear/bvh/BVHStaticBinary.hxx new file mode 100644 index 00000000..05b8aa3b --- /dev/null +++ b/simgear/bvh/BVHStaticBinary.hxx @@ -0,0 +1,78 @@ +// 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 BVHStaticBinary_hxx +#define BVHStaticBinary_hxx + +#include +#include +#include "BVHStaticNode.hxx" + +namespace simgear { + +class BVHStaticBinary : public BVHStaticNode { +public: + BVHStaticBinary(unsigned splitAxis, const BVHStaticNode* leftChild, + const BVHStaticNode* rightChild, const SGBoxf& box); + virtual ~BVHStaticBinary(); + virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const; + + void traverse(BVHVisitor& visitor, const BVHStaticData& data) const + { + _leftChild->accept(visitor, data); + _rightChild->accept(visitor, data); + } + + // Traverse call that first enters the child node that is potentially closer + // to the given point than the other. + template + void traverse(BVHVisitor& visitor, const BVHStaticData& data, + const SGVec3& pt) const + { + float center = 0.5f*(_boundingBox.getMin()[_splitAxis] + + _boundingBox.getMax()[_splitAxis]); + if (pt[_splitAxis] < center) { + _leftChild->accept(visitor, data); + _rightChild->accept(visitor, data); + } else { + _rightChild->accept(visitor, data); + _leftChild->accept(visitor, data); + } + } + + unsigned getSplitAxis() const + { return _splitAxis; } + + const BVHStaticNode* getLeftChild() const + { return _leftChild; } + const BVHStaticNode* getRightChild() const + { return _rightChild; } + + const SGBoxf& getBoundingBox() const + { return _boundingBox; } + +private: + // Note the order of the members, this is to avoid padding + unsigned _splitAxis; + SGSharedPtr _leftChild; + SGSharedPtr _rightChild; + SGBoxf _boundingBox; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticData.hxx b/simgear/bvh/BVHStaticData.hxx new file mode 100644 index 00000000..400632ad --- /dev/null +++ b/simgear/bvh/BVHStaticData.hxx @@ -0,0 +1,61 @@ +// 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 BVHStaticData_hxx +#define BVHStaticData_hxx + +#include +#include +#include +#include + +/// FIXME, the SGMaterial class is too much tied to the scenegraph aspects of +/// the materials. Use some class more decribing the +/// nature of the surface we live on ... +class SGMaterial; + +namespace simgear { + +class BVHStaticData : public SGReferenced { +public: + virtual ~BVHStaticData() {} + + unsigned addVertex(const SGVec3f& vertex) + { _vertices.push_back(vertex); return _vertices.size() - 1; } + const SGVec3f& getVertex(unsigned i) const + { return _vertices[i]; } + + + unsigned addMaterial(const SGMaterial* material) + { _materials.push_back(material); return _materials.size() - 1; } + const SGMaterial* getMaterial(unsigned i) const + { if (_materials.size() <= i) return 0; return _materials[i]; } + + void trim() + { + std::vector(_vertices).swap(_vertices); + std::vector(_materials).swap(_materials); + } + +private: + std::vector _vertices; + std::vector _materials; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticGeometry.cxx b/simgear/bvh/BVHStaticGeometry.cxx new file mode 100644 index 00000000..a8479565 --- /dev/null +++ b/simgear/bvh/BVHStaticGeometry.cxx @@ -0,0 +1,51 @@ +// 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. +// + +#include "BVHStaticGeometry.hxx" + +#include "BVHBoundingBoxVisitor.hxx" + +namespace simgear { + +BVHStaticGeometry::BVHStaticGeometry(const BVHStaticNode* staticNode, + const BVHStaticData* staticData) : + _staticNode(staticNode), + _staticData(staticData) +{ +} + +BVHStaticGeometry::~BVHStaticGeometry() +{ +} + +void +BVHStaticGeometry::accept(BVHVisitor& visitor) +{ + visitor.apply(*this); +} + +SGSphered +BVHStaticGeometry::computeBoundingSphere() const +{ + BVHBoundingBoxVisitor bbv; + _staticNode->accept(bbv, *_staticData); + SGSphered sphere; + sphere.expandBy(SGBoxd(bbv.getBox())); + return sphere; +} + +} diff --git a/simgear/bvh/BVHStaticGeometry.hxx b/simgear/bvh/BVHStaticGeometry.hxx new file mode 100644 index 00000000..693d4ff8 --- /dev/null +++ b/simgear/bvh/BVHStaticGeometry.hxx @@ -0,0 +1,56 @@ +// 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 BVHStaticGeometry_hxx +#define BVHStaticGeometry_hxx + +#include +#include + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHStaticData.hxx" +#include "BVHStaticNode.hxx" + +namespace simgear { + +class BVHStaticGeometry : public BVHNode { +public: + BVHStaticGeometry(const BVHStaticNode* staticNode, + const BVHStaticData* staticData); + virtual ~BVHStaticGeometry(); + + virtual void accept(BVHVisitor& visitor); + + void traverse(BVHVisitor& visitor) const + { _staticNode->accept(visitor, *_staticData); } + + const BVHStaticData* getStaticData() const + { return _staticData; } + const BVHStaticNode* getStaticNode() const + { return _staticNode; } + + virtual SGSphered computeBoundingSphere() const; + +private: + SGSharedPtr _staticNode; + SGSharedPtr _staticData; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticGeometryBuilder.hxx b/simgear/bvh/BVHStaticGeometryBuilder.hxx new file mode 100644 index 00000000..98968162 --- /dev/null +++ b/simgear/bvh/BVHStaticGeometryBuilder.hxx @@ -0,0 +1,228 @@ +// 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 BVHStaticGeometryBuilder_hxx +#define BVHStaticGeometryBuilder_hxx + +#include +#include +#include + +#include +#include + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticLeaf.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" +#include "BVHStaticGeometry.hxx" + +namespace simgear { + +class BVHStaticGeometryBuilder : public SGReferenced { +public: + BVHStaticGeometryBuilder() : + _staticData(new BVHStaticData), + _currentMaterial(0), + _currentMaterialIndex(~0u) + { } + virtual ~BVHStaticGeometryBuilder() + { } + + struct LeafRef { + LeafRef(const BVHStaticLeaf* leaf, const BVHStaticData& data) : + _leaf(leaf), + _box(_leaf->computeBoundingBox(data)), + _center(_leaf->computeCenter(data)) + { } + SGSharedPtr _leaf; + SGBoxf _box; + SGVec3f _center; + }; + typedef std::list LeafRefList; + + struct LeafRefLess : public std::binary_function { + LeafRefLess(unsigned sortAxis) : _sortAxis(sortAxis) {} + bool operator()(const LeafRef& x, const LeafRef& y) + { return x._center[_sortAxis] < y._center[_sortAxis]; } + unsigned _sortAxis; + }; + + SGSharedPtr _staticData; + LeafRefList _leafRefList; + + typedef std::map VertexMap; + VertexMap _vertexMap; + + typedef std::set > TriangleSet; + TriangleSet _triangleSet; + + void setCurrentMaterial(const SGMaterial* material) + { + _currentMaterial = material; + _currentMaterialIndex = addMaterial(material); + } + const SGMaterial* getCurrentMaterial() const + { + return _currentMaterial; + } + unsigned addMaterial(const SGMaterial* material) + { + MaterialMap::const_iterator i = _materialMap.find(material); + if (i != _materialMap.end()) + return i->second; + unsigned index = _staticData->addMaterial(material); + _materialMap[material] = index; + return index; + } + + typedef std::map MaterialMap; + MaterialMap _materialMap; + const SGMaterial* _currentMaterial; + unsigned _currentMaterialIndex; + + void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3) + { + unsigned indices[3] = { addVertex(v1), addVertex(v2), addVertex(v3) }; + std::sort(indices, indices + 3); + SGVec3 indexKey(indices); + if (_triangleSet.find(indexKey) != _triangleSet.end()) + return; + _triangleSet.insert(indexKey); + BVHStaticTriangle* staticTriangle; + staticTriangle = new BVHStaticTriangle(_currentMaterialIndex, indices); + _leafRefList.push_back(LeafRef(staticTriangle, *_staticData)); + } + unsigned addVertex(const SGVec3f& v) + { + VertexMap::const_iterator i = _vertexMap.find(v); + if (i != _vertexMap.end()) + return i->second; + unsigned index = _staticData->addVertex(v); + _vertexMap[v] = index; + return index; + } + + BVHStaticGeometry* buildTree() + { + const BVHStaticNode* tree = buildTreeRecursive(_leafRefList); + if (!tree) + return 0; + _staticData->trim(); + return new BVHStaticGeometry(tree, _staticData); + } + +private: + static void + centerSplitLeafs(unsigned splitAxis, const double& splitValue, + LeafRefList& leafs, LeafRefList split[2]) + { + while (!leafs.empty()) { + if (leafs.front()._center[splitAxis] < splitValue) { + split[0].splice(split[0].begin(), leafs, leafs.begin()); + } else { + split[1].splice(split[1].begin(), leafs, leafs.begin()); + } + } + } + + static void + equalSplitLeafs(unsigned splitAxis, LeafRefList& leafs, + LeafRefList split[2]) + { + leafs.sort(LeafRefLess(splitAxis)); + while (true) { + if (leafs.empty()) + break; + split[0].splice(split[0].begin(), leafs, leafs.begin()); + + if (leafs.empty()) + break; + split[1].splice(split[1].begin(), leafs, --leafs.end()); + } + } + + static const BVHStaticNode* buildTreeRecursive(LeafRefList& leafs) + { + // recursion termination + if (leafs.empty()) + return 0; + // FIXME size is O(n)!!! + // if (leafs.size() == 1) + if (++leafs.begin() == leafs.end()) + return leafs.front()._leaf; + + SGBoxf box; + for (LeafRefList::const_iterator i = leafs.begin(); + i != leafs.end(); ++i) + box.expandBy(i->_box); + + // // FIXME ... + // if (length(box.getSize()) < 1) + // return new BVHBox(box); + + if (box.empty()) + return 0; + + unsigned splitAxis = box.getBroadestAxis(); + LeafRefList splitLeafs[2]; + double splitValue = box.getCenter()[splitAxis]; + centerSplitLeafs(splitAxis, splitValue, leafs, splitLeafs); + + if (splitLeafs[0].empty() || splitLeafs[1].empty()) { + for (unsigned i = 0; i < 3 ; ++i) { + if (i == splitAxis) + continue; + + leafs.swap(splitLeafs[0]); + leafs.splice(leafs.begin(), splitLeafs[1]); + splitValue = box.getCenter()[i]; + centerSplitLeafs(i, splitValue, leafs, splitLeafs); + + if (!splitLeafs[0].empty() && !splitLeafs[1].empty()) { + splitAxis = i; + break; + } + } + } + if (splitLeafs[0].empty() || splitLeafs[1].empty()) { + leafs.swap(splitLeafs[0]); + leafs.splice(leafs.begin(), splitLeafs[1]); + equalSplitLeafs(splitAxis, leafs, splitLeafs); + } + + const BVHStaticNode* child0 = buildTreeRecursive(splitLeafs[0]); + const BVHStaticNode* child1 = buildTreeRecursive(splitLeafs[1]); + if (!child0) + return child1; + if (!child1) + return child0; + + return new BVHStaticBinary(splitAxis, child0, child1, box); + } +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticLeaf.cxx b/simgear/bvh/BVHStaticLeaf.cxx new file mode 100644 index 00000000..29c2e04f --- /dev/null +++ b/simgear/bvh/BVHStaticLeaf.cxx @@ -0,0 +1,27 @@ +// 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. +// + +#include "BVHStaticLeaf.hxx" +#include "BVHVisitor.hxx" + +namespace simgear { + +BVHStaticLeaf::~BVHStaticLeaf() +{ +} + +} diff --git a/simgear/bvh/BVHStaticLeaf.hxx b/simgear/bvh/BVHStaticLeaf.hxx new file mode 100644 index 00000000..99d2959d --- /dev/null +++ b/simgear/bvh/BVHStaticLeaf.hxx @@ -0,0 +1,38 @@ +// 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 BVHStaticLeaf_hxx +#define BVHStaticLeaf_hxx + +#include +#include "BVHStaticNode.hxx" + +namespace simgear { + +class BVHStaticLeaf : public BVHStaticNode { +public: + virtual ~BVHStaticLeaf(); + + virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const = 0; + + virtual SGBoxf computeBoundingBox(const BVHStaticData&) const = 0; + virtual SGVec3f computeCenter(const BVHStaticData&) const = 0; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticNode.cxx b/simgear/bvh/BVHStaticNode.cxx new file mode 100644 index 00000000..4ab67c3f --- /dev/null +++ b/simgear/bvh/BVHStaticNode.cxx @@ -0,0 +1,26 @@ +// 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. +// + +#include "BVHStaticNode.hxx" + +namespace simgear { + +BVHStaticNode::~BVHStaticNode() +{ +} + +} diff --git a/simgear/bvh/BVHStaticNode.hxx b/simgear/bvh/BVHStaticNode.hxx new file mode 100644 index 00000000..8134599a --- /dev/null +++ b/simgear/bvh/BVHStaticNode.hxx @@ -0,0 +1,37 @@ +// 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 BVHStaticNode_hxx +#define BVHStaticNode_hxx + +#include + +namespace simgear { + +class BVHStaticData; +class BVHVisitor; + +class BVHStaticNode : public SGReferenced { +public: + virtual ~BVHStaticNode(); + + virtual void accept(BVHVisitor&, const BVHStaticData&) const = 0; +}; + +} + +#endif diff --git a/simgear/bvh/BVHStaticTriangle.cxx b/simgear/bvh/BVHStaticTriangle.cxx new file mode 100644 index 00000000..53572060 --- /dev/null +++ b/simgear/bvh/BVHStaticTriangle.cxx @@ -0,0 +1,58 @@ +// 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. +// + +#include "BVHStaticTriangle.hxx" + +#include "BVHVisitor.hxx" + +namespace simgear { + +BVHStaticTriangle::BVHStaticTriangle(unsigned material, + const unsigned indices[3]) : + _material(material) +{ + for (unsigned i = 0; i < 3; ++i) + _indices[i] = indices[i]; +} + +BVHStaticTriangle::~BVHStaticTriangle() +{ +} + +void +BVHStaticTriangle::accept(BVHVisitor& visitor, const BVHStaticData& data) const +{ + visitor.apply(*this, data); +} + +SGBoxf +BVHStaticTriangle::computeBoundingBox(const BVHStaticData& data) const +{ + SGBoxf box; + box.expandBy(data.getVertex(_indices[0])); + box.expandBy(data.getVertex(_indices[1])); + box.expandBy(data.getVertex(_indices[2])); + return box; +} + +SGVec3f +BVHStaticTriangle::computeCenter(const BVHStaticData& data) const +{ + return getTriangle(data).getCenter(); +} + +} diff --git a/simgear/bvh/BVHStaticTriangle.hxx b/simgear/bvh/BVHStaticTriangle.hxx new file mode 100644 index 00000000..79ff391f --- /dev/null +++ b/simgear/bvh/BVHStaticTriangle.hxx @@ -0,0 +1,54 @@ +// 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 BVHStaticTriangle_hxx +#define BVHStaticTriangle_hxx + +#include +#include "BVHStaticData.hxx" +#include "BVHStaticLeaf.hxx" + +namespace simgear { + +class BVHStaticTriangle : public BVHStaticLeaf { +public: + BVHStaticTriangle(unsigned material, const unsigned indices[3]); + virtual ~BVHStaticTriangle(); + + virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const; + + virtual SGBoxf computeBoundingBox(const BVHStaticData& data) const; + virtual SGVec3f computeCenter(const BVHStaticData& data) const; + + SGTrianglef getTriangle(const BVHStaticData& data) const + { + return SGTrianglef(data.getVertex(_indices[0]), + data.getVertex(_indices[1]), + data.getVertex(_indices[2])); + } + + unsigned getMaterialIndex() const + { return _material; } + +private: + unsigned _indices[3]; + unsigned _material; +}; + +} + +#endif diff --git a/simgear/bvh/BVHSubTreeCollector.cxx b/simgear/bvh/BVHSubTreeCollector.cxx new file mode 100644 index 00000000..5c8a915c --- /dev/null +++ b/simgear/bvh/BVHSubTreeCollector.cxx @@ -0,0 +1,249 @@ +// 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. +// + +#include "BVHSubTreeCollector.hxx" + +#include +#include + +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" +#include "BVHStaticGeometry.hxx" +#include "BVHBoundingBoxVisitor.hxx" + +namespace simgear { + +BVHSubTreeCollector::BVHSubTreeCollector(const SGSphered& sphere) : + _sphere(sphere) +{ +} + +BVHSubTreeCollector::~BVHSubTreeCollector() +{ +} + +void +BVHSubTreeCollector::apply(BVHGroup& group) +{ + if (!intersects(_sphere, group.getBoundingSphere())) + return; + + // The _nodeList content is somehow the 'return value' of the subtree. + // Set it to zero to see if we have something to collect down there. + NodeList parentNodeList; + pushNodeList(parentNodeList); + + group.traverse(*this); + + popNodeList(parentNodeList); +} + +void +BVHSubTreeCollector::apply(BVHTransform& transform) +{ + if (!intersects(_sphere, transform.getBoundingSphere())) + return; + + SGSphered sphere = _sphere; + _sphere = transform.sphereToLocal(sphere); + + NodeList parentNodeList; + pushNodeList(parentNodeList); + + transform.traverse(*this); + + if (haveChildren()) { + BVHTransform* currentBvTransform = new BVHTransform; + currentBvTransform->setTransform(transform); + popNodeList(parentNodeList, currentBvTransform); + } else { + popNodeList(parentNodeList); + } + + _sphere = sphere; +} + +void +BVHSubTreeCollector::apply(BVHMotionTransform& transform) +{ + if (!intersects(_sphere, transform.getBoundingSphere())) + return; + + SGSphered sphere = _sphere; + _sphere = transform.sphereToLocal(sphere, transform.getStartTime()); + _sphere.expandBy(transform.sphereToLocal(sphere, transform.getEndTime())); + + NodeList parentNodeList; + pushNodeList(parentNodeList); + + transform.traverse(*this); + + if (haveChildren()) { + BVHMotionTransform* currentBvTransform = new BVHMotionTransform; + currentBvTransform->setTransform(transform); + popNodeList(parentNodeList, currentBvTransform); + } else { + popNodeList(parentNodeList); + } + + _sphere = sphere; +} + +void +BVHSubTreeCollector::apply(BVHLineGeometry& lineSegment) +{ + if (!intersects(_sphere, lineSegment.getBoundingSphere())) + return; + addNode(&lineSegment); +} + +void +BVHSubTreeCollector::apply(BVHStaticGeometry& node) +{ + if (!intersects(_sphere, node.getBoundingSphere())) + return; + + assert(!_staticNode); + node.traverse(*this); + if (!_staticNode) + return; + + BVHStaticGeometry* staticTree; + staticTree = new BVHStaticGeometry(_staticNode, node.getStaticData()); + addNode(staticTree); + _staticNode = 0; +} + +void +BVHSubTreeCollector::apply(const BVHStaticBinary& node, + const BVHStaticData& data) +{ + assert(!_staticNode); + + if (!intersects(_sphere, node.getBoundingBox())) + return; + + SGVec3d corner(node.getBoundingBox().getFarestCorner(_sphere.getCenter())); + if (intersects(_sphere, corner)) { + // If the box is totally contained in the sphere, just take it all + _staticNode = &node; + + } else { + // We have still a chance to seperate something out, try it. + + node.getLeftChild()->accept(*this, data); + SGSharedPtr leftStaticNode = _staticNode; + _staticNode = 0; + node.getRightChild()->accept(*this, data); + SGSharedPtr rightStaticNode = _staticNode; + _staticNode = 0; + + if (leftStaticNode) { + if (rightStaticNode) { + BVHBoundingBoxVisitor bbv; + leftStaticNode->accept(bbv, data); + rightStaticNode->accept(bbv, data); + _staticNode + = new BVHStaticBinary(node.getSplitAxis(), leftStaticNode, + rightStaticNode, bbv.getBox()); + } else { + _staticNode = leftStaticNode; + } + } else { + if (rightStaticNode) { + _staticNode = rightStaticNode; + } else { + // Nothing to report to parents ... + } + } + } +} + +void +BVHSubTreeCollector::apply(const BVHStaticTriangle& node, + const BVHStaticData& data) +{ + if (!intersects(_sphere, node.getTriangle(data))) + return; + _staticNode = &node; +} + +void +BVHSubTreeCollector::addNode(BVHNode* node) +{ + if (!node) + return; + if (!_nodeList.capacity()) + _nodeList.reserve(64); + _nodeList.push_back(node); +} + +void +BVHSubTreeCollector::popNodeList(NodeList& parentNodeList, BVHGroup* transform) +{ + // Only do something if we really have children + if (!_nodeList.empty()) { + NodeList::const_iterator i; + for (i = _nodeList.begin(); i != _nodeList.end(); ++i) + transform->addChild(*i); + parentNodeList.push_back(transform); + } + _nodeList.swap(parentNodeList); +} + +void +BVHSubTreeCollector::popNodeList(NodeList& parentNodeList) +{ + // Only do something if we really have children + if (!_nodeList.empty()) { + if (_nodeList.size() == 1) { + parentNodeList.push_back(_nodeList.front()); + } else { + BVHGroup* group = new BVHGroup; + NodeList::const_iterator i; + for (i = _nodeList.begin(); i != _nodeList.end(); ++i) + group->addChild(*i); + parentNodeList.push_back(group); + } + } + _nodeList.swap(parentNodeList); +} + +SGSharedPtr +BVHSubTreeCollector::getNode() const +{ + if (_nodeList.empty()) + return 0; + + if (_nodeList.size() == 1) + return _nodeList.front(); + + BVHGroup* group = new BVHGroup; + NodeList::const_iterator i; + for (i = _nodeList.begin(); i != _nodeList.end(); ++i) + group->addChild(*i); + return group; +} + +} diff --git a/simgear/bvh/BVHSubTreeCollector.hxx b/simgear/bvh/BVHSubTreeCollector.hxx new file mode 100644 index 00000000..aa3e1124 --- /dev/null +++ b/simgear/bvh/BVHSubTreeCollector.hxx @@ -0,0 +1,81 @@ +// 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 BVHSubTreeCollector_hxx +#define BVHSubTreeCollector_hxx + +#include + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHStaticNode.hxx" + +namespace simgear { + +/// Visitor to subcollect parts of an existing bounding volume tree. +/// Given a sphere, it takes those sub parts of the tree that intersect the +/// sphere. Transform nodes of any kind are preserved to be able to ask for +/// intersections a different times. The subcollected tree is kept as small as +/// possible as it does avoid having groups with single childs. +/// Also the BVHStaticGeometry parts are seached for subtrees that are outside +/// the sphere. + +class BVHSubTreeCollector : public BVHVisitor { +public: + typedef std::vector > NodeList; + + BVHSubTreeCollector(const SGSphered& sphere = SGSphered()); + virtual ~BVHSubTreeCollector(); + + virtual void apply(BVHGroup&); + virtual void apply(BVHTransform&); + virtual void apply(BVHMotionTransform&); + virtual void apply(BVHLineGeometry&); + virtual void apply(BVHStaticGeometry&); + + virtual void apply(const BVHStaticBinary&, const BVHStaticData&); + virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); + + void setSphere(const SGSphered& sphere) + { _sphere = sphere; } + const SGSphered& getSphere() const + { return _sphere; } + + bool haveChildren() const + { return !_nodeList.empty(); } + + void addNode(BVHNode* node); + + void pushNodeList(NodeList& parentNodeList) + { _nodeList.swap(parentNodeList); } + void popNodeList(NodeList& parentNodeList, BVHGroup* transform); + void popNodeList(NodeList& parentNodeList); + + SGSharedPtr getNode() const; + +protected: + NodeList _nodeList; + SGSharedPtr _staticNode; + +private: + SGSphered _sphere; +}; + +} + +#endif diff --git a/simgear/bvh/BVHTransform.cxx b/simgear/bvh/BVHTransform.cxx new file mode 100644 index 00000000..802d8075 --- /dev/null +++ b/simgear/bvh/BVHTransform.cxx @@ -0,0 +1,99 @@ +// 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. +// + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "BVHTransform.hxx" + +#include "BVHVisitor.hxx" +#include "BVHNode.hxx" +#include "BVHGroup.hxx" + +namespace simgear { + +BVHTransform::BVHTransform() : + _toWorld(SGMatrixd::unit()), + _toLocal(SGMatrixd::unit()), + _toWorldAmplification(1), + _toLocalAmplification(1) +{ +} + +BVHTransform::~BVHTransform() +{ +} + +void +BVHTransform::accept(BVHVisitor& visitor) +{ + visitor.apply(*this); +} + +void +BVHTransform::setTransform(const BVHTransform& transform) +{ + _toWorld = transform._toWorld; + _toLocal = transform._toLocal; + _toWorldAmplification = transform._toWorldAmplification; + _toLocalAmplification = transform._toLocalAmplification; + invalidateParentBound(); +} + +void +BVHTransform::setToWorldTransform(const SGMatrixd& transform) +{ + _toWorld = transform; + invert(_toLocal, transform); + updateAmplificationFactors(); + invalidateParentBound(); +} + +void +BVHTransform::setToLocalTransform(const SGMatrixd& transform) +{ + _toLocal = transform; + invert(_toWorld, transform); + updateAmplificationFactors(); + invalidateParentBound(); +} + +SGSphered +BVHTransform::computeBoundingSphere() const +{ + return sphereToWorld(BVHGroup::computeBoundingSphere()); +} + +void +BVHTransform::updateAmplificationFactors() +{ + // Hmm, this is just a hint, true? + // But anyway, almost all transforms in a scenegraph will + // have them equal to 1 ... + double r = norm(vecToWorld(SGVec3d(1, 0, 0))); + r = std::max(r, norm(vecToWorld(SGVec3d(0, 1, 0)))); + r = std::max(r, norm(vecToWorld(SGVec3d(0, 0, 1)))); + _toWorldAmplification = r; + + r = norm(vecToLocal(SGVec3d(1, 0, 0))); + r = std::max(r, norm(vecToLocal(SGVec3d(0, 1, 0)))); + r = std::max(r, norm(vecToLocal(SGVec3d(0, 0, 1)))); + _toLocalAmplification = r; +} + +} diff --git a/simgear/bvh/BVHTransform.hxx b/simgear/bvh/BVHTransform.hxx new file mode 100644 index 00000000..d8b5096c --- /dev/null +++ b/simgear/bvh/BVHTransform.hxx @@ -0,0 +1,82 @@ +// 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 BVHTransform_hxx +#define BVHTransform_hxx + +#include "BVHGroup.hxx" + +namespace simgear { + +class BVHTransform : public BVHGroup { +public: + BVHTransform(); + virtual ~BVHTransform(); + + virtual void accept(BVHVisitor& visitor); + + void setTransform(const BVHTransform& transform); + + void setToWorldTransform(const SGMatrixd& transform); + const SGMatrixd& getToWorldTransform() const + { return _toWorld; } + + void setToLocalTransform(const SGMatrixd& transform); + const SGMatrixd& getToLocalTransform() const + { return _toLocal; } + + SGVec3d ptToWorld(const SGVec3d& point) const + { return _toWorld.xformPt(point); } + SGVec3d ptToLocal(const SGVec3d& point) const + { return _toLocal.xformPt(point); } + + SGVec3d vecToWorld(const SGVec3d& vec) const + { return _toWorld.xformVec(vec); } + SGVec3d vecToLocal(const SGVec3d& vec) const + { return _toLocal.xformVec(vec); } + + SGLineSegmentd lineSegmentToWorld(const SGLineSegmentd& lineSeg) const + { return lineSeg.transform(_toWorld); } + SGLineSegmentd lineSegmentToLocal(const SGLineSegmentd& lineSeg) const + { return lineSeg.transform(_toLocal); } + + SGSphered sphereToWorld(const SGSphered& sphere) const + { + SGVec3d center = ptToWorld(sphere.getCenter()); + double radius = _toWorldAmplification*sphere.getRadius(); + return SGSphered(center, radius); + } + SGSphered sphereToLocal(const SGSphered& sphere) const + { + SGVec3d center = ptToLocal(sphere.getCenter()); + double radius = _toLocalAmplification*sphere.getRadius(); + return SGSphered(center, radius); + } + +private: + virtual SGSphered computeBoundingSphere() const; + void updateAmplificationFactors(); + + SGMatrixd _toWorld; + SGMatrixd _toLocal; + double _toWorldAmplification; + double _toLocalAmplification; +}; + +} + +#endif diff --git a/simgear/bvh/BVHVisitor.hxx b/simgear/bvh/BVHVisitor.hxx new file mode 100644 index 00000000..f74f4456 --- /dev/null +++ b/simgear/bvh/BVHVisitor.hxx @@ -0,0 +1,56 @@ +// 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 BVHVisitor_hxx +#define BVHVisitor_hxx + +namespace simgear { + +class BVHStaticData; + +class BVHGroup; +class BVHTransform; +class BVHMotionTransform; +class BVHStaticGeometry; +class BVHLineGeometry; + +class BVHStaticBinary; +class BVHStaticTriangle; + +class BVHVisitor { +public: + // The magnitudes of pure virtuals is because of the fact that this chaining + // just takes needless runtime. This declaration should force the user of + // this classes to implement a common functionality that should be called + // from each apropriate apply method directly. + virtual ~BVHVisitor() {} + + // High level nodes to handle + virtual void apply(BVHGroup&) = 0; + virtual void apply(BVHTransform&) = 0; + virtual void apply(BVHMotionTransform&) = 0; + virtual void apply(BVHLineGeometry&) = 0; + virtual void apply(BVHStaticGeometry&) = 0; + + // Static tree nodes to handle + virtual void apply(const BVHStaticBinary&, const BVHStaticData&) = 0; + virtual void apply(const BVHStaticTriangle&, const BVHStaticData&) = 0; +}; + +} + +#endif diff --git a/simgear/bvh/CMakeLists.txt b/simgear/bvh/CMakeLists.txt new file mode 100644 index 00000000..f1a8340e --- /dev/null +++ b/simgear/bvh/CMakeLists.txt @@ -0,0 +1,50 @@ +include (SimGearComponent) + +set(HEADERS + BVHBoundingBoxVisitor.hxx + BVHGroup.hxx + BVHLineGeometry.hxx + BVHLineSegmentVisitor.hxx + BVHMotionTransform.hxx + BVHNearestPointVisitor.hxx + BVHNode.hxx + BVHStaticBinary.hxx + BVHStaticData.hxx + BVHStaticGeometry.hxx + BVHStaticGeometryBuilder.hxx + BVHStaticLeaf.hxx + BVHStaticNode.hxx + BVHStaticTriangle.hxx + BVHSubTreeCollector.hxx + BVHTransform.hxx + BVHVisitor.hxx +) + +set(SOURCES + BVHGroup.cxx + BVHLineGeometry.cxx + BVHLineSegmentVisitor.cxx + BVHMotionTransform.cxx + BVHNode.cxx + BVHStaticBinary.cxx + BVHStaticGeometry.cxx + BVHStaticLeaf.cxx + BVHStaticNode.cxx + BVHStaticTriangle.cxx + BVHSubTreeCollector.cxx + BVHTransform.cxx +) + +simgear_component(bvh bvh "${SOURCES}" "${HEADERS}") + +if(ENABLE_TESTS) + if (SIMGEAR_SHARED) + set(TEST_LIBS SimGearCore) + else() + set(TEST_LIBS sgbvh sgmath sgstructure sgdebug) + endif() + + add_executable(bvhtest bvhtest.cxx) + target_link_libraries(bvhtest ${TEST_LIBS}) + add_test(bvhtest ${EXECUTABLE_OUTPUT_PATH}/bvhtest) +endif(ENABLE_TESTS) diff --git a/simgear/bvh/bvhtest.cxx b/simgear/bvh/bvhtest.cxx new file mode 100644 index 00000000..0f01e7f0 --- /dev/null +++ b/simgear/bvh/bvhtest.cxx @@ -0,0 +1,142 @@ +// 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. +// + +#include +#include + +#include "BVHNode.hxx" +#include "BVHGroup.hxx" +#include "BVHTransform.hxx" + +#include "BVHStaticData.hxx" + +#include "BVHStaticNode.hxx" +#include "BVHStaticLeaf.hxx" +#include "BVHStaticTriangle.hxx" +#include "BVHStaticBinary.hxx" +#include "BVHStaticGeometry.hxx" + +#include "BVHBoundingBoxVisitor.hxx" +#include "BVHSubTreeCollector.hxx" +#include "BVHLineSegmentVisitor.hxx" +#include "BVHNearestPointVisitor.hxx" + +using namespace simgear; + +BVHNode* +buildSingleTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3) +{ + BVHStaticData* staticData = new BVHStaticData; + unsigned indices[3] = { + staticData->addVertex(v1), + staticData->addVertex(v2), + staticData->addVertex(v3) + }; + BVHStaticTriangle* staticTriangle = new BVHStaticTriangle(~0u, indices); + return new BVHStaticGeometry(staticTriangle, staticData); +} + +bool +testLineIntersections() +{ + SGVec3f v1(-1, -1, 0); + SGVec3f v2(1, -1, 0); + SGVec3f v3(-1, 1, 0); + SGSharedPtr node = buildSingleTriangle(v1, v2, v3); + + SGLineSegmentd lineSegment(SGVec3d(0, 0, -1), SGVec3d(0, 0, 1)); + { + BVHLineSegmentVisitor lineSegmentVisitor(lineSegment); + node->accept(lineSegmentVisitor); + if (lineSegmentVisitor.empty()) + return false; + if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) + return false; + } + + SGVec3d position(1000, 1000, 1000); + SGMatrixd matrix(position); + SGSharedPtr transform1 = new BVHTransform; + transform1->setToWorldTransform(matrix); + transform1->addChild(node); + + SGSharedPtr transform2 = new BVHTransform; + transform2->setToLocalTransform(matrix); + transform2->addChild(transform1); + + { + BVHLineSegmentVisitor lineSegmentVisitor(lineSegment); + transform2->accept(lineSegmentVisitor); + if (lineSegmentVisitor.empty()) + return false; + if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) + return false; + } + + SGSharedPtr transform3 = new BVHMotionTransform; + transform3->setLinearVelocity(SGVec3d(0, 0, 1)); + transform3->setAngularVelocity(SGVec3d(1, 0, 0)); + transform3->addChild(node); + + { + BVHLineSegmentVisitor lineSegmentVisitor(lineSegment, 0); + transform3->accept(lineSegmentVisitor); + if (lineSegmentVisitor.empty()) + return false; + if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) + return false; + if (!equivalent(lineSegmentVisitor.getLinearVelocity(), + SGVec3d(0, 1, 1))) + return false; + if (!equivalent(lineSegmentVisitor.getAngularVelocity(), + SGVec3d(1, 0, 0))) + return false; + } + + 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; +} diff --git a/simgear/scene/CMakeLists.txt b/simgear/scene/CMakeLists.txt index 732798b6..73429d55 100644 --- a/simgear/scene/CMakeLists.txt +++ b/simgear/scene/CMakeLists.txt @@ -3,7 +3,6 @@ include (SimGearComponent) include_directories(${PROJECT_SOURCE_DIR}) foreach( mylibfolder - bvh material model sky diff --git a/simgear/scene/bvh/.gitignore b/simgear/scene/bvh/.gitignore deleted file mode 100644 index 8a0ce98b..00000000 --- a/simgear/scene/bvh/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -bvhtest - diff --git a/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx b/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx deleted file mode 100644 index d37779c3..00000000 --- a/simgear/scene/bvh/BVHBoundingBoxVisitor.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// 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 BVHBoundingBoxVisitor_hxx -#define BVHBoundingBoxVisitor_hxx - -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" -#include "BVHMotionTransform.hxx" -#include "BVHLineGeometry.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" -#include "BVHStaticGeometry.hxx" - -namespace simgear { - -class BVHBoundingBoxVisitor : public BVHVisitor { -public: - virtual ~BVHBoundingBoxVisitor() {} - - void clear() - { _box.clear(); } - - virtual void apply(BVHGroup& node) - { expandBy(node.getBoundingSphere()); } - virtual void apply(BVHTransform& node) - { expandBy(node.getBoundingSphere()); } - virtual void apply(BVHMotionTransform& node) - { expandBy(node.getBoundingSphere()); } - virtual void apply(BVHLineGeometry& node) - { expandBy(node.getBoundingSphere()); } - virtual void apply(BVHStaticGeometry& node) - { expandBy(node.getBoundingSphere()); } - - virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) - { expandBy(node.getBoundingBox()); } - virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) - { expandBy(node.computeBoundingBox(data)); } - - const SGBoxf& getBox() const - { return _box; } - -private: - void expandBy(const SGSphered& sphere) - { - SGVec3f v0(sphere.getCenter() - sphere.getRadius()*SGVec3d(1, 1, 1)); - SGVec3f v1(sphere.getCenter() + sphere.getRadius()*SGVec3d(1, 1, 1)); - _box.expandBy(SGBoxf(v0, v1)); - } - void expandBy(const SGBoxf& box) - { _box.expandBy(box); } - - SGBoxf _box; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHDebugCollectVisitor.hxx b/simgear/scene/bvh/BVHDebugCollectVisitor.hxx deleted file mode 100644 index ecbe476c..00000000 --- a/simgear/scene/bvh/BVHDebugCollectVisitor.hxx +++ /dev/null @@ -1,210 +0,0 @@ -// 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 BVHDebugCollectVisitor_hxx -#define BVHDebugCollectVisitor_hxx - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" -#include "BVHMotionTransform.hxx" -#include "BVHStaticGeometry.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" - -#include "BVHBoundingBoxVisitor.hxx" - -namespace simgear { - -class BVHNode; -class BVHStaticNode; - -class BVHDebugCollectVisitor : public BVHVisitor { -public: - BVHDebugCollectVisitor(const double& time, unsigned level = ~0u) : - _group(new osg::Group), - _time(time), - _level(level), - _currentLevel(0) - { - osg::StateSet* stateSet = _group->getOrCreateStateSet(); - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false)); - osg::BlendFunc *blendFunc; - blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, - osg::BlendFunc::DST_ALPHA); - stateSet->setAttributeAndModes(blendFunc); - osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1); - stateSet->setAttributeAndModes(polygonOffset); - } - virtual ~BVHDebugCollectVisitor() - { } - - virtual void apply(BVHGroup& node) - { - addNodeSphere(node); - ++_currentLevel; - node.traverse(*this); - --_currentLevel; - } - virtual void apply(BVHTransform& node) - { - addNodeSphere(node); - osg::ref_ptr oldGroup = _group; - osg::ref_ptr transform = new osg::MatrixTransform; - transform->setMatrix(osg::Matrix(node.getToWorldTransform().data())); - _group = transform; - ++_currentLevel; - node.traverse(*this); - --_currentLevel; - _group = oldGroup; - if (transform->getNumChildren()) - _group->addChild(transform.get()); - } - virtual void apply(BVHMotionTransform& node) - { - addNodeSphere(node); - osg::ref_ptr oldGroup = _group; - osg::ref_ptr transform = new osg::MatrixTransform; - transform->setMatrix(osg::Matrix(node.getToWorldTransform(_time).data())); - _group = transform; - ++_currentLevel; - node.traverse(*this); - --_currentLevel; - _group = oldGroup; - if (transform->getNumChildren()) - _group->addChild(transform.get()); - } - virtual void apply(BVHLineGeometry&) - { - } - virtual void apply(BVHStaticGeometry& node) - { - addNodeSphere(node); - ++_currentLevel; - node.traverse(*this); - --_currentLevel; - } - - virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) - { - addNodeBox(node, data); - ++_currentLevel; - node.traverse(*this, data); - --_currentLevel; - } - virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) - { - addNodeBox(node, data); - addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2)); - } - - osg::Node* getNode() const { return _group.get(); } - - static unsigned allLevels() { return ~0u; } - static unsigned triangles() { return ~0u - 1; } - -private: - void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color) - { - if (_level != triangles()) - return; - - osg::Geometry* geometry = new osg::Geometry; - - osg::Vec3Array* vertices = new osg::Vec3Array; - vertices->push_back(toOsg(triangle.getVertex(0))); - vertices->push_back(toOsg(triangle.getVertex(1))); - vertices->push_back(toOsg(triangle.getVertex(2))); - - osg::Vec4Array* colors = new osg::Vec4Array; - colors->push_back(color); - - geometry->setVertexArray(vertices); - geometry->setColorArray(colors); - geometry->setColorBinding(osg::Geometry::BIND_OVERALL); - - geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3)); - - osg::Geode* geode = new osg::Geode; - geode->addDrawable(geometry); - _group->addChild(geode); - } - - void addNodeSphere(const BVHNode& node) - { - if (_level != ~0u && _level != _currentLevel) - return; - SGSphered sphere = node.getBoundingSphere(); - osg::Sphere* shape = new osg::Sphere; - shape->setCenter(toOsg(sphere.getCenter())); - shape->setRadius(sphere.getRadius()); - addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f)); - } - - void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data) - { - if (_level != ~0u && _level != _currentLevel) - return; - BVHBoundingBoxVisitor bbv; - node.accept(bbv, data); - osg::Box* shape = new osg::Box; - shape->setCenter(toOsg(bbv.getBox().getCenter())); - shape->setHalfLengths(toOsg((0.5*bbv.getBox().getSize()))); - addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f)); - } - - void addShape(osg::Shape* shape, const osg::Vec4& color) - { - osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable; - shapeDrawable->setColor(color); - shapeDrawable->setShape(shape); - osg::Geode* geode = new osg::Geode; - geode->addDrawable(shapeDrawable); - _group->addChild(geode); - } - - osg::ref_ptr _group; - const double _time; - const unsigned _level; - unsigned _currentLevel; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHGroup.cxx b/simgear/scene/bvh/BVHGroup.cxx deleted file mode 100644 index d444791c..00000000 --- a/simgear/scene/bvh/BVHGroup.cxx +++ /dev/null @@ -1,92 +0,0 @@ -// 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. -// - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "BVHGroup.hxx" - -#include - -namespace simgear { - -BVHGroup::BVHGroup() -{ -} - -BVHGroup::~BVHGroup() -{ - ChildList::iterator i; - for (i = _children.begin(); i != _children.end(); ++i) { - (*i)->removeParent(this); - *i = 0; - } -} - -void -BVHGroup::accept(BVHVisitor& visitor) -{ - visitor.apply(*this); -} - -void -BVHGroup::clear() -{ - _children.clear(); - invalidateBound(); -} - -void -BVHGroup::addChild(BVHNode* child) -{ - if (!child) - return; - ChildList::iterator i; - i = std::find(_children.begin(), _children.end(), child); - if (i != _children.end()) - return; - invalidateBound(); - child->addParent(this); - _children.push_back(child); -} - -void -BVHGroup::removeChild(BVHNode* child) -{ - if (!child) - return; - ChildList::iterator i; - i = std::find(_children.begin(), _children.end(), child); - if (i == _children.end()) - return; - invalidateBound(); - child->removeParent(this); - _children.erase(i); -} - -SGSphered -BVHGroup::computeBoundingSphere() const -{ - SGSphered sphere; - ChildList::const_iterator i; - for (i = _children.begin(); i != _children.end(); ++i) - sphere.expandBy((*i)->getBoundingSphere()); - return sphere; -} - -} diff --git a/simgear/scene/bvh/BVHGroup.hxx b/simgear/scene/bvh/BVHGroup.hxx deleted file mode 100644 index d0b58363..00000000 --- a/simgear/scene/bvh/BVHGroup.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// 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 BVHGroup_hxx -#define BVHGroup_hxx - -#include -#include "BVHNode.hxx" -#include "BVHVisitor.hxx" - -namespace simgear { - -class BVHGroup : public BVHNode { -public: - BVHGroup(); - virtual ~BVHGroup(); - - virtual void accept(BVHVisitor& visitor); - - void traverse(BVHVisitor& visitor) - { - ChildList::const_iterator i; - for (i = _children.begin(); i != _children.end(); ++i) - (*i)->accept(visitor); - } - - void clear(); - void addChild(BVHNode* child); - void removeChild(BVHNode* child); - - unsigned getNumChildren() const - { return _children.size(); } - const BVHNode* getChild(unsigned i) const - { if (_children.size() <= i) return 0; return _children[i]; } - BVHNode* getChild(unsigned i) - { if (_children.size() <= i) return 0; return _children[i]; } - - virtual SGSphered computeBoundingSphere() const; - -private: - typedef std::vector > ChildList; - ChildList _children; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHLineGeometry.cxx b/simgear/scene/bvh/BVHLineGeometry.cxx deleted file mode 100644 index 679a4675..00000000 --- a/simgear/scene/bvh/BVHLineGeometry.cxx +++ /dev/null @@ -1,49 +0,0 @@ -// 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. -// - -#include "BVHLineGeometry.hxx" - -#include "BVHVisitor.hxx" - -namespace simgear { - -BVHLineGeometry::BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type) : - _lineSegment(lineSegment), - _type(type) -{ -} - -BVHLineGeometry::~BVHLineGeometry() -{ -} - -void -BVHLineGeometry::accept(BVHVisitor& visitor) -{ - visitor.apply(*this); -} - -SGSphered -BVHLineGeometry::computeBoundingSphere() const -{ - SGSphered sphere; - sphere.expandBy(SGVec3d(_lineSegment.getStart())); - sphere.expandBy(SGVec3d(_lineSegment.getEnd())); - return sphere; -} - -} diff --git a/simgear/scene/bvh/BVHLineGeometry.hxx b/simgear/scene/bvh/BVHLineGeometry.hxx deleted file mode 100644 index d0d87211..00000000 --- a/simgear/scene/bvh/BVHLineGeometry.hxx +++ /dev/null @@ -1,53 +0,0 @@ -// 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 BVHLineGeometry_hxx -#define BVHLineGeometry_hxx - -#include -#include "BVHNode.hxx" - -namespace simgear { - -class BVHLineGeometry : public BVHNode { -public: - enum Type { - CarrierCatapult, - CarrierWire - }; - - BVHLineGeometry(const SGLineSegmentf& lineSegment, Type type); - virtual ~BVHLineGeometry(); - - virtual void accept(BVHVisitor& visitor); - - const SGLineSegmentf& getLineSegment() const - { return _lineSegment; } - - Type getType() const - { return _type; } - - virtual SGSphered computeBoundingSphere() const; - -private: - SGLineSegmentf _lineSegment; - Type _type; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHLineSegmentVisitor.cxx b/simgear/scene/bvh/BVHLineSegmentVisitor.cxx deleted file mode 100644 index 1b93cd09..00000000 --- a/simgear/scene/bvh/BVHLineSegmentVisitor.cxx +++ /dev/null @@ -1,157 +0,0 @@ -// 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. -// - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "BVHLineSegmentVisitor.hxx" - -#include - -#include "BVHVisitor.hxx" - -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" -#include "BVHMotionTransform.hxx" -#include "BVHLineGeometry.hxx" -#include "BVHStaticGeometry.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" - -namespace simgear { - -void -BVHLineSegmentVisitor::apply(BVHGroup& group) -{ - if (!intersects(_lineSegment, group.getBoundingSphere())) - return; - group.traverse(*this); -} - -void -BVHLineSegmentVisitor::apply(BVHTransform& transform) -{ - if (!intersects(_lineSegment, transform.getBoundingSphere())) - return; - - bool haveHit = _haveHit; - _haveHit = false; - - // Push the line segment - SGLineSegmentd lineSegment = getLineSegment(); - _lineSegment = transform.lineSegmentToLocal(lineSegment); - - transform.traverse(*this); - - if (_haveHit) { - _linearVelocity = transform.vecToWorld(_linearVelocity); - _angularVelocity = transform.vecToWorld(_angularVelocity); - SGVec3d point(transform.ptToWorld(_lineSegment.getEnd())); - _lineSegment.set(lineSegment.getStart(), point); - _normal = transform.vecToWorld(_normal); - } else { - _lineSegment = lineSegment; - _haveHit = haveHit; - } -} - -void -BVHLineSegmentVisitor::apply(BVHMotionTransform& transform) -{ - if (!intersects(_lineSegment, transform.getBoundingSphere())) - return; - - bool haveHit = _haveHit; - _haveHit = false; - - // Push the line segment - SGLineSegmentd lineSegment = getLineSegment(); - SGMatrixd toLocal = transform.getToLocalTransform(_time); - _lineSegment = lineSegment.transform(toLocal); - - transform.traverse(*this); - - if (_haveHit) { - SGMatrixd toWorld = transform.getToWorldTransform(_time); - SGVec3d localStart = _lineSegment.getStart(); - _linearVelocity += transform.getLinearVelocityAt(localStart); - _angularVelocity += transform.getAngularVelocity(); - _linearVelocity = toWorld.xformVec(_linearVelocity); - _angularVelocity = toWorld.xformVec(_angularVelocity); - SGVec3d localEnd = _lineSegment.getEnd(); - _lineSegment.set(lineSegment.getStart(), toWorld.xformPt(localEnd)); - _normal = toWorld.xformVec(_normal); - if (!_id) - _id = transform.getId(); - } else { - _lineSegment = lineSegment; - _haveHit = haveHit; - } -} - -void -BVHLineSegmentVisitor::apply(BVHLineGeometry&) -{ -} - -void -BVHLineSegmentVisitor::apply(BVHStaticGeometry& node) -{ - if (!intersects(_lineSegment, node.getBoundingSphere())) - return; - node.traverse(*this); -} - -void -BVHLineSegmentVisitor::apply(const BVHStaticBinary& node, - const BVHStaticData& data) -{ - if (!intersects(SGLineSegmentf(_lineSegment), node.getBoundingBox())) - return; - - // The first box to enter is the one the startpoint is in. - // this increases the probability, that on exit of that box we do not - // even need to walk the other one, since the line segment is - // then already short enough to not intersect the other one anymore. - node.traverse(*this, data, _lineSegment.getStart()); -} - -void -BVHLineSegmentVisitor::apply(const BVHStaticTriangle& triangle, - const BVHStaticData& data) -{ - SGTrianglef tri = triangle.getTriangle(data); - SGVec3f point; - if (!intersects(point, tri, SGLineSegmentf(_lineSegment), 1e-4f)) - return; - setLineSegmentEnd(SGVec3d(point)); - _normal = SGVec3d(tri.getNormal()); - _linearVelocity = SGVec3d::zeros(); - _angularVelocity = SGVec3d::zeros(); - _material = data.getMaterial(triangle.getMaterialIndex()); - _id = 0; - _haveHit = true; -} - - -} diff --git a/simgear/scene/bvh/BVHLineSegmentVisitor.hxx b/simgear/scene/bvh/BVHLineSegmentVisitor.hxx deleted file mode 100644 index cca02588..00000000 --- a/simgear/scene/bvh/BVHLineSegmentVisitor.hxx +++ /dev/null @@ -1,98 +0,0 @@ -// 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 BVHLineSegmentVisitor_hxx -#define BVHLineSegmentVisitor_hxx - -#include -#include -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" - -namespace simgear { - -class BVHLineSegmentVisitor : public BVHVisitor { -public: - BVHLineSegmentVisitor(const SGLineSegmentd& lineSegment, - const double& t = 0) : - _lineSegment(lineSegment), - _time(t), - _material(0), - _id(0), - _haveHit(false) - { } - virtual ~BVHLineSegmentVisitor() - { } - - bool empty() const - { return !_haveHit; } - - const SGLineSegmentd& getLineSegment() const - { return _lineSegment; } - - SGVec3d getPoint() const - { return _lineSegment.getEnd(); } - const SGVec3d& getNormal() const - { return _normal; } - const SGVec3d& getLinearVelocity() const - { return _linearVelocity; } - const SGVec3d& getAngularVelocity() const - { return _angularVelocity; } - const SGMaterial* getMaterial() const - { return _material; } - BVHNode::Id getId() const - { return _id; } - - virtual void apply(BVHGroup& group); - virtual void apply(BVHTransform& transform); - virtual void apply(BVHMotionTransform& transform); - virtual void apply(BVHLineGeometry&); - virtual void apply(BVHStaticGeometry& node); - - virtual void apply(const BVHStaticBinary&, const BVHStaticData&); - virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); - -protected: - void setLineSegmentEnd(const SGVec3d& end) - { - // Ok, you need to make sure that the new end is in the previous - // direction and that the line segment is not enlarged by that call. -#ifndef _NDEBUG - // FIXME insert code to check this... -#endif - _lineSegment.set(_lineSegment.getStart(), end); - } - -private: - SGLineSegmentd _lineSegment; - double _time; - - // belongs in a derived class - SGVec3d _normal; - SGVec3d _linearVelocity; - SGVec3d _angularVelocity; - const SGMaterial* _material; - BVHNode::Id _id; - - bool _haveHit; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHMotionTransform.cxx b/simgear/scene/bvh/BVHMotionTransform.cxx deleted file mode 100644 index 249c0784..00000000 --- a/simgear/scene/bvh/BVHMotionTransform.cxx +++ /dev/null @@ -1,120 +0,0 @@ -// 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. -// - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "BVHMotionTransform.hxx" - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" - -namespace simgear { - -BVHMotionTransform::BVHMotionTransform() : - _toWorldReference(SGMatrixd::unit()), - _toLocalReference(SGMatrixd::unit()), - _toWorldAmplification(1), - _toLocalAmplification(1), - _linearVelocity(0, 0, 0), - _angularVelocity(0, 0, 0), - _referenceTime(0), - _startTime(0), - _endTime(0), - _id(0) -{ -} - -BVHMotionTransform::~BVHMotionTransform() -{ -} - -void -BVHMotionTransform::accept(BVHVisitor& visitor) -{ - visitor.apply(*this); -} - -void -BVHMotionTransform::setTransform(const BVHMotionTransform& transform) -{ - _toWorldReference = transform._toWorldReference; - _toLocalReference = transform._toLocalReference; - _toWorldAmplification = transform._toWorldAmplification; - _toLocalAmplification = transform._toLocalAmplification; - _linearVelocity = transform._linearVelocity; - _angularVelocity = transform._angularVelocity; - _referenceTime = transform._referenceTime; - _startTime = transform._startTime; - _endTime = transform._endTime; - _id = transform._id; - invalidateParentBound(); -} - -void -BVHMotionTransform::setToWorldTransform(const SGMatrixd& transform) -{ - _toWorldReference = transform; - invert(_toLocalReference, transform); - updateAmplificationFactors(); - invalidateParentBound(); -} - -void -BVHMotionTransform::setToLocalTransform(const SGMatrixd& transform) -{ - _toLocalReference = transform; - invert(_toWorldReference, transform); - updateAmplificationFactors(); - invalidateParentBound(); -} - -SGSphered -BVHMotionTransform::computeBoundingSphere() const -{ - SGSphered sphere(BVHGroup::computeBoundingSphere()); - if (sphere.empty()) - return sphere; - SGMatrixd toWorldStart = getToWorldTransform(_startTime); - SGVec3d centerStart = toWorldStart.xformPt(sphere.getCenter()); - SGMatrixd toWorldEnd = getToWorldTransform(_endTime); - SGVec3d centerEnd = toWorldEnd.xformPt(sphere.getCenter()); - double rad = 0.5*length(centerStart - centerEnd) + sphere.getRadius(); - rad *= _toWorldAmplification; - return SGSphered(0.5*(centerStart + centerEnd), rad); -} - -void -BVHMotionTransform::updateAmplificationFactors() -{ - // Hmm, this is just a hint, true? - // But anyway, almost all transforms in a scenegraph will - // have them equal to 1 ... - double r = norm(_toWorldReference.xformVec(SGVec3d(1, 0, 0))); - r = SGMiscd::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 1, 0)))); - r = SGMiscd::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 0, 1)))); - _toWorldAmplification = r; - - r = norm(_toLocalReference.xformVec(SGVec3d(1, 0, 0))); - r = SGMiscd::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 1, 0)))); - r = SGMiscd::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 0, 1)))); - _toLocalAmplification = r; -} - -} diff --git a/simgear/scene/bvh/BVHMotionTransform.hxx b/simgear/scene/bvh/BVHMotionTransform.hxx deleted file mode 100644 index d1a401e3..00000000 --- a/simgear/scene/bvh/BVHMotionTransform.hxx +++ /dev/null @@ -1,126 +0,0 @@ -// 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 BVHMotionTransform_hxx -#define BVHMotionTransform_hxx - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" - -namespace simgear { - -class BVHMotionTransform : public BVHGroup { -public: - BVHMotionTransform(); - virtual ~BVHMotionTransform(); - - virtual void accept(BVHVisitor& visitor); - - void setTransform(const BVHMotionTransform& transform); - void setToWorldTransform(const SGMatrixd& transform); - void setToLocalTransform(const SGMatrixd& transform); - - void setLinearVelocity(const SGVec3d& linearVelocity) - { _linearVelocity = linearVelocity; } - const SGVec3d& getLinearVelocity() const - { return _linearVelocity; } - - void setAngularVelocity(const SGVec3d& angularVelocity) - { _angularVelocity = angularVelocity; } - const SGVec3d& getAngularVelocity() const - { return _angularVelocity; } - - void setReferenceTime(const double& referenceTime) - { _referenceTime = referenceTime; } - const double& getReferenceTime() const - { return _referenceTime; } - - void setStartTime(const double& startTime) - { _startTime = startTime; } - const double& getStartTime() const - { return _startTime; } - - void setEndTime(const double& endTime) - { _endTime = endTime; } - const double& getEndTime() const - { return _endTime; } - - SGMatrixd getToWorldTransform(const double& t) const - { - if (t == _referenceTime) - return _toWorldReference; - double dt = t - _referenceTime; - SGMatrixd matrix(_toWorldReference); - matrix.postMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity)); - matrix.postMultTranslate(dt*_linearVelocity); - return matrix; - } - SGMatrixd getToLocalTransform(const double& t) const - { - if (t == _referenceTime) - return _toLocalReference; - double dt = _referenceTime - t; - SGMatrixd matrix(_toLocalReference); - matrix.preMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity)); - matrix.preMultTranslate(dt*_linearVelocity); - return matrix; - } - - const SGMatrixd& getToWorldReferenceTransform() const - { return _toWorldReference; } - const SGMatrixd& getToLocalReferenceTransform() const - { return _toLocalReference; } - - SGVec3d getLinearVelocityAt(const SGVec3d& reference) const - { return _linearVelocity + cross(_angularVelocity, reference); } - - SGSphered sphereToLocal(const SGSphered& sphere, const double& t) const - { - SGMatrixd matrix = getToLocalTransform(t); - SGVec3d center = matrix.xformPt(sphere.getCenter()); - double radius = _toLocalAmplification*sphere.getRadius(); - return SGSphered(center, radius); - } - - void setId(Id id) - { _id = id; } - Id getId() const - { return _id; } - -private: - virtual SGSphered computeBoundingSphere() const; - void updateAmplificationFactors(); - - SGMatrixd _toWorldReference; - SGMatrixd _toLocalReference; - double _toWorldAmplification; - double _toLocalAmplification; - - SGVec3d _linearVelocity; - SGVec3d _angularVelocity; - - double _referenceTime; - double _startTime; - double _endTime; - - Id _id; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHNearestPointVisitor.hxx b/simgear/scene/bvh/BVHNearestPointVisitor.hxx deleted file mode 100644 index 1c07c66a..00000000 --- a/simgear/scene/bvh/BVHNearestPointVisitor.hxx +++ /dev/null @@ -1,166 +0,0 @@ -// 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), - _id(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); - if (!_id) - _id = transform.getId(); - } - _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; - _id = 0; - } - - 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; } - BVHNode::Id getId() const - { return _id; } - - bool empty() const - { return !_havePoint; } - -private: - SGSphered _sphere; - double _time; - - SGVec3d _point; - SGVec3d _linearVelocity; - SGVec3d _angularVelocity; - const SGMaterial* _material; - BVHNode::Id _id; - - bool _havePoint; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHNode.cxx b/simgear/scene/bvh/BVHNode.cxx deleted file mode 100644 index d4b1ca5f..00000000 --- a/simgear/scene/bvh/BVHNode.cxx +++ /dev/null @@ -1,80 +0,0 @@ -// 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. -// - -#include "BVHNode.hxx" - -#include -#include -#include - -namespace simgear { - -BVHNode::BVHNode() : - _dirtyBoundingSphere(true) -{ -} - -BVHNode::~BVHNode() -{ -} - -BVHNode::Id -BVHNode::getNewId() -{ - static SGAtomic id(0); - return ++id; -} - -void -BVHNode::addParent(BVHNode* parent) -{ - // should not happen, but be paranoid ... - ParentList::iterator i; - i = std::find(_parents.begin(), _parents.end(), parent); - if (i != _parents.end()) - return; - // add to the parents list ... - _parents.push_back(parent); -} - -void -BVHNode::removeParent(BVHNode* parent) -{ - ParentList::iterator i; - i = std::find(_parents.begin(), _parents.end(), parent); - if (i == _parents.end()) - return; - _parents.erase(i); -} - -void -BVHNode::invalidateParentBound() -{ - for (ParentList::iterator i = _parents.begin(); i != _parents.end(); ++i) - (*i)->invalidateBound(); -} - -void -BVHNode::invalidateBound() -{ - if (_dirtyBoundingSphere) - return; - invalidateParentBound(); - _dirtyBoundingSphere = true; -} - -} diff --git a/simgear/scene/bvh/BVHNode.hxx b/simgear/scene/bvh/BVHNode.hxx deleted file mode 100644 index 10a0a957..00000000 --- a/simgear/scene/bvh/BVHNode.hxx +++ /dev/null @@ -1,74 +0,0 @@ -// 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 BVHNode_hxx -#define BVHNode_hxx - -#include -#include -#include - -namespace simgear { - -class BVHGroup; -class BVHVisitor; - -// Base for the tree nodes -class BVHNode : public SGReferenced { -public: - BVHNode(); - virtual ~BVHNode(); - - // visitors ... - virtual void accept(BVHVisitor& visitor) = 0; - - const SGSphered& getBoundingSphere() const - { - if (_dirtyBoundingSphere) { - _boundingSphere = computeBoundingSphere(); - _dirtyBoundingSphere = false; - } - return _boundingSphere; - } - virtual SGSphered computeBoundingSphere() const = 0; - - /// A unique id for some kind of BVHNodes. - /// Currently only motions transforms. - typedef unsigned Id; - - // Factory to get a new id - static Id getNewId(); - -protected: - friend class BVHGroup; - void addParent(BVHNode* parent); - void removeParent(BVHNode* parent); - - void invalidateParentBound(); - virtual void invalidateBound(); - -private: - mutable bool _dirtyBoundingSphere; - mutable SGSphered _boundingSphere; - - typedef std::vector ParentList; - ParentList _parents; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticBinary.cxx b/simgear/scene/bvh/BVHStaticBinary.cxx deleted file mode 100644 index d98a35e0..00000000 --- a/simgear/scene/bvh/BVHStaticBinary.cxx +++ /dev/null @@ -1,45 +0,0 @@ -// 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. -// - -#include "BVHStaticBinary.hxx" - -#include "BVHVisitor.hxx" - -namespace simgear { - -BVHStaticBinary::BVHStaticBinary(unsigned splitAxis, - const BVHStaticNode* leftChild, - const BVHStaticNode* rightChild, - const SGBoxf& boundingBox) : - _splitAxis(splitAxis), - _leftChild(leftChild), - _rightChild(rightChild), - _boundingBox(boundingBox) -{ -} - -BVHStaticBinary::~BVHStaticBinary() -{ -} - -void -BVHStaticBinary::accept(BVHVisitor& visitor, const BVHStaticData& data) const -{ - visitor.apply(*this, data); -} - -} diff --git a/simgear/scene/bvh/BVHStaticBinary.hxx b/simgear/scene/bvh/BVHStaticBinary.hxx deleted file mode 100644 index 05b8aa3b..00000000 --- a/simgear/scene/bvh/BVHStaticBinary.hxx +++ /dev/null @@ -1,78 +0,0 @@ -// 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 BVHStaticBinary_hxx -#define BVHStaticBinary_hxx - -#include -#include -#include "BVHStaticNode.hxx" - -namespace simgear { - -class BVHStaticBinary : public BVHStaticNode { -public: - BVHStaticBinary(unsigned splitAxis, const BVHStaticNode* leftChild, - const BVHStaticNode* rightChild, const SGBoxf& box); - virtual ~BVHStaticBinary(); - virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const; - - void traverse(BVHVisitor& visitor, const BVHStaticData& data) const - { - _leftChild->accept(visitor, data); - _rightChild->accept(visitor, data); - } - - // Traverse call that first enters the child node that is potentially closer - // to the given point than the other. - template - void traverse(BVHVisitor& visitor, const BVHStaticData& data, - const SGVec3& pt) const - { - float center = 0.5f*(_boundingBox.getMin()[_splitAxis] - + _boundingBox.getMax()[_splitAxis]); - if (pt[_splitAxis] < center) { - _leftChild->accept(visitor, data); - _rightChild->accept(visitor, data); - } else { - _rightChild->accept(visitor, data); - _leftChild->accept(visitor, data); - } - } - - unsigned getSplitAxis() const - { return _splitAxis; } - - const BVHStaticNode* getLeftChild() const - { return _leftChild; } - const BVHStaticNode* getRightChild() const - { return _rightChild; } - - const SGBoxf& getBoundingBox() const - { return _boundingBox; } - -private: - // Note the order of the members, this is to avoid padding - unsigned _splitAxis; - SGSharedPtr _leftChild; - SGSharedPtr _rightChild; - SGBoxf _boundingBox; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticData.hxx b/simgear/scene/bvh/BVHStaticData.hxx deleted file mode 100644 index 400632ad..00000000 --- a/simgear/scene/bvh/BVHStaticData.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// 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 BVHStaticData_hxx -#define BVHStaticData_hxx - -#include -#include -#include -#include - -/// FIXME, the SGMaterial class is too much tied to the scenegraph aspects of -/// the materials. Use some class more decribing the -/// nature of the surface we live on ... -class SGMaterial; - -namespace simgear { - -class BVHStaticData : public SGReferenced { -public: - virtual ~BVHStaticData() {} - - unsigned addVertex(const SGVec3f& vertex) - { _vertices.push_back(vertex); return _vertices.size() - 1; } - const SGVec3f& getVertex(unsigned i) const - { return _vertices[i]; } - - - unsigned addMaterial(const SGMaterial* material) - { _materials.push_back(material); return _materials.size() - 1; } - const SGMaterial* getMaterial(unsigned i) const - { if (_materials.size() <= i) return 0; return _materials[i]; } - - void trim() - { - std::vector(_vertices).swap(_vertices); - std::vector(_materials).swap(_materials); - } - -private: - std::vector _vertices; - std::vector _materials; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticGeometry.cxx b/simgear/scene/bvh/BVHStaticGeometry.cxx deleted file mode 100644 index a8479565..00000000 --- a/simgear/scene/bvh/BVHStaticGeometry.cxx +++ /dev/null @@ -1,51 +0,0 @@ -// 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. -// - -#include "BVHStaticGeometry.hxx" - -#include "BVHBoundingBoxVisitor.hxx" - -namespace simgear { - -BVHStaticGeometry::BVHStaticGeometry(const BVHStaticNode* staticNode, - const BVHStaticData* staticData) : - _staticNode(staticNode), - _staticData(staticData) -{ -} - -BVHStaticGeometry::~BVHStaticGeometry() -{ -} - -void -BVHStaticGeometry::accept(BVHVisitor& visitor) -{ - visitor.apply(*this); -} - -SGSphered -BVHStaticGeometry::computeBoundingSphere() const -{ - BVHBoundingBoxVisitor bbv; - _staticNode->accept(bbv, *_staticData); - SGSphered sphere; - sphere.expandBy(SGBoxd(bbv.getBox())); - return sphere; -} - -} diff --git a/simgear/scene/bvh/BVHStaticGeometry.hxx b/simgear/scene/bvh/BVHStaticGeometry.hxx deleted file mode 100644 index 693d4ff8..00000000 --- a/simgear/scene/bvh/BVHStaticGeometry.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// 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 BVHStaticGeometry_hxx -#define BVHStaticGeometry_hxx - -#include -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHStaticData.hxx" -#include "BVHStaticNode.hxx" - -namespace simgear { - -class BVHStaticGeometry : public BVHNode { -public: - BVHStaticGeometry(const BVHStaticNode* staticNode, - const BVHStaticData* staticData); - virtual ~BVHStaticGeometry(); - - virtual void accept(BVHVisitor& visitor); - - void traverse(BVHVisitor& visitor) const - { _staticNode->accept(visitor, *_staticData); } - - const BVHStaticData* getStaticData() const - { return _staticData; } - const BVHStaticNode* getStaticNode() const - { return _staticNode; } - - virtual SGSphered computeBoundingSphere() const; - -private: - SGSharedPtr _staticNode; - SGSharedPtr _staticData; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticGeometryBuilder.hxx b/simgear/scene/bvh/BVHStaticGeometryBuilder.hxx deleted file mode 100644 index 98968162..00000000 --- a/simgear/scene/bvh/BVHStaticGeometryBuilder.hxx +++ /dev/null @@ -1,228 +0,0 @@ -// 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 BVHStaticGeometryBuilder_hxx -#define BVHStaticGeometryBuilder_hxx - -#include -#include -#include - -#include -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" -#include "BVHStaticGeometry.hxx" - -namespace simgear { - -class BVHStaticGeometryBuilder : public SGReferenced { -public: - BVHStaticGeometryBuilder() : - _staticData(new BVHStaticData), - _currentMaterial(0), - _currentMaterialIndex(~0u) - { } - virtual ~BVHStaticGeometryBuilder() - { } - - struct LeafRef { - LeafRef(const BVHStaticLeaf* leaf, const BVHStaticData& data) : - _leaf(leaf), - _box(_leaf->computeBoundingBox(data)), - _center(_leaf->computeCenter(data)) - { } - SGSharedPtr _leaf; - SGBoxf _box; - SGVec3f _center; - }; - typedef std::list LeafRefList; - - struct LeafRefLess : public std::binary_function { - LeafRefLess(unsigned sortAxis) : _sortAxis(sortAxis) {} - bool operator()(const LeafRef& x, const LeafRef& y) - { return x._center[_sortAxis] < y._center[_sortAxis]; } - unsigned _sortAxis; - }; - - SGSharedPtr _staticData; - LeafRefList _leafRefList; - - typedef std::map VertexMap; - VertexMap _vertexMap; - - typedef std::set > TriangleSet; - TriangleSet _triangleSet; - - void setCurrentMaterial(const SGMaterial* material) - { - _currentMaterial = material; - _currentMaterialIndex = addMaterial(material); - } - const SGMaterial* getCurrentMaterial() const - { - return _currentMaterial; - } - unsigned addMaterial(const SGMaterial* material) - { - MaterialMap::const_iterator i = _materialMap.find(material); - if (i != _materialMap.end()) - return i->second; - unsigned index = _staticData->addMaterial(material); - _materialMap[material] = index; - return index; - } - - typedef std::map MaterialMap; - MaterialMap _materialMap; - const SGMaterial* _currentMaterial; - unsigned _currentMaterialIndex; - - void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3) - { - unsigned indices[3] = { addVertex(v1), addVertex(v2), addVertex(v3) }; - std::sort(indices, indices + 3); - SGVec3 indexKey(indices); - if (_triangleSet.find(indexKey) != _triangleSet.end()) - return; - _triangleSet.insert(indexKey); - BVHStaticTriangle* staticTriangle; - staticTriangle = new BVHStaticTriangle(_currentMaterialIndex, indices); - _leafRefList.push_back(LeafRef(staticTriangle, *_staticData)); - } - unsigned addVertex(const SGVec3f& v) - { - VertexMap::const_iterator i = _vertexMap.find(v); - if (i != _vertexMap.end()) - return i->second; - unsigned index = _staticData->addVertex(v); - _vertexMap[v] = index; - return index; - } - - BVHStaticGeometry* buildTree() - { - const BVHStaticNode* tree = buildTreeRecursive(_leafRefList); - if (!tree) - return 0; - _staticData->trim(); - return new BVHStaticGeometry(tree, _staticData); - } - -private: - static void - centerSplitLeafs(unsigned splitAxis, const double& splitValue, - LeafRefList& leafs, LeafRefList split[2]) - { - while (!leafs.empty()) { - if (leafs.front()._center[splitAxis] < splitValue) { - split[0].splice(split[0].begin(), leafs, leafs.begin()); - } else { - split[1].splice(split[1].begin(), leafs, leafs.begin()); - } - } - } - - static void - equalSplitLeafs(unsigned splitAxis, LeafRefList& leafs, - LeafRefList split[2]) - { - leafs.sort(LeafRefLess(splitAxis)); - while (true) { - if (leafs.empty()) - break; - split[0].splice(split[0].begin(), leafs, leafs.begin()); - - if (leafs.empty()) - break; - split[1].splice(split[1].begin(), leafs, --leafs.end()); - } - } - - static const BVHStaticNode* buildTreeRecursive(LeafRefList& leafs) - { - // recursion termination - if (leafs.empty()) - return 0; - // FIXME size is O(n)!!! - // if (leafs.size() == 1) - if (++leafs.begin() == leafs.end()) - return leafs.front()._leaf; - - SGBoxf box; - for (LeafRefList::const_iterator i = leafs.begin(); - i != leafs.end(); ++i) - box.expandBy(i->_box); - - // // FIXME ... - // if (length(box.getSize()) < 1) - // return new BVHBox(box); - - if (box.empty()) - return 0; - - unsigned splitAxis = box.getBroadestAxis(); - LeafRefList splitLeafs[2]; - double splitValue = box.getCenter()[splitAxis]; - centerSplitLeafs(splitAxis, splitValue, leafs, splitLeafs); - - if (splitLeafs[0].empty() || splitLeafs[1].empty()) { - for (unsigned i = 0; i < 3 ; ++i) { - if (i == splitAxis) - continue; - - leafs.swap(splitLeafs[0]); - leafs.splice(leafs.begin(), splitLeafs[1]); - splitValue = box.getCenter()[i]; - centerSplitLeafs(i, splitValue, leafs, splitLeafs); - - if (!splitLeafs[0].empty() && !splitLeafs[1].empty()) { - splitAxis = i; - break; - } - } - } - if (splitLeafs[0].empty() || splitLeafs[1].empty()) { - leafs.swap(splitLeafs[0]); - leafs.splice(leafs.begin(), splitLeafs[1]); - equalSplitLeafs(splitAxis, leafs, splitLeafs); - } - - const BVHStaticNode* child0 = buildTreeRecursive(splitLeafs[0]); - const BVHStaticNode* child1 = buildTreeRecursive(splitLeafs[1]); - if (!child0) - return child1; - if (!child1) - return child0; - - return new BVHStaticBinary(splitAxis, child0, child1, box); - } -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticLeaf.cxx b/simgear/scene/bvh/BVHStaticLeaf.cxx deleted file mode 100644 index 29c2e04f..00000000 --- a/simgear/scene/bvh/BVHStaticLeaf.cxx +++ /dev/null @@ -1,27 +0,0 @@ -// 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. -// - -#include "BVHStaticLeaf.hxx" -#include "BVHVisitor.hxx" - -namespace simgear { - -BVHStaticLeaf::~BVHStaticLeaf() -{ -} - -} diff --git a/simgear/scene/bvh/BVHStaticLeaf.hxx b/simgear/scene/bvh/BVHStaticLeaf.hxx deleted file mode 100644 index 99d2959d..00000000 --- a/simgear/scene/bvh/BVHStaticLeaf.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// 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 BVHStaticLeaf_hxx -#define BVHStaticLeaf_hxx - -#include -#include "BVHStaticNode.hxx" - -namespace simgear { - -class BVHStaticLeaf : public BVHStaticNode { -public: - virtual ~BVHStaticLeaf(); - - virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const = 0; - - virtual SGBoxf computeBoundingBox(const BVHStaticData&) const = 0; - virtual SGVec3f computeCenter(const BVHStaticData&) const = 0; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticNode.cxx b/simgear/scene/bvh/BVHStaticNode.cxx deleted file mode 100644 index 4ab67c3f..00000000 --- a/simgear/scene/bvh/BVHStaticNode.cxx +++ /dev/null @@ -1,26 +0,0 @@ -// 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. -// - -#include "BVHStaticNode.hxx" - -namespace simgear { - -BVHStaticNode::~BVHStaticNode() -{ -} - -} diff --git a/simgear/scene/bvh/BVHStaticNode.hxx b/simgear/scene/bvh/BVHStaticNode.hxx deleted file mode 100644 index 8134599a..00000000 --- a/simgear/scene/bvh/BVHStaticNode.hxx +++ /dev/null @@ -1,37 +0,0 @@ -// 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 BVHStaticNode_hxx -#define BVHStaticNode_hxx - -#include - -namespace simgear { - -class BVHStaticData; -class BVHVisitor; - -class BVHStaticNode : public SGReferenced { -public: - virtual ~BVHStaticNode(); - - virtual void accept(BVHVisitor&, const BVHStaticData&) const = 0; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHStaticTriangle.cxx b/simgear/scene/bvh/BVHStaticTriangle.cxx deleted file mode 100644 index 53572060..00000000 --- a/simgear/scene/bvh/BVHStaticTriangle.cxx +++ /dev/null @@ -1,58 +0,0 @@ -// 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. -// - -#include "BVHStaticTriangle.hxx" - -#include "BVHVisitor.hxx" - -namespace simgear { - -BVHStaticTriangle::BVHStaticTriangle(unsigned material, - const unsigned indices[3]) : - _material(material) -{ - for (unsigned i = 0; i < 3; ++i) - _indices[i] = indices[i]; -} - -BVHStaticTriangle::~BVHStaticTriangle() -{ -} - -void -BVHStaticTriangle::accept(BVHVisitor& visitor, const BVHStaticData& data) const -{ - visitor.apply(*this, data); -} - -SGBoxf -BVHStaticTriangle::computeBoundingBox(const BVHStaticData& data) const -{ - SGBoxf box; - box.expandBy(data.getVertex(_indices[0])); - box.expandBy(data.getVertex(_indices[1])); - box.expandBy(data.getVertex(_indices[2])); - return box; -} - -SGVec3f -BVHStaticTriangle::computeCenter(const BVHStaticData& data) const -{ - return getTriangle(data).getCenter(); -} - -} diff --git a/simgear/scene/bvh/BVHStaticTriangle.hxx b/simgear/scene/bvh/BVHStaticTriangle.hxx deleted file mode 100644 index 79ff391f..00000000 --- a/simgear/scene/bvh/BVHStaticTriangle.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// 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 BVHStaticTriangle_hxx -#define BVHStaticTriangle_hxx - -#include -#include "BVHStaticData.hxx" -#include "BVHStaticLeaf.hxx" - -namespace simgear { - -class BVHStaticTriangle : public BVHStaticLeaf { -public: - BVHStaticTriangle(unsigned material, const unsigned indices[3]); - virtual ~BVHStaticTriangle(); - - virtual void accept(BVHVisitor& visitor, const BVHStaticData& data) const; - - virtual SGBoxf computeBoundingBox(const BVHStaticData& data) const; - virtual SGVec3f computeCenter(const BVHStaticData& data) const; - - SGTrianglef getTriangle(const BVHStaticData& data) const - { - return SGTrianglef(data.getVertex(_indices[0]), - data.getVertex(_indices[1]), - data.getVertex(_indices[2])); - } - - unsigned getMaterialIndex() const - { return _material; } - -private: - unsigned _indices[3]; - unsigned _material; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHSubTreeCollector.cxx b/simgear/scene/bvh/BVHSubTreeCollector.cxx deleted file mode 100644 index 5c8a915c..00000000 --- a/simgear/scene/bvh/BVHSubTreeCollector.cxx +++ /dev/null @@ -1,249 +0,0 @@ -// 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. -// - -#include "BVHSubTreeCollector.hxx" - -#include -#include - -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" -#include "BVHStaticGeometry.hxx" -#include "BVHBoundingBoxVisitor.hxx" - -namespace simgear { - -BVHSubTreeCollector::BVHSubTreeCollector(const SGSphered& sphere) : - _sphere(sphere) -{ -} - -BVHSubTreeCollector::~BVHSubTreeCollector() -{ -} - -void -BVHSubTreeCollector::apply(BVHGroup& group) -{ - if (!intersects(_sphere, group.getBoundingSphere())) - return; - - // The _nodeList content is somehow the 'return value' of the subtree. - // Set it to zero to see if we have something to collect down there. - NodeList parentNodeList; - pushNodeList(parentNodeList); - - group.traverse(*this); - - popNodeList(parentNodeList); -} - -void -BVHSubTreeCollector::apply(BVHTransform& transform) -{ - if (!intersects(_sphere, transform.getBoundingSphere())) - return; - - SGSphered sphere = _sphere; - _sphere = transform.sphereToLocal(sphere); - - NodeList parentNodeList; - pushNodeList(parentNodeList); - - transform.traverse(*this); - - if (haveChildren()) { - BVHTransform* currentBvTransform = new BVHTransform; - currentBvTransform->setTransform(transform); - popNodeList(parentNodeList, currentBvTransform); - } else { - popNodeList(parentNodeList); - } - - _sphere = sphere; -} - -void -BVHSubTreeCollector::apply(BVHMotionTransform& transform) -{ - if (!intersects(_sphere, transform.getBoundingSphere())) - return; - - SGSphered sphere = _sphere; - _sphere = transform.sphereToLocal(sphere, transform.getStartTime()); - _sphere.expandBy(transform.sphereToLocal(sphere, transform.getEndTime())); - - NodeList parentNodeList; - pushNodeList(parentNodeList); - - transform.traverse(*this); - - if (haveChildren()) { - BVHMotionTransform* currentBvTransform = new BVHMotionTransform; - currentBvTransform->setTransform(transform); - popNodeList(parentNodeList, currentBvTransform); - } else { - popNodeList(parentNodeList); - } - - _sphere = sphere; -} - -void -BVHSubTreeCollector::apply(BVHLineGeometry& lineSegment) -{ - if (!intersects(_sphere, lineSegment.getBoundingSphere())) - return; - addNode(&lineSegment); -} - -void -BVHSubTreeCollector::apply(BVHStaticGeometry& node) -{ - if (!intersects(_sphere, node.getBoundingSphere())) - return; - - assert(!_staticNode); - node.traverse(*this); - if (!_staticNode) - return; - - BVHStaticGeometry* staticTree; - staticTree = new BVHStaticGeometry(_staticNode, node.getStaticData()); - addNode(staticTree); - _staticNode = 0; -} - -void -BVHSubTreeCollector::apply(const BVHStaticBinary& node, - const BVHStaticData& data) -{ - assert(!_staticNode); - - if (!intersects(_sphere, node.getBoundingBox())) - return; - - SGVec3d corner(node.getBoundingBox().getFarestCorner(_sphere.getCenter())); - if (intersects(_sphere, corner)) { - // If the box is totally contained in the sphere, just take it all - _staticNode = &node; - - } else { - // We have still a chance to seperate something out, try it. - - node.getLeftChild()->accept(*this, data); - SGSharedPtr leftStaticNode = _staticNode; - _staticNode = 0; - node.getRightChild()->accept(*this, data); - SGSharedPtr rightStaticNode = _staticNode; - _staticNode = 0; - - if (leftStaticNode) { - if (rightStaticNode) { - BVHBoundingBoxVisitor bbv; - leftStaticNode->accept(bbv, data); - rightStaticNode->accept(bbv, data); - _staticNode - = new BVHStaticBinary(node.getSplitAxis(), leftStaticNode, - rightStaticNode, bbv.getBox()); - } else { - _staticNode = leftStaticNode; - } - } else { - if (rightStaticNode) { - _staticNode = rightStaticNode; - } else { - // Nothing to report to parents ... - } - } - } -} - -void -BVHSubTreeCollector::apply(const BVHStaticTriangle& node, - const BVHStaticData& data) -{ - if (!intersects(_sphere, node.getTriangle(data))) - return; - _staticNode = &node; -} - -void -BVHSubTreeCollector::addNode(BVHNode* node) -{ - if (!node) - return; - if (!_nodeList.capacity()) - _nodeList.reserve(64); - _nodeList.push_back(node); -} - -void -BVHSubTreeCollector::popNodeList(NodeList& parentNodeList, BVHGroup* transform) -{ - // Only do something if we really have children - if (!_nodeList.empty()) { - NodeList::const_iterator i; - for (i = _nodeList.begin(); i != _nodeList.end(); ++i) - transform->addChild(*i); - parentNodeList.push_back(transform); - } - _nodeList.swap(parentNodeList); -} - -void -BVHSubTreeCollector::popNodeList(NodeList& parentNodeList) -{ - // Only do something if we really have children - if (!_nodeList.empty()) { - if (_nodeList.size() == 1) { - parentNodeList.push_back(_nodeList.front()); - } else { - BVHGroup* group = new BVHGroup; - NodeList::const_iterator i; - for (i = _nodeList.begin(); i != _nodeList.end(); ++i) - group->addChild(*i); - parentNodeList.push_back(group); - } - } - _nodeList.swap(parentNodeList); -} - -SGSharedPtr -BVHSubTreeCollector::getNode() const -{ - if (_nodeList.empty()) - return 0; - - if (_nodeList.size() == 1) - return _nodeList.front(); - - BVHGroup* group = new BVHGroup; - NodeList::const_iterator i; - for (i = _nodeList.begin(); i != _nodeList.end(); ++i) - group->addChild(*i); - return group; -} - -} diff --git a/simgear/scene/bvh/BVHSubTreeCollector.hxx b/simgear/scene/bvh/BVHSubTreeCollector.hxx deleted file mode 100644 index aa3e1124..00000000 --- a/simgear/scene/bvh/BVHSubTreeCollector.hxx +++ /dev/null @@ -1,81 +0,0 @@ -// 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 BVHSubTreeCollector_hxx -#define BVHSubTreeCollector_hxx - -#include - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHStaticNode.hxx" - -namespace simgear { - -/// Visitor to subcollect parts of an existing bounding volume tree. -/// Given a sphere, it takes those sub parts of the tree that intersect the -/// sphere. Transform nodes of any kind are preserved to be able to ask for -/// intersections a different times. The subcollected tree is kept as small as -/// possible as it does avoid having groups with single childs. -/// Also the BVHStaticGeometry parts are seached for subtrees that are outside -/// the sphere. - -class BVHSubTreeCollector : public BVHVisitor { -public: - typedef std::vector > NodeList; - - BVHSubTreeCollector(const SGSphered& sphere = SGSphered()); - virtual ~BVHSubTreeCollector(); - - virtual void apply(BVHGroup&); - virtual void apply(BVHTransform&); - virtual void apply(BVHMotionTransform&); - virtual void apply(BVHLineGeometry&); - virtual void apply(BVHStaticGeometry&); - - virtual void apply(const BVHStaticBinary&, const BVHStaticData&); - virtual void apply(const BVHStaticTriangle&, const BVHStaticData&); - - void setSphere(const SGSphered& sphere) - { _sphere = sphere; } - const SGSphered& getSphere() const - { return _sphere; } - - bool haveChildren() const - { return !_nodeList.empty(); } - - void addNode(BVHNode* node); - - void pushNodeList(NodeList& parentNodeList) - { _nodeList.swap(parentNodeList); } - void popNodeList(NodeList& parentNodeList, BVHGroup* transform); - void popNodeList(NodeList& parentNodeList); - - SGSharedPtr getNode() const; - -protected: - NodeList _nodeList; - SGSharedPtr _staticNode; - -private: - SGSphered _sphere; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHTransform.cxx b/simgear/scene/bvh/BVHTransform.cxx deleted file mode 100644 index 802d8075..00000000 --- a/simgear/scene/bvh/BVHTransform.cxx +++ /dev/null @@ -1,99 +0,0 @@ -// 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. -// - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "BVHTransform.hxx" - -#include "BVHVisitor.hxx" -#include "BVHNode.hxx" -#include "BVHGroup.hxx" - -namespace simgear { - -BVHTransform::BVHTransform() : - _toWorld(SGMatrixd::unit()), - _toLocal(SGMatrixd::unit()), - _toWorldAmplification(1), - _toLocalAmplification(1) -{ -} - -BVHTransform::~BVHTransform() -{ -} - -void -BVHTransform::accept(BVHVisitor& visitor) -{ - visitor.apply(*this); -} - -void -BVHTransform::setTransform(const BVHTransform& transform) -{ - _toWorld = transform._toWorld; - _toLocal = transform._toLocal; - _toWorldAmplification = transform._toWorldAmplification; - _toLocalAmplification = transform._toLocalAmplification; - invalidateParentBound(); -} - -void -BVHTransform::setToWorldTransform(const SGMatrixd& transform) -{ - _toWorld = transform; - invert(_toLocal, transform); - updateAmplificationFactors(); - invalidateParentBound(); -} - -void -BVHTransform::setToLocalTransform(const SGMatrixd& transform) -{ - _toLocal = transform; - invert(_toWorld, transform); - updateAmplificationFactors(); - invalidateParentBound(); -} - -SGSphered -BVHTransform::computeBoundingSphere() const -{ - return sphereToWorld(BVHGroup::computeBoundingSphere()); -} - -void -BVHTransform::updateAmplificationFactors() -{ - // Hmm, this is just a hint, true? - // But anyway, almost all transforms in a scenegraph will - // have them equal to 1 ... - double r = norm(vecToWorld(SGVec3d(1, 0, 0))); - r = std::max(r, norm(vecToWorld(SGVec3d(0, 1, 0)))); - r = std::max(r, norm(vecToWorld(SGVec3d(0, 0, 1)))); - _toWorldAmplification = r; - - r = norm(vecToLocal(SGVec3d(1, 0, 0))); - r = std::max(r, norm(vecToLocal(SGVec3d(0, 1, 0)))); - r = std::max(r, norm(vecToLocal(SGVec3d(0, 0, 1)))); - _toLocalAmplification = r; -} - -} diff --git a/simgear/scene/bvh/BVHTransform.hxx b/simgear/scene/bvh/BVHTransform.hxx deleted file mode 100644 index d8b5096c..00000000 --- a/simgear/scene/bvh/BVHTransform.hxx +++ /dev/null @@ -1,82 +0,0 @@ -// 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 BVHTransform_hxx -#define BVHTransform_hxx - -#include "BVHGroup.hxx" - -namespace simgear { - -class BVHTransform : public BVHGroup { -public: - BVHTransform(); - virtual ~BVHTransform(); - - virtual void accept(BVHVisitor& visitor); - - void setTransform(const BVHTransform& transform); - - void setToWorldTransform(const SGMatrixd& transform); - const SGMatrixd& getToWorldTransform() const - { return _toWorld; } - - void setToLocalTransform(const SGMatrixd& transform); - const SGMatrixd& getToLocalTransform() const - { return _toLocal; } - - SGVec3d ptToWorld(const SGVec3d& point) const - { return _toWorld.xformPt(point); } - SGVec3d ptToLocal(const SGVec3d& point) const - { return _toLocal.xformPt(point); } - - SGVec3d vecToWorld(const SGVec3d& vec) const - { return _toWorld.xformVec(vec); } - SGVec3d vecToLocal(const SGVec3d& vec) const - { return _toLocal.xformVec(vec); } - - SGLineSegmentd lineSegmentToWorld(const SGLineSegmentd& lineSeg) const - { return lineSeg.transform(_toWorld); } - SGLineSegmentd lineSegmentToLocal(const SGLineSegmentd& lineSeg) const - { return lineSeg.transform(_toLocal); } - - SGSphered sphereToWorld(const SGSphered& sphere) const - { - SGVec3d center = ptToWorld(sphere.getCenter()); - double radius = _toWorldAmplification*sphere.getRadius(); - return SGSphered(center, radius); - } - SGSphered sphereToLocal(const SGSphered& sphere) const - { - SGVec3d center = ptToLocal(sphere.getCenter()); - double radius = _toLocalAmplification*sphere.getRadius(); - return SGSphered(center, radius); - } - -private: - virtual SGSphered computeBoundingSphere() const; - void updateAmplificationFactors(); - - SGMatrixd _toWorld; - SGMatrixd _toLocal; - double _toWorldAmplification; - double _toLocalAmplification; -}; - -} - -#endif diff --git a/simgear/scene/bvh/BVHVisitor.hxx b/simgear/scene/bvh/BVHVisitor.hxx deleted file mode 100644 index f74f4456..00000000 --- a/simgear/scene/bvh/BVHVisitor.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// 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 BVHVisitor_hxx -#define BVHVisitor_hxx - -namespace simgear { - -class BVHStaticData; - -class BVHGroup; -class BVHTransform; -class BVHMotionTransform; -class BVHStaticGeometry; -class BVHLineGeometry; - -class BVHStaticBinary; -class BVHStaticTriangle; - -class BVHVisitor { -public: - // The magnitudes of pure virtuals is because of the fact that this chaining - // just takes needless runtime. This declaration should force the user of - // this classes to implement a common functionality that should be called - // from each apropriate apply method directly. - virtual ~BVHVisitor() {} - - // High level nodes to handle - virtual void apply(BVHGroup&) = 0; - virtual void apply(BVHTransform&) = 0; - virtual void apply(BVHMotionTransform&) = 0; - virtual void apply(BVHLineGeometry&) = 0; - virtual void apply(BVHStaticGeometry&) = 0; - - // Static tree nodes to handle - virtual void apply(const BVHStaticBinary&, const BVHStaticData&) = 0; - virtual void apply(const BVHStaticTriangle&, const BVHStaticData&) = 0; -}; - -} - -#endif diff --git a/simgear/scene/bvh/CMakeLists.txt b/simgear/scene/bvh/CMakeLists.txt deleted file mode 100644 index 230a6bc6..00000000 --- a/simgear/scene/bvh/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -include (SimGearComponent) - -set(HEADERS - BVHBoundingBoxVisitor.hxx - BVHDebugCollectVisitor.hxx - BVHGroup.hxx - BVHLineGeometry.hxx - BVHLineSegmentVisitor.hxx - BVHMotionTransform.hxx - BVHNearestPointVisitor.hxx - BVHNode.hxx - BVHStaticBinary.hxx - BVHStaticData.hxx - BVHStaticGeometry.hxx - BVHStaticGeometryBuilder.hxx - BVHStaticLeaf.hxx - BVHStaticNode.hxx - BVHStaticTriangle.hxx - BVHSubTreeCollector.hxx - BVHTransform.hxx - BVHVisitor.hxx - ) - -set(SOURCES - BVHGroup.cxx - BVHLineGeometry.cxx - BVHLineSegmentVisitor.cxx - BVHMotionTransform.cxx - BVHNode.cxx - BVHStaticBinary.cxx - BVHStaticGeometry.cxx - BVHStaticLeaf.cxx - BVHStaticNode.cxx - BVHStaticTriangle.cxx - BVHSubTreeCollector.cxx - BVHTransform.cxx - ) - -simgear_scene_component(bvh scene/bvh "${SOURCES}" "${HEADERS}") diff --git a/simgear/scene/bvh/bvhtest.cxx b/simgear/scene/bvh/bvhtest.cxx deleted file mode 100644 index 0f01e7f0..00000000 --- a/simgear/scene/bvh/bvhtest.cxx +++ /dev/null @@ -1,142 +0,0 @@ -// 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. -// - -#include -#include - -#include "BVHNode.hxx" -#include "BVHGroup.hxx" -#include "BVHTransform.hxx" - -#include "BVHStaticData.hxx" - -#include "BVHStaticNode.hxx" -#include "BVHStaticLeaf.hxx" -#include "BVHStaticTriangle.hxx" -#include "BVHStaticBinary.hxx" -#include "BVHStaticGeometry.hxx" - -#include "BVHBoundingBoxVisitor.hxx" -#include "BVHSubTreeCollector.hxx" -#include "BVHLineSegmentVisitor.hxx" -#include "BVHNearestPointVisitor.hxx" - -using namespace simgear; - -BVHNode* -buildSingleTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3) -{ - BVHStaticData* staticData = new BVHStaticData; - unsigned indices[3] = { - staticData->addVertex(v1), - staticData->addVertex(v2), - staticData->addVertex(v3) - }; - BVHStaticTriangle* staticTriangle = new BVHStaticTriangle(~0u, indices); - return new BVHStaticGeometry(staticTriangle, staticData); -} - -bool -testLineIntersections() -{ - SGVec3f v1(-1, -1, 0); - SGVec3f v2(1, -1, 0); - SGVec3f v3(-1, 1, 0); - SGSharedPtr node = buildSingleTriangle(v1, v2, v3); - - SGLineSegmentd lineSegment(SGVec3d(0, 0, -1), SGVec3d(0, 0, 1)); - { - BVHLineSegmentVisitor lineSegmentVisitor(lineSegment); - node->accept(lineSegmentVisitor); - if (lineSegmentVisitor.empty()) - return false; - if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) - return false; - } - - SGVec3d position(1000, 1000, 1000); - SGMatrixd matrix(position); - SGSharedPtr transform1 = new BVHTransform; - transform1->setToWorldTransform(matrix); - transform1->addChild(node); - - SGSharedPtr transform2 = new BVHTransform; - transform2->setToLocalTransform(matrix); - transform2->addChild(transform1); - - { - BVHLineSegmentVisitor lineSegmentVisitor(lineSegment); - transform2->accept(lineSegmentVisitor); - if (lineSegmentVisitor.empty()) - return false; - if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) - return false; - } - - SGSharedPtr transform3 = new BVHMotionTransform; - transform3->setLinearVelocity(SGVec3d(0, 0, 1)); - transform3->setAngularVelocity(SGVec3d(1, 0, 0)); - transform3->addChild(node); - - { - BVHLineSegmentVisitor lineSegmentVisitor(lineSegment, 0); - transform3->accept(lineSegmentVisitor); - if (lineSegmentVisitor.empty()) - return false; - if (!equivalent(lineSegmentVisitor.getPoint(), SGVec3d(0, 0, 0))) - return false; - if (!equivalent(lineSegmentVisitor.getLinearVelocity(), - SGVec3d(0, 1, 1))) - return false; - if (!equivalent(lineSegmentVisitor.getAngularVelocity(), - SGVec3d(1, 0, 0))) - return false; - } - - 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; -} diff --git a/simgear/scene/model/BVHDebugCollectVisitor.hxx b/simgear/scene/model/BVHDebugCollectVisitor.hxx new file mode 100644 index 00000000..e99779ff --- /dev/null +++ b/simgear/scene/model/BVHDebugCollectVisitor.hxx @@ -0,0 +1,211 @@ +// 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 BVHDebugCollectVisitor_hxx +#define BVHDebugCollectVisitor_hxx + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +namespace simgear { + +class BVHNode; +class BVHStaticNode; + +class BVHDebugCollectVisitor : public BVHVisitor { +public: + BVHDebugCollectVisitor(const double& time, unsigned level = ~0u) : + _group(new osg::Group), + _time(time), + _level(level), + _currentLevel(0) + { + osg::StateSet* stateSet = _group->getOrCreateStateSet(); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateSet->setAttribute(new osg::Depth(osg::Depth::LESS, 0, 1, false)); + osg::BlendFunc *blendFunc; + blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, + osg::BlendFunc::DST_ALPHA); + stateSet->setAttributeAndModes(blendFunc); + osg::PolygonOffset* polygonOffset = new osg::PolygonOffset(-1, -1); + stateSet->setAttributeAndModes(polygonOffset); + } + virtual ~BVHDebugCollectVisitor() + { } + + virtual void apply(BVHGroup& node) + { + addNodeSphere(node); + ++_currentLevel; + node.traverse(*this); + --_currentLevel; + } + virtual void apply(BVHTransform& node) + { + addNodeSphere(node); + osg::ref_ptr oldGroup = _group; + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrix(node.getToWorldTransform().data())); + _group = transform; + ++_currentLevel; + node.traverse(*this); + --_currentLevel; + _group = oldGroup; + if (transform->getNumChildren()) + _group->addChild(transform.get()); + } + virtual void apply(BVHMotionTransform& node) + { + addNodeSphere(node); + osg::ref_ptr oldGroup = _group; + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrix(node.getToWorldTransform(_time).data())); + _group = transform; + ++_currentLevel; + node.traverse(*this); + --_currentLevel; + _group = oldGroup; + if (transform->getNumChildren()) + _group->addChild(transform.get()); + } + virtual void apply(BVHLineGeometry&) + { + } + virtual void apply(BVHStaticGeometry& node) + { + addNodeSphere(node); + ++_currentLevel; + node.traverse(*this); + --_currentLevel; + } + + virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data) + { + addNodeBox(node, data); + ++_currentLevel; + node.traverse(*this, data); + --_currentLevel; + } + virtual void apply(const BVHStaticTriangle& node, const BVHStaticData& data) + { + addNodeBox(node, data); + addTriangle(node.getTriangle(data), osg::Vec4(0.5, 0, 0.5, 0.2)); + } + + osg::Node* getNode() const { return _group.get(); } + + static unsigned allLevels() { return ~0u; } + static unsigned triangles() { return ~0u - 1; } + +private: + void addTriangle(const SGTrianglef& triangle, const osg::Vec4& color) + { + if (_level != triangles()) + return; + + osg::Geometry* geometry = new osg::Geometry; + + osg::Vec3Array* vertices = new osg::Vec3Array; + vertices->push_back(toOsg(triangle.getVertex(0))); + vertices->push_back(toOsg(triangle.getVertex(1))); + vertices->push_back(toOsg(triangle.getVertex(2))); + + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(color); + + geometry->setVertexArray(vertices); + geometry->setColorArray(colors); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3)); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + _group->addChild(geode); + } + + void addNodeSphere(const BVHNode& node) + { + if (_level != ~0u && _level != _currentLevel) + return; + SGSphered sphere = node.getBoundingSphere(); + osg::Sphere* shape = new osg::Sphere; + shape->setCenter(toOsg(sphere.getCenter())); + shape->setRadius(sphere.getRadius()); + addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f)); + } + + void addNodeBox(const BVHStaticNode& node, const BVHStaticData& data) + { + if (_level != ~0u && _level != _currentLevel) + return; + BVHBoundingBoxVisitor bbv; + node.accept(bbv, data); + osg::Box* shape = new osg::Box; + shape->setCenter(toOsg(bbv.getBox().getCenter())); + shape->setHalfLengths(toOsg((0.5*bbv.getBox().getSize()))); + addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f)); + } + + void addShape(osg::Shape* shape, const osg::Vec4& color) + { + osg::ShapeDrawable* shapeDrawable = new osg::ShapeDrawable; + shapeDrawable->setColor(color); + shapeDrawable->setShape(shape); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(shapeDrawable); + _group->addChild(geode); + } + + osg::ref_ptr _group; + const double _time; + const unsigned _level; + unsigned _currentLevel; +}; + +} + +#endif diff --git a/simgear/scene/model/BoundingVolumeBuildVisitor.hxx b/simgear/scene/model/BoundingVolumeBuildVisitor.hxx index 9155bcec..f544606b 100644 --- a/simgear/scene/model/BoundingVolumeBuildVisitor.hxx +++ b/simgear/scene/model/BoundingVolumeBuildVisitor.hxx @@ -33,7 +33,7 @@ #include #include -#include +#include namespace simgear { diff --git a/simgear/scene/model/CMakeLists.txt b/simgear/scene/model/CMakeLists.txt index 83264bda..8f2760e0 100644 --- a/simgear/scene/model/CMakeLists.txt +++ b/simgear/scene/model/CMakeLists.txt @@ -2,6 +2,7 @@ include (SimGearComponent) set(HEADERS BoundingVolumeBuildVisitor.hxx + BVHDebugCollectVisitor.hxx CheckSceneryVisitor.hxx ConditionNode.hxx ModelRegistry.hxx diff --git a/simgear/scene/model/SGInteractionAnimation.cxx b/simgear/scene/model/SGInteractionAnimation.cxx index 171f4939..e6af9862 100644 --- a/simgear/scene/model/SGInteractionAnimation.cxx +++ b/simgear/scene/model/SGInteractionAnimation.cxx @@ -26,10 +26,10 @@ #include #include +#include +#include #include #include -#include -#include class SGInteractionAnimation::LineCollector : public osg::NodeVisitor { struct LinePrimitiveFunctor { diff --git a/simgear/scene/util/SGSceneUserData.hxx b/simgear/scene/util/SGSceneUserData.hxx index d0c69d03..c2a08352 100644 --- a/simgear/scene/util/SGSceneUserData.hxx +++ b/simgear/scene/util/SGSceneUserData.hxx @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "SGPickCallback.hxx" class SGSceneUserData : public osg::Object {