Ensure transient octrees bypass the NavCache
This commit is contained in:
parent
a17180f5b0
commit
72ec70f275
2 changed files with 66 additions and 65 deletions
|
@ -43,8 +43,8 @@ namespace flightgear
|
||||||
namespace Octree
|
namespace Octree
|
||||||
{
|
{
|
||||||
|
|
||||||
std::unique_ptr<Node> global_spatialOctree;
|
static std::unique_ptr<Node> global_spatialOctree;
|
||||||
std::unique_ptr<Node> global_transientOctree;
|
static std::unique_ptr<Node> global_transientOctree;
|
||||||
|
|
||||||
double RADIUS_EARTH_M = 7000 * 1000.0; // 7000km is plenty
|
double RADIUS_EARTH_M = 7000 * 1000.0; // 7000km is plenty
|
||||||
|
|
||||||
|
@ -98,9 +98,11 @@ Node *Node::findNodeForBox(const SGBoxd&) const
|
||||||
return const_cast<Node*>(this);
|
return const_cast<Node*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Leaf::Leaf(const SGBoxd& aBox, int64_t aIdent, bool persistent) : Node(aBox, aIdent, persistent),
|
Leaf::Leaf(const SGBoxd& aBox, int64_t aIdent, bool persistent) : Node(aBox, aIdent, persistent)
|
||||||
childrenLoaded(false)
|
|
||||||
{
|
{
|
||||||
|
if (!persistent) {
|
||||||
|
_childrenLoaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Leaf::visit(const SGVec3d& aPos, double aCutoff,
|
void Leaf::visit(const SGVec3d& aPos, double aCutoff,
|
||||||
|
@ -152,9 +154,9 @@ void Leaf::insertChild(FGPositioned::Type ty, PositionedID id)
|
||||||
|
|
||||||
void Leaf::loadChildren()
|
void Leaf::loadChildren()
|
||||||
{
|
{
|
||||||
if (childrenLoaded) {
|
if (_childrenLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavDataCache* cache = NavDataCache::instance();
|
NavDataCache* cache = NavDataCache::instance();
|
||||||
for (const auto& tp : cache->getOctreeLeafChildren(guid())) {
|
for (const auto& tp : cache->getOctreeLeafChildren(guid())) {
|
||||||
|
@ -162,15 +164,17 @@ void Leaf::loadChildren()
|
||||||
children.insert(children.end(), tp);
|
children.insert(children.end(), tp);
|
||||||
} // of leaf members iteration
|
} // of leaf members iteration
|
||||||
|
|
||||||
childrenLoaded = true;
|
_childrenLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Branch::Branch(const SGBoxd& aBox, int64_t aIdent, bool persistent) : Node(aBox, aIdent, persistent),
|
Branch::Branch(const SGBoxd& aBox, int64_t aIdent, bool persistent) : Node(aBox, aIdent, persistent)
|
||||||
childrenLoaded(false)
|
|
||||||
{
|
{
|
||||||
memset(children, 0, sizeof(Node*) * 8);
|
_children.fill(nullptr);
|
||||||
|
if (!_persistent) {
|
||||||
|
_childrenLoaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Branch::visit(const SGVec3d& aPos, double aCutoff,
|
void Branch::visit(const SGVec3d& aPos, double aCutoff,
|
||||||
|
@ -179,16 +183,16 @@ void Branch::visit(const SGVec3d& aPos, double aCutoff,
|
||||||
{
|
{
|
||||||
loadChildren();
|
loadChildren();
|
||||||
for (unsigned int i=0; i<8; ++i) {
|
for (unsigned int i=0; i<8; ++i) {
|
||||||
if (!children[i]) {
|
if (!_children[i]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double d = _children[i]->distToNearest(aPos);
|
||||||
|
if (d > aCutoff) {
|
||||||
|
continue; // exceeded cutoff
|
||||||
}
|
}
|
||||||
|
|
||||||
double d = children[i]->distToNearest(aPos);
|
aQ.push(Ordered<Node*>(_children[i], d));
|
||||||
if (d > aCutoff) {
|
|
||||||
continue; // exceeded cutoff
|
|
||||||
}
|
|
||||||
|
|
||||||
aQ.push(Ordered<Node*>(children[i], d));
|
|
||||||
} // of child iteration
|
} // of child iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,16 +204,16 @@ void Branch::visitForLines(const SGVec3d& aPos, double aCutoff,
|
||||||
Node::visitForLines(aPos, aCutoff, aLines, aQ);
|
Node::visitForLines(aPos, aCutoff, aLines, aQ);
|
||||||
|
|
||||||
for (unsigned int i=0; i<8; ++i) {
|
for (unsigned int i=0; i<8; ++i) {
|
||||||
if (!children[i]) {
|
if (!_children[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double d = children[i]->distToNearest(aPos);
|
double d = _children[i]->distToNearest(aPos);
|
||||||
if (d > aCutoff) {
|
if (d > aCutoff) {
|
||||||
continue; // exceeded cutoff
|
continue; // exceeded cutoff
|
||||||
}
|
}
|
||||||
|
|
||||||
aQ.push_back(children[i]);
|
aQ.push_back(_children[i]);
|
||||||
} // of child iteration
|
} // of child iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,46 +270,42 @@ Node* Branch::childForPos(const SGVec3d& aCart) const
|
||||||
|
|
||||||
Node* Branch::childAtIndex(int childIndex) const
|
Node* Branch::childAtIndex(int childIndex) const
|
||||||
{
|
{
|
||||||
Node* child = children[childIndex];
|
Node* child = _children[childIndex];
|
||||||
if (!child) { // lazy building of children
|
if (!child) { // lazy building of children
|
||||||
SGBoxd cb(boxForChild(childIndex));
|
SGBoxd cb(boxForChild(childIndex));
|
||||||
double d2 = dot(cb.getSize(), cb.getSize());
|
double d2 = dot(cb.getSize(), cb.getSize());
|
||||||
|
|
||||||
assert(((_ident << 3) >> 3) == _ident);
|
assert(((_ident << 3) >> 3) == _ident);
|
||||||
|
|
||||||
// child index is 0..7, so 3-bits is sufficient, and hence we can
|
// child index is 0..7, so 3-bits is sufficient, and hence we can
|
||||||
// pack 20 levels of octree into a int64, which is plenty
|
// pack 20 levels of octree into a int64, which is plenty
|
||||||
int64_t childIdent = (_ident << 3) | childIndex;
|
int64_t childIdent = (_ident << 3) | childIndex;
|
||||||
|
|
||||||
if (d2 < LEAF_SIZE_SQR) {
|
if (d2 < LEAF_SIZE_SQR) {
|
||||||
// REVIEW: Memory Leak - 480 bytes in 3 blocks are still reachable
|
// REVIEW: Memory Leak - 480 bytes in 3 blocks are still reachable
|
||||||
child = new Leaf(cb, childIdent, _persistent);
|
child = new Leaf(cb, childIdent, _persistent);
|
||||||
} else {
|
} else {
|
||||||
// REVIEW: Memory Leak - 9,152 bytes in 52 blocks are still reachable
|
// REVIEW: Memory Leak - 9,152 bytes in 52 blocks are still reachable
|
||||||
child = new Branch(cb, childIdent, _persistent);
|
child = new Branch(cb, childIdent, _persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
children[childIndex] = child;
|
_children[childIndex] = child;
|
||||||
|
|
||||||
if (_persistent && childrenLoaded) {
|
if (_persistent && _childrenLoaded) {
|
||||||
// childrenLoad is done, so we're defining a new node - add it to the
|
// childrenLoad is done, so we're defining a new node - add it to the
|
||||||
// cache too.
|
// cache too.
|
||||||
NavDataCache::instance()->defineOctreeNode(const_cast<Branch*>(this), child);
|
NavDataCache::instance()->defineOctreeNode(const_cast<Branch*>(this), child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return children[childIndex];
|
return _children[childIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Branch::loadChildren() const
|
void Branch::loadChildren() const
|
||||||
{
|
{
|
||||||
if (childrenLoaded) {
|
if (_childrenLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_persistent) {
|
|
||||||
childrenLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int childrenMask = NavDataCache::instance()->getOctreeBranchChildren(guid());
|
int childrenMask = NavDataCache::instance()->getOctreeBranchChildren(guid());
|
||||||
for (int i=0; i<8; ++i) {
|
for (int i=0; i<8; ++i) {
|
||||||
|
@ -316,16 +316,16 @@ void Branch::loadChildren() const
|
||||||
|
|
||||||
// set this after creating the child nodes, so the cache update logic
|
// set this after creating the child nodes, so the cache update logic
|
||||||
// in childAtIndex knows any future created children need to be added.
|
// in childAtIndex knows any future created children need to be added.
|
||||||
childrenLoaded = true;
|
_childrenLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Branch::childMask() const
|
int Branch::childMask() const
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i=0; i<8; ++i) {
|
for (int i=0; i<8; ++i) {
|
||||||
if (children[i]) {
|
if (_children[i]) {
|
||||||
result |= 1 << i;
|
result |= 1 << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -25,12 +25,13 @@
|
||||||
#define FG_POSITIONED_OCTREE_HXX
|
#define FG_POSITIONED_OCTREE_HXX
|
||||||
|
|
||||||
// std
|
// std
|
||||||
#include <vector>
|
#include <array>
|
||||||
#include <set>
|
|
||||||
#include <queue>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// SimGear
|
// SimGear
|
||||||
#include <simgear/math/SGGeometry.hxx>
|
#include <simgear/math/SGGeometry.hxx>
|
||||||
|
@ -194,12 +195,12 @@ namespace Octree
|
||||||
void insertChild(FGPositioned::Type ty, PositionedID id);
|
void insertChild(FGPositioned::Type ty, PositionedID id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool childrenLoaded;
|
bool _childrenLoaded = false;
|
||||||
|
|
||||||
typedef std::multimap<FGPositioned::Type, PositionedID> ChildMap;
|
typedef std::multimap<FGPositioned::Type, PositionedID> ChildMap;
|
||||||
ChildMap children;
|
ChildMap children;
|
||||||
|
|
||||||
void loadChildren();
|
void loadChildren();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Branch : public Node
|
class Branch : public Node
|
||||||
|
@ -241,8 +242,8 @@ namespace Octree
|
||||||
|
|
||||||
void loadChildren() const;
|
void loadChildren() const;
|
||||||
|
|
||||||
mutable Node* children[8];
|
mutable std::array<Node*, 8> _children;
|
||||||
mutable bool childrenLoaded;
|
mutable bool _childrenLoaded = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter* aFilter, FGPositionedList& aResults, int aCutoffMsec);
|
bool findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter* aFilter, FGPositionedList& aResults, int aCutoffMsec);
|
||||||
|
|
Loading…
Add table
Reference in a new issue