To trace the spatial position of Creatures I use
https://en.wikipedia.org/wiki/Quadtree- {l Code}: {l Select All Code}
int CullingManager::cullCreatures()
{
//cerr << "countnodes " << myCullingQuad.countNodes() <<endl;
mMyCullingQuad.holdRootSemaphore();
MortuaryQuad tmpQuad(mMyCullingQuad);
mMyCullingQuad.releaseRootSemaphore();
tmpQuad.cut(Segment(mOgreVectorsArray[1], mOgreVectorsArray[0]));
tmpQuad.cut(Segment(mOgreVectorsArray[0], mOgreVectorsArray[3]));
tmpQuad.cut(Segment(mOgreVectorsArray[3], mOgreVectorsArray[2]));
tmpQuad.cut(Segment(mOgreVectorsArray[2], mOgreVectorsArray[1]));
//cerr << "tmpQuad.countNodes() " << tmpQuad.countNodes() <<endl;
std::swap(mCurrentVisibleCreatures, mPreviousVisibleCreatures);
mCurrentVisibleCreatures = tmpQuad.returnCreaturesSet(mCurrentVisibleCreatures);
//cerr << "currentVisibleCreatures " << currentVisibleCreatures->size() <<endl;
std::set<Creature*> intersection;
std::set<Creature*> ascendingCreatures;
std::set<Creature*> descendingCreatures;
std::set_intersection(mPreviousVisibleCreatures->begin(), mPreviousVisibleCreatures->end(),
mCurrentVisibleCreatures->begin(), mCurrentVisibleCreatures->end(),
std::inserter(intersection, intersection.end()));
std::set_difference(mCurrentVisibleCreatures->begin(), mCurrentVisibleCreatures->end(),
intersection.begin(), intersection.end(),
std::inserter(ascendingCreatures, ascendingCreatures.end()));
std::set_difference(mPreviousVisibleCreatures->begin(), mPreviousVisibleCreatures->end(),
intersection.begin(), intersection.end(),
std::inserter(descendingCreatures, descendingCreatures.end()));
for(std::vector<Creature*>::iterator it = tmpQuad.mMortuaryQuad.begin(); it != tmpQuad.mMortuaryQuad.end(); ++it)
descendingCreatures.erase(*it);
for(std::set<Creature*>::iterator it = ascendingCreatures.begin(); it != ascendingCreatures.end(); ++it)
(*it)->show();
for(std::set<Creature*>::iterator it = descendingCreatures.begin(); it != descendingCreatures.end(); ++it)
(*it)->hide();
return 1;
}
On start of every frame I do int CullingManager::cullCreatures.
1. I make a copy of MortuaryQuad
- {l Code}: {l Select All Code}
MortuaryQuad tmpQuad(mMyCullingQuad)
;
2. I have already prepared the cast of camera frustrum onto XY plane, having for points ( they mark what is visible from camera on that plane ) .
3. Now I cut away everything what's on the left side of each line ( or Segment) constructed from the already mentioned points
- {l Code}: {l Select All Code}
tmpQuad.cut(Segment(mOgreVectorsArray[1], mOgreVectorsArray[0]));
tmpQuad.cut(Segment(mOgreVectorsArray[0], mOgreVectorsArray[3]));
tmpQuad.cut(Segment(mOgreVectorsArray[3], mOgreVectorsArray[2]));
tmpQuad.cut(Segment(mOgreVectorsArray[2], mOgreVectorsArray[1]));
[/code]
4. We prepare the previous visible creatures
- {l Code}: {l Select All Code}
std::swap(mCurrentVisibleCreatures, mPreviousVisibleCreatures);
.
5. That way in tmpQuad are Creatures visible in current frame . I extract them to std::set with :
- {l Code}: {l Select All Code}
mCurrentVisibleCreatures = tmpQuad.returnCreaturesSet(mCurrentVisibleCreatures);
5. Ascending creatures are the creatures which are new in our Quadtree. In other words those are creatures :
in mCurrentVisibleCreatures and not in mPreviousVisibleCreatures.
That is : AscendingCreatures = mCurrentVisibleCreatures \ ( mCurrentVisibleCreatures ^ mPreviousVisibleCreatures. ) ^ --means inttersection
and the same for DescendingCreatures ( the ones which ought to be hidden )
AscendingCreatures = mPreviousVisibleCreatures. \ ( mCurrentVisibleCreatures ^ mPreviousVisibleCreatures. ) ^ --means inttersection
6. We compute intersection :
- {l Code}: {l Select All Code}
std::set_intersection(mPreviousVisibleCreatures->begin(), mPreviousVisibleCreatures->end(),
mCurrentVisibleCreatures->begin(), mCurrentVisibleCreatures->end(),
std::inserter(intersection, intersection.end()));
and set diffrences :
- {l Code}: {l Select All Code}
std::set_difference(mCurrentVisibleCreatures->begin(), mCurrentVisibleCreatures->end(),
intersection.begin(), intersection.end(),
std::inserter(ascendingCreatures, ascendingCreatures.end()));
std::set_difference(mPreviousVisibleCreatures->begin(), mPreviousVisibleCreatures->end(),
intersection.begin(), intersection.end(),
std::inserter(descendingCreatures, descendingCreatures.end()));
We also register creatures which are dead , and which disapperence have nothing to do with culling, instead there are other mechanisms whcih care to remove them from the scneene ( rrDestroyCreature I suppose ) . Therefor we run the hook :
- {l Code}: {l Select All Code}
for(std::vector<Creature*>::iterator it = tmpQuad.mMortuaryQuad.begin(); it != tmpQuad.mMortuaryQuad.end(); ++it)
descendingCreatures.erase(*it);
Finnally we can iterate over the resulting sets , and hide and show proper Creatures :
- {l Code}: {l Select All Code}
for(std::set<Creature*>::iterator it = ascendingCreatures.begin(); it != ascendingCreatures.end(); ++it)
(*it)->show();
for(std::set<Creature*>::iterator it = descendingCreatures.begin(); it != descendingCreatures.end(); ++it)
(*it)->hide();
As you see this algorithm does not account about creatures which get picked / dropped bby the Player. If anyone could have an idea, how do I extract what creatures are in Hand_node ...