1 // Copyright (C) 2009 - 2012 Mathias Froehlich
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License as
5 // published by the Free Software Foundation; either version 2 of the
6 // License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "AIObject.hxx"
23 #include <simgear/bvh/BVHLineSegmentVisitor.hxx>
24 #include <simgear/bvh/BVHNode.hxx>
25 #include <simgear/math/SGGeometry.hxx>
27 #include "AIManager.hxx"
31 AIObject::AIObject() :
32 _environment(new AIEnvironment),
33 _subsystemGroup(new AISubsystemGroup)
42 AIObject::init(AIManager& manager)
44 _simTime = manager.getSimTime();
48 AIObject::update(AIManager& manager, const SGTimeStamp& simTime)
54 AIObject::shutdown(AIManager& manager)
56 _simTime = SGTimeStamp();
60 AIObject::setGroundCache(const AIPhysics& physics, AIBVHPager& pager, const SGTimeStamp& dt)
62 SGVec3d point = physics.getLocation().getPosition();
63 double linearVelocity = norm(physics.getLinearBodyVelocity());
64 // The 2 is a security factor for accelerations, but at least 100 meters
65 double radius = std::max(100.0, 2*dt.toSecs()*linearVelocity);
66 SGSphered requiredSphere(point, radius);
67 /// Are we already good enough?
68 if (requiredSphere.inside(_querySphere))
70 // Now query something somehow bigger to avoid querying again in the next frame
71 SGSphered sphere(point, 4*radius);
72 _node = pager.getBoundingVolumes(sphere);
75 _querySphere = sphere;
79 AIObject::getGroundIntersection(SGVec3d& point, SGVec3d& normal, const SGLineSegmentd& lineSegment) const
83 simgear::BVHLineSegmentVisitor lineSegmentVisitor(lineSegment);
84 _node->accept(lineSegmentVisitor);
85 if (lineSegmentVisitor.empty())
87 normal = lineSegmentVisitor.getNormal();
88 point = lineSegmentVisitor.getPoint();
93 AIObject::getGroundIntersection(SGPlaned& plane, const SGLineSegmentd& lineSegment) const
97 if (!getGroundIntersection(point, normal, lineSegment))
99 plane = SGPlaned(normal, point);