#include #include #include "Pvs.h" #include "Intersectable.h" #include "IntersectableWrapper.h" #include "KdTree.h" #include "common.h" #include "BvHierarchy.h" namespace GtpVisibilityPreprocessor { int MailablePvsData::sMailId = 1; int MailablePvsData::sReservedMailboxes = 1; int KdPvs::Compress() { return 0; // TODO } /** the pvs is the number of different objects in the node leaves We eliminate already accounted kd nodes and objects using mailboxing. */ static int CountNewObjectsInKdNode(KdIntersectable *kdobj) { int pvs = 0; stack tStack; tStack.push(kdobj->GetItem()); while (!tStack.empty()) { KdNode *node = tStack.top(); tStack.pop(); // already processed node (=> objects already in pvs)? if (!node->Mailed()) { node->Mail(); if (node->IsLeaf()) { KdLeaf *leaf = dynamic_cast(node); // add #objects exclusivly in this node pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); // Objects already accounted for can only be found among those // which are referenced in more than one leaf ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) { Intersectable *object = *oit; if (!object->Mailed()) { object->Mail(); ++ pvs; } } } else // traverse tree { KdInterior *interior = dynamic_cast(node); tStack.push(interior->mFront); tStack.push(interior->mBack); } } } return pvs; } /** the pvs is the number of different objects in the node leaves We eliminate already accounted kd nodes and objects using mailboxing. */ static int CountNewObjectsInBvhNode(BvhIntersectable *bvhobj) { BvhNode *node= bvhobj->GetItem(); // early exit if (node->IsLeaf()) { // objects already accounted for if (node->Mailed()) return 0; node->Mail(); BvhLeaf *leaf = dynamic_cast(node); return (int)leaf->mObjects.size(); } // compute leaf pvs int pvs = 0; stack tStack; tStack.push(bvhobj->GetItem()); while (!tStack.empty()) { BvhNode *node = tStack.top(); tStack.pop(); // already processed node (=> objects already in pvs)? if (!node->Mailed()) { node->Mail(); if (node->IsLeaf()) { BvhLeaf *leaf = dynamic_cast(node); // add #objects exclusivly in this node pvs += (int)leaf->mObjects.size(); } else // traverse tree { BvhInterior *interior = dynamic_cast(node); tStack.push(interior->GetFront()); tStack.push(interior->GetBack()); } } } return pvs; } int ObjectPvs::CountObjectsInPvs() const { int pvs = 0; Intersectable::NewMail(); KdLeaf::NewMail(); BvhLeaf::NewMail(); ObjectPvsMap::const_iterator it, it_end = mEntries.end(); for (it = mEntries.begin(); it != it_end; ++ it) { Intersectable *obj = (*it).first; switch (obj->Type()) { case Intersectable::KD_INTERSECTABLE: { // found kd node KdIntersectable *kdObj = dynamic_cast(obj); pvs += CountNewObjectsInKdNode(kdObj); break; } case Intersectable::BVH_INTERSECTABLE: { BvhIntersectable *bvhObj = dynamic_cast(obj); pvs += CountNewObjectsInBvhNode(bvhObj); break; } default: ++ pvs; break; } } return pvs; } }