31#include <osg/Drawable>
33#include <osg/Geometry>
35#include <osg/Transform>
36#include <osg/MatrixTransform>
37#include <osg/PositionAttitudeTransform>
38#include <osg/CameraView>
39#include <osgTerrain/TerrainTile>
40#include <osgTerrain/Terrain>
42#include <simgear/sg_inlines.h>
43#include <simgear/constants.h>
44#include <simgear/debug/logstream.hxx>
45#include <simgear/math/SGMisc.hxx>
46#include <simgear/scene/material/mat.hxx>
47#include <simgear/scene/util/SGNodeMasks.hxx>
48#include <simgear/scene/util/SGSceneUserData.hxx>
49#include <simgear/scene/util/OsgMath.hxx>
51#include <simgear/bvh/BVHNode.hxx>
52#include <simgear/bvh/BVHGroup.hxx>
53#include <simgear/bvh/BVHTransform.hxx>
54#include <simgear/bvh/BVHMotionTransform.hxx>
55#include <simgear/bvh/BVHLineGeometry.hxx>
56#include <simgear/bvh/BVHStaticGeometry.hxx>
57#include <simgear/bvh/BVHStaticData.hxx>
58#include <simgear/bvh/BVHStaticNode.hxx>
59#include <simgear/bvh/BVHStaticTriangle.hxx>
60#include <simgear/bvh/BVHStaticBinary.hxx>
61#include <simgear/bvh/BVHSubTreeCollector.hxx>
62#include <simgear/bvh/BVHLineSegmentVisitor.hxx>
63#include <simgear/bvh/BVHNearestPointVisitor.hxx>
65#ifdef GROUNDCACHE_DEBUG
66#include <simgear/scene/model/BVHDebugCollectVisitor.hxx>
79 CacheFill(
const SGVec3d& center,
const SGVec3d& down,
const double& radius,
80 const double& startTime,
const double& endTime) :
81 osg::NodeVisitor(
osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
85 _startTime(startTime),
88 _maxDown(SGGeod::fromCart(center).getElevationM() + 9999),
92 setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
94 virtual void apply(osg::Node& node)
102 virtual void apply(osg::Group& group)
107 simgear::BVHSubTreeCollector::NodeList parentNodeList;
108 mSubTreeCollector.pushNodeList(parentNodeList);
113 mSubTreeCollector.popNodeList(parentNodeList);
115 virtual void apply(osg::Transform& transform)
117 virtual void apply(osg::Camera& camera)
119 if (camera.getRenderOrder() != osg::Camera::NESTED_RENDER)
123 virtual void apply(osg::CameraView& transform)
125 virtual void apply(osg::MatrixTransform& transform)
127 virtual void apply(osg::PositionAttitudeTransform& transform)
133 if (transform.getReferenceFrame() != osg::Transform::RELATIVE_RF)
139 osg::Matrix inverseMatrix;
140 if (!transform.computeWorldToLocalMatrix(inverseMatrix,
this))
143 if (!transform.computeLocalToWorldMatrix(matrix,
this))
147 const SGSceneUserData::Velocity* velocity =
getVelocity(transform);
149 SGVec3d center = _center;
150 SGVec3d down = _down;
151 double radius = _radius;
152 bool haveHit = _haveHit;
153 const simgear::BVHMaterial* material = _material;
156 _center = toSG(inverseMatrix.preMult(toOsg(_center)));
157 _down = toSG(osg::Matrix::transform3x3(toOsg(_down), inverseMatrix));
159 SGVec3d staticCenter(_center);
161 double dtStart = velocity->referenceTime - _startTime;
162 SGVec3d startCenter = staticCenter + dtStart*velocity->linear;
163 SGQuatd startOr(SGQuatd::fromAngleAxis(dtStart*velocity->angular));
164 startCenter = startOr.transform(startCenter);
166 double dtEnd = velocity->referenceTime - _endTime;
167 SGVec3d endCenter = staticCenter + dtEnd*velocity->linear;
168 SGQuatd endOr(SGQuatd::fromAngleAxis(dtEnd*velocity->angular));
169 endCenter = endOr.transform(endCenter);
171 _center = 0.5*(startCenter + endCenter);
172 _down = startOr.transform(_down);
173 _radius += 0.5*dist(startCenter, endCenter);
176 simgear::BVHSubTreeCollector::NodeList parentNodeList;
177 mSubTreeCollector.pushNodeList(parentNodeList);
182 if (mSubTreeCollector.haveChildren()) {
184 simgear::BVHMotionTransform* bvhTransform;
185 bvhTransform =
new simgear::BVHMotionTransform;
186 bvhTransform->setToWorldTransform(SGMatrixd(matrix.ptr()));
187 bvhTransform->setLinearVelocity(velocity->linear);
188 bvhTransform->setAngularVelocity(velocity->angular);
189 bvhTransform->setReferenceTime(velocity->referenceTime);
190 bvhTransform->setStartTime(_startTime);
191 bvhTransform->setEndTime(_endTime);
192 bvhTransform->setId(velocity->id);
194 mSubTreeCollector.popNodeList(parentNodeList, bvhTransform);
196 simgear::BVHTransform* bvhTransform;
197 bvhTransform =
new simgear::BVHTransform;
198 bvhTransform->setToWorldTransform(SGMatrixd(matrix.ptr()));
200 mSubTreeCollector.popNodeList(parentNodeList, bvhTransform);
203 mSubTreeCollector.popNodeList(parentNodeList);
208 double dt = _startTime - velocity->referenceTime;
209 SGQuatd ori(SGQuatd::fromAngleAxis(dt*velocity->angular));
210 _sceneryHit = ori.transform(_sceneryHit);
211 _sceneryHit += dt*velocity->linear;
213 _sceneryHit = toSG(matrix.preMult(toOsg(_sceneryHit)));
215 _material = material;
226 SGSceneUserData* userData = SGSceneUserData::getSceneUserData(&node);
229 return userData->getVelocity();
233 SGSceneUserData* userData = SGSceneUserData::getSceneUserData(&node);
236 return userData->getBVHNode();
245 SGLineSegmentd line(_center + _radius*_down, _center + _maxDown*_down);
246 simgear::BVHLineSegmentVisitor lineSegmentVisitor(line, _startTime);
247 bvNode->accept(lineSegmentVisitor);
248 if (!lineSegmentVisitor.empty()) {
249 _sceneryHit = lineSegmentVisitor.getPoint();
250 _material = lineSegmentVisitor.getMaterial();
251 _maxDown = SGMiscd::max(_radius, dot(_down, _sceneryHit - _center));
257 mSubTreeCollector.setSphere(SGSphered(_center, _radius));
258 bvNode->accept(mSubTreeCollector);
266 SGLineSegmentd downSeg(_center, _center + _maxDown*_down);
267 double maxDist = bound._radius + _radius;
268 SGVec3d boundCenter(toVec3d(toSG(bound._center)));
269 return distSqr(downSeg, boundCenter) <= maxDist*maxDist;
273 {
return mSubTreeCollector.getNode(); }
278 {
return SGGeod::fromCart(_sceneryHit).getElevationM(); }
280 {
return _material; }
289 simgear::BVHSubTreeCollector mSubTreeCollector;
292 const simgear::BVHMaterial* _material;
300 cache_time_offset(0),
302 reference_wgs84_point(SGVec3d(0, 0, 0)),
303 reference_vehicle_radius(0),
307#ifdef GROUNDCACHE_DEBUG
308 _lookupTime = SGTimeStamp::fromSec(0.0);
310 _buildTime = SGTimeStamp::fromSec(0.0);
321 const SGVec3d& pt,
double rad)
324 SG_LOG(SG_FLIGHT, SG_DEV_WARN,
"FGGroundCache::prepare_ground_cache passed an excessive radius");
328#ifdef GROUNDCACHE_DEBUG
329 SGTimeStamp t0 = SGTimeStamp::now();
333 found_ground =
false;
335 SGGeod geodPt = SGGeod::fromCart(pt);
338 if (!
globals->get_scenery()->schedule_scenery(geodPt, rad, 1.0)) {
339 SG_LOG(SG_FLIGHT, SG_BULK,
"prepare_ground_cache(): scenery_available "
340 "returns false at " << geodPt <<
" " << pt <<
" " << rad);
347 rad = SGMiscd::max(200, rad);
350 reference_wgs84_point = pt;
351 reference_vehicle_radius = rad;
353 cache_ref_time = startSimTime;
356 SGQuatd hlToEc = SGQuatd::fromLonLat(geodPt);
357 down = hlToEc.rotate(SGVec3d(0, 0, 1));
360 startSimTime += cache_time_offset;
361 endSimTime += cache_time_offset;
362 CacheFill subtreeCollector(pt, down, rad, startSimTime, endSimTime);
363 globals->get_scenery()->get_scene_graph()->accept(subtreeCollector);
364 _localBvhTree = subtreeCollector.
getBVHNode();
372 }
else if (_localBvhTree) {
375 SGLineSegmentd line(pt + reference_vehicle_radius*down, pt - 1e3*down);
376 simgear::BVHLineSegmentVisitor lineSegmentVisitor(line, startSimTime);
377 _localBvhTree->accept(lineSegmentVisitor);
379 if (!lineSegmentVisitor.empty()) {
380 SGGeod geodPt = SGGeod::fromCart(lineSegmentVisitor.getPoint());
381 _altitude = geodPt.getElevationM();
382 _material = lineSegmentVisitor.getMaterial();
391 found_ground =
globals->get_scenery()->
392 get_elevation_m(SGGeod::fromGeodM(geodPt, 10000), alt, &_material);
404#ifdef GROUNDCACHE_DEBUG
405 t0 = SGTimeStamp::now() - t0;
409 if (_buildCount > 60) {
410 double buildTime = 0;
412 buildTime = _buildTime.toSecs()/_buildCount;
413 double lookupTime = 0;
415 lookupTime = _lookupTime.toSecs()/_lookupCount;
416 _buildTime = SGTimeStamp::fromSec(0.0);
418 _lookupTime = SGTimeStamp::fromSec(0.0);
420 SG_LOG(SG_FLIGHT, SG_ALERT,
"build time = " << buildTime
421 <<
", lookup Time = " << lookupTime);
424 if (!_group.valid()) {
425 _group =
new osg::Group;
426 globals->get_scenery()->get_scene_graph()->addChild(_group);
427 fgSetInt(
"/fdm/groundcache-debug-level", -3);
429 _group->removeChildren(0, _group->getNumChildren());
431 int level =
fgGetInt(
"/fdm/groundcache-debug-level");
433 simgear::BVHDebugCollectVisitor debug(endSimTime, level);
434 _localBvhTree->accept(debug);
435 _group->addChild(debug.getNode());
446 pt = reference_wgs84_point;
447 rad = reference_vehicle_radius;
448 ref_time = cache_ref_time;
467 leaf.traverse(*
this);
469 virtual void apply(BVHPageNode& leaf)
473 leaf.traverse(*
this);
475 virtual void apply(BVHTransform& transform)
480 transform.traverse(*
this);
488 virtual void apply(BVHMotionTransform& transform)
493 if (
_id == transform.getId()) {
496 transform.traverse(*
this);
500 SGMatrixd toWorld = transform.getToWorldTransform(
_time);
501 SGVec3d referencePoint =
_bodyToWorld.xformPt(SGVec3d::zeros());
509 virtual void apply(BVHLineGeometry& node) { }
510 virtual void apply(BVHStaticGeometry& node) { }
511 virtual void apply(BVHTerrainTile& node) { }
513 virtual void apply(
const BVHStaticBinary&,
const BVHStaticData&) { }
514 virtual void apply(
const BVHStaticTriangle&,
const BVHStaticData&) { }
541 SGVec3d& angularVel, simgear::BVHNode::Id
id)
546 t += cache_time_offset;
548 _localBvhTree->accept(bodyFinder);
554 if (bodyFinder.
empty())
570 if (!intersects(
_sphere, leaf.getBoundingSphere()))
572 leaf.traverse(*
this);
574 virtual void apply(BVHPageNode& leaf)
576 if (!intersects(
_sphere, leaf.getBoundingSphere()))
578 leaf.traverse(*
this);
580 virtual void apply(BVHTransform& transform)
582 if (!intersects(
_sphere, transform.getBoundingSphere()))
586 _sphere = transform.sphereToLocal(sphere);
590 transform.traverse(*
this);
598 _sphere.setCenter(sphere.getCenter());
600 virtual void apply(BVHMotionTransform& transform)
602 if (!intersects(
_sphere, transform.getBoundingSphere()))
610 transform.traverse(*
this);
613 SGMatrixd toWorld = transform.getToWorldTransform(
_time);
615 += transform.getLinearVelocityAt(
_lineSegment.getStart());
622 _sphere.setCenter(sphere.getCenter());
624 virtual void apply(BVHLineGeometry& node)
626 if (node.getType() != BVHLineGeometry::CarrierCatapult)
629 SGLineSegmentd lineSegment(node.getLineSegment());
630 if (!intersects(
_sphere, lineSegment))
634 double dist = distSqr(lineSegment,
getSphere().getCenter());
640 virtual void apply(BVHStaticGeometry& node) { }
641 virtual void apply(BVHTerrainTile& node) { }
643 virtual void apply(
const BVHStaticBinary&,
const BVHStaticData&) { }
644 virtual void apply(
const BVHStaticTriangle&,
const BVHStaticData&) { }
674 SGVec3d end[2], SGVec3d vel[2])
676 double maxDistance = 1000;
679 t += cache_time_offset;
682 _localBvhTree->accept(catapultFinder);
704 SGVec3d& normal, SGVec3d& linearVel, SGVec3d& angularVel,
705 simgear::BVHNode::Id&
id,
const simgear::BVHMaterial*& material)
708 throw sg_range_exception(
"FGGroundCache::get_agl: NaN position input");
711#ifdef GROUNDCACHE_DEBUG
712 SGTimeStamp t0 = SGTimeStamp::now();
716 SGLineSegmentd line(pt, pt + 10*reference_vehicle_radius*down);
717 t += cache_time_offset;
718 simgear::BVHLineSegmentVisitor lineSegmentVisitor(line, t);
720 _localBvhTree->accept(lineSegmentVisitor);
722#ifdef GROUNDCACHE_DEBUG
723 t0 = SGTimeStamp::now() - t0;
728 if (!lineSegmentVisitor.empty()) {
730 contact = lineSegmentVisitor.getPoint();
731 normal = lineSegmentVisitor.getNormal();
732 if (0 < dot(normal, down))
734 linearVel = lineSegmentVisitor.getLinearVelocity();
735 angularVel = lineSegmentVisitor.getAngularVelocity();
736 material = lineSegmentVisitor.getMaterial();
737 id = lineSegmentVisitor.getId();
744 SGGeod geodPt = SGGeod::fromCart(pt);
745 geodPt.setElevationM(_altitude);
746 contact = SGVec3d::fromGeod(geodPt);
748 linearVel = SGVec3d(0, 0, 0);
749 angularVel = SGVec3d(0, 0, 0);
750 material = _material;
760 SGVec3d& contact, SGVec3d& linearVel,
761 SGVec3d& angularVel, simgear::BVHNode::Id&
id,
762 const simgear::BVHMaterial*& material)
767#ifdef GROUNDCACHE_DEBUG
768 SGTimeStamp t0 = SGTimeStamp::now();
772 SGSphered sphere(pt, maxDist);
773 t += cache_time_offset;
774 simgear::BVHNearestPointVisitor nearestPointVisitor(sphere, t);
775 _localBvhTree->accept(nearestPointVisitor);
777#ifdef GROUNDCACHE_DEBUG
778 t0 = SGTimeStamp::now() - t0;
783 if (nearestPointVisitor.empty())
787 contact = nearestPointVisitor.getPoint();
788 linearVel = nearestPointVisitor.getLinearVelocity();
789 angularVel = nearestPointVisitor.getAngularVelocity();
790 material = nearestPointVisitor.getMaterial();
791 id = nearestPointVisitor.getId();
800 _linearVelocity(SGVec3d::zeros()),
801 _angularVelocity(SGVec3d::zeros()),
807 _triangles[0].set(pt[0], pt[1], pt[2]);
808 _triangles[1].set(pt[0], pt[2], pt[3]);
816 leaf.traverse(*
this);
818 virtual void apply(BVHPageNode& leaf)
823 leaf.traverse(*
this);
825 virtual void apply(BVHTransform& transform)
830 SGTriangled triangles[2] = { _triangles[0], _triangles[1] };
831 _triangles[0] = triangles[0].transform(transform.getToLocalTransform());
832 _triangles[1] = triangles[1].transform(transform.getToLocalTransform());
834 transform.traverse(*
this);
837 _lineSegment = transform.lineSegmentToWorld(_lineSegment);
838 _linearVelocity = transform.vecToWorld(_linearVelocity);
839 _angularVelocity = transform.vecToWorld(_angularVelocity);
841 _triangles[0] = triangles[0];
842 _triangles[1] = triangles[1];
844 virtual void apply(BVHMotionTransform& transform)
849 SGMatrixd toLocal = transform.getToLocalTransform(_time);
851 SGTriangled triangles[2] = { _triangles[0], _triangles[1] };
852 _triangles[0] = triangles[0].transform(toLocal);
853 _triangles[1] = triangles[1].transform(toLocal);
855 transform.traverse(*
this);
858 SGMatrixd toWorld = transform.getToWorldTransform(_time);
860 += transform.getLinearVelocityAt(_lineSegment.getStart());
861 _angularVelocity += transform.getAngularVelocity();
862 _linearVelocity = toWorld.xformVec(_linearVelocity);
863 _angularVelocity = toWorld.xformVec(_angularVelocity);
864 _lineSegment = _lineSegment.transform(toWorld);
866 _triangles[0] = triangles[0];
867 _triangles[1] = triangles[1];
869 virtual void apply(BVHLineGeometry& node)
871 if (node.getType() != BVHLineGeometry::CarrierWire)
873 SGLineSegmentd lineSegment(node.getLineSegment());
877 _lineSegment = lineSegment;
878 _linearVelocity = SGVec3d::zeros();
879 _angularVelocity = SGVec3d::zeros();
882 virtual void apply(BVHStaticGeometry& node) { }
883 virtual void apply(BVHTerrainTile& node) { }
885 virtual void apply(
const BVHStaticBinary&,
const BVHStaticData&) { }
886 virtual void apply(
const BVHStaticTriangle&,
const BVHStaticData&) { }
892 if (intersects(_triangles[0], sphere))
894 if (intersects(_triangles[1], sphere))
902 if (intersects(_triangles[0], lineSegment))
904 if (intersects(_triangles[1], lineSegment))
910 {
return _lineSegment; }
912 {
return _linearVelocity; }
914 {
return _angularVelocity; }
920 SGLineSegmentd _lineSegment;
921 SGVec3d _linearVelocity;
922 SGVec3d _angularVelocity;
923 const BVHLineGeometry* _wire;
925 SGTriangled _triangles[2];
932 t += cache_time_offset;
935 _localBvhTree->accept(wireIntersector);
937 _wire = wireIntersector.
getWire();
938 return (_wire != NULL);
946 _lineSegment(SGVec3d::zeros(), SGVec3d::zeros()),
947 _linearVelocity(SGVec3d::zeros()),
948 _angularVelocity(SGVec3d::zeros()),
949 _haveLineSegment(false)
954 if (_haveLineSegment)
956 leaf.traverse(*
this);
958 virtual void apply(BVHPageNode& leaf)
960 if (_haveLineSegment)
962 leaf.traverse(*
this);
964 virtual void apply(BVHTransform& transform)
966 if (_haveLineSegment)
969 transform.traverse(*
this);
971 if (_haveLineSegment) {
972 _linearVelocity = transform.vecToWorld(_linearVelocity);
973 _angularVelocity = transform.vecToWorld(_angularVelocity);
974 _lineSegment = transform.lineSegmentToWorld(_lineSegment);
977 virtual void apply(BVHMotionTransform& transform)
979 if (_haveLineSegment)
982 transform.traverse(*
this);
984 if (_haveLineSegment) {
985 SGMatrixd toWorld = transform.getToWorldTransform(_time);
987 += transform.getLinearVelocityAt(_lineSegment.getStart());
988 _angularVelocity += transform.getAngularVelocity();
989 _linearVelocity = toWorld.xformVec(_linearVelocity);
990 _angularVelocity = toWorld.xformVec(_angularVelocity);
991 _lineSegment = _lineSegment.transform(toWorld);
994 virtual void apply(BVHLineGeometry& node)
996 if (_haveLineSegment)
1000 if (node.getType() != BVHLineGeometry::CarrierWire)
1002 _lineSegment = SGLineSegmentd(node.getLineSegment());
1003 _linearVelocity = SGVec3d::zeros();
1004 _angularVelocity = SGVec3d::zeros();
1005 _haveLineSegment =
true;
1007 virtual void apply(BVHStaticGeometry&) { }
1010 virtual void apply(
const BVHStaticBinary&,
const BVHStaticData&) { }
1011 virtual void apply(
const BVHStaticTriangle&,
const BVHStaticData&) { }
1014 {
return _lineSegment; }
1017 {
return _haveLineSegment; }
1020 {
return _linearVelocity; }
1022 {
return _angularVelocity; }
1025 const BVHLineGeometry* _wire;
1028 SGLineSegmentd _lineSegment;
1029 SGVec3d _linearVelocity;
1030 SGVec3d _angularVelocity;
1032 bool _haveLineSegment;
1042 t += cache_time_offset;
1045 _localBvhTree->accept(wireFinder);
virtual void apply(BVHGroup &leaf)
BodyFinder(BVHNode::Id id, const double &t)
virtual void apply(BVHLineGeometry &node)
const SGMatrixd & getBodyToWorld() const
const SGVec3d & getLinearVelocity() const
virtual void apply(BVHStaticGeometry &node)
const SGVec3d & getAngularVelocity() const
virtual void apply(BVHMotionTransform &transform)
virtual void apply(BVHTerrainTile &node)
virtual void apply(const BVHStaticBinary &, const BVHStaticData &)
virtual void apply(const BVHStaticTriangle &, const BVHStaticData &)
virtual void apply(BVHTransform &transform)
virtual void apply(BVHPageNode &leaf)
virtual void apply(osg::Camera &camera)
void addBoundingVolume(osg::Node &node)
bool getHaveElevationBelowCache() const
bool testBoundingSphere(const osg::BoundingSphere &bound) const
void handleTransform(osg::Transform &transform)
virtual void apply(osg::MatrixTransform &transform)
const SGSceneUserData::Velocity * getVelocity(osg::Node &node)
double getElevationBelowCache() const
CacheFill(const SGVec3d ¢er, const SGVec3d &down, const double &radius, const double &startTime, const double &endTime)
virtual void apply(osg::CameraView &transform)
virtual void apply(osg::Group &group)
virtual void apply(osg::PositionAttitudeTransform &transform)
virtual void apply(osg::Node &node)
virtual void apply(osg::Transform &transform)
SGSharedPtr< simgear::BVHNode > getBVHNode() const
simgear::BVHNode * getNodeBoundingVolume(osg::Node &node)
const simgear::BVHMaterial * getMaterialBelowCache() const
const SGSphered & getSphere() const
void setSphere(const SGSphered &sphere)
virtual void apply(BVHStaticGeometry &node)
bool getHaveLineSegment() const
virtual void apply(const BVHStaticBinary &, const BVHStaticData &)
virtual void apply(BVHTransform &transform)
virtual void apply(BVHTerrainTile &node)
virtual void apply(BVHMotionTransform &transform)
virtual void apply(const BVHStaticTriangle &, const BVHStaticData &)
virtual void apply(BVHPageNode &leaf)
SGLineSegmentd _lineSegment
virtual void apply(BVHGroup &leaf)
const SGLineSegmentd & getLineSegment() const
const SGVec3d & getLinearVelocity() const
virtual void apply(BVHLineGeometry &node)
CatapultFinder(const SGSphered &sphere, const double &t)
const SGVec3d & getAngularVelocity() const
virtual void apply(const BVHStaticTriangle &, const BVHStaticData &)
virtual void apply(BVHLineGeometry &node)
virtual void apply(BVHGroup &leaf)
virtual void apply(BVHMotionTransform &transform)
WireFinder(const BVHLineGeometry *wire, const double &t)
const SGVec3d & getLinearVelocity() const
virtual void apply(BVHTransform &transform)
const SGVec3d & getAngularVelocity() const
virtual void apply(BVHTerrainTile &)
virtual void apply(BVHStaticGeometry &)
virtual void apply(const BVHStaticBinary &, const BVHStaticData &)
virtual void apply(BVHPageNode &leaf)
bool getHaveLineSegment() const
const SGLineSegmentd & getLineSegment() const
virtual void apply(BVHLineGeometry &node)
virtual void apply(BVHTransform &transform)
virtual void apply(const BVHStaticBinary &, const BVHStaticData &)
virtual void apply(const BVHStaticTriangle &, const BVHStaticData &)
const SGVec3d & getAngularVelocity() const
bool _intersects(const SGSphered &sphere) const
const BVHLineGeometry * getWire() const
virtual void apply(BVHTerrainTile &node)
const SGVec3d & getLinearVelocity() const
virtual void apply(BVHMotionTransform &transform)
WireIntersector(const SGVec3d pt[4], const double &t)
bool _intersects(const SGLineSegmentd &lineSegment) const
const SGLineSegmentd & getLineSegment() const
virtual void apply(BVHStaticGeometry &node)
virtual void apply(BVHGroup &leaf)
virtual void apply(BVHPageNode &leaf)
bool get_body(double t, SGMatrixd &bodyToWorld, SGVec3d &linearVel, SGVec3d &angularVel, simgear::BVHNode::Id id)
bool get_agl(double t, const SGVec3d &pt, SGVec3d &contact, SGVec3d &normal, SGVec3d &linearVel, SGVec3d &angularVel, simgear::BVHNode::Id &id, const simgear::BVHMaterial *&material)
bool is_valid(double &ref_time, SGVec3d &pt, double &rad)
double get_cat(double t, const SGVec3d &pt, SGVec3d end[2], SGVec3d vel[2])
bool get_nearest(double t, const SGVec3d &pt, double maxDist, SGVec3d &contact, SGVec3d &linearVel, SGVec3d &angularVel, simgear::BVHNode::Id &id, const simgear::BVHMaterial *&material)
bool prepare_ground_cache(double startSimTime, double endSimTime, const SGVec3d &pt, double rad)
bool get_wire_ends(double t, SGVec3d end[2], SGVec3d vel[2])
bool caught_wire(double t, const SGVec3d pt[4])
int fgGetInt(const char *name, int defaultValue)
Get an int value for a property.
bool fgSetInt(const char *name, int val)
Set an int value for a property.