#include "..\include\OgreSharedRuns.h" #include "OgreIlluminationManager.h" void OgreSharedRuns::runChanged(RenderingRunType runType, RenderingRun* run) { if(child1 != 0) child1->runChanged(runType, run); if(child2 != 0) child2->runChanged(runType, run); std::vector::iterator it = childTechniqueGroups.begin(); std::vector::iterator itend = childTechniqueGroups.end(); while(it != itend) { (*it)->runChanged(runType, run); it++; } } void OgreSharedRuns::runUpdated(RenderingRunType runType, RenderingRun* run) { if(child1 != 0) child1->runUpdated(runType, run); if(child2 != 0) child2->runUpdated(runType, run); std::vector::iterator it = childTechniqueGroups.begin(); std::vector::iterator itend = childTechniqueGroups.end(); while(it != itend) { (*it)->runUpdated(runType, run); it++; } } RenderingRun* OgreSharedRuns::getRun(RenderingRunType runType) { /* if(parent != 0) return parent->getRun(runType);*/ if( hasOwnRun(runType) ) return sharedRuns[runType]; if(child1 != 0) { RenderingRun* run = child1->getRun(runType); if( run != 0) return run; } if(child2 != 0) return child2->getRun(runType); return 0; } void OgreSharedRuns::addRun(RenderingRunType runType, RenderingRun* run) { sharedRuns[runType] = run; } void OgreSharedRuns::updateRun(RenderingRunType runType, unsigned long frameNum) { /* if(parent != 0) parent->updateRun(runType, frameNum); else sharedRuns[runType]->update(frameNum); */ RenderingRun* run = getRun(runType); if(run->update(frameNum)) runUpdated(runType, run); } bool OgreSharedRuns::hasOwnRun(RenderingRunType runType) { if(sharedRuns.find(runType) == sharedRuns.end()) return false; return true; } void OgreSharedRuns::gatherRuns() { OgreSharedRuns* child1 = (OgreSharedRuns*) this->child1; OgreSharedRuns* child2 = (OgreSharedRuns*) this->child2; std::map::iterator it = child1->sharedRuns.begin(); std::map::iterator itend = child1->sharedRuns.end(); while(it != itend) { if( child2->hasOwnRun((*it).first) ) sharedRuns[(*it).first] = (*it).second; it++; } } void OgreSharedRuns::updateBounds() { if(child1) { OgreSharedRuns* child1 = (OgreSharedRuns*) this->child1; OgreSharedRuns* child2 = (OgreSharedRuns*) this->child2; boundingBox = child1->boundingBox; boundingBox.merge(child2->boundingBox); boundingSphere.setCenter((child1->boundingSphere.getCenter() + child2->boundingSphere.getCenter())/2.0); float dist = (child1->boundingSphere.getCenter() - child2->boundingSphere.getCenter()).length(); float radius1 = child1->boundingSphere.getRadius(); float radius2 = child2->boundingSphere.getRadius(); float maxrad = std::max(radius1, radius2); if(radius1 + dist <= radius2)boundingSphere.setRadius(radius2); else if(radius2 + dist <= radius1)boundingSphere.setRadius(radius1); else boundingSphere.setRadius(dist + maxrad); } else { std::map::iterator it = renderables.begin(); OgreRenderable* rend = (*it).first; rend->updateBounds(); boundingBox = rend->getBoundingBox(); boundingSphere = rend->getBoundingSphere(); } } void OgreSharedRuns::fireRunChanges() { std::map::iterator it = sharedRuns.begin(); std::map::iterator itend = sharedRuns.end(); while(it != itend) { runChanged( (*it).first, (*it).second ); it++; } } SharedRuns* OgreSharedRuns::createInstance() { return new OgreSharedRuns(); } void OgreSharedRuns::validate() { updateBounds(); if(child1 == 0) { if(parent != 0) parent->validate(); return; } if( canJoin(child1, child2)) { if(parent != 0) parent->validate(); } else //destroy this shared object with parents destroy(); } bool OgreSharedRuns::haveCommonRuns(SharedRuns* r1, SharedRuns* r2, std::vector& commonruns) { OgreSharedRuns* run1 = (OgreSharedRuns*) r1; OgreSharedRuns* run2 = (OgreSharedRuns*) r2; std::map::iterator it = run1->sharedRuns.begin(); std::map::iterator itend = run1->sharedRuns.end(); bool returnvalue = false; while(it != itend) { if( run2->hasOwnRun((*it).first)) { if( run1->getRun((*it).first)->asOgreRenderingRun()-> canJoin( run2->getRun((*it).first)->asOgreRenderingRun() ) ) { returnvalue = true; commonruns.push_back((*it).first); } } it++; } return returnvalue; } bool OgreSharedRuns::canJoin(SharedRuns* r1, SharedRuns* r2) { std::vector commonruns; //check if they have common resources if(!haveCommonRuns(r1, r2, commonruns)) return false; float MAXRAD = 0xffffffff; //check bounds for(int i = 0; i < commonruns.size(); i++) { RenderingRunType type = commonruns.at(i); float marad = OgreIlluminationManager::getSingleton().getMaxJoinRadius(type); MAXRAD = std::min(MAXRAD, marad); } Sphere bSphere1 = ((OgreSharedRuns*) r1)->getBoundingSphere(); Sphere bSphere2 = ((OgreSharedRuns*) r2)->getBoundingSphere(); float radius1 = bSphere1.getRadius(); float radius2 = bSphere2.getRadius(); float dist = (bSphere1.getCenter() - bSphere2.getCenter()).length(); float maxrad = std::max(radius1,radius2); if(dist + radius1 <= radius2 && radius2 < MAXRAD) return true; else if(dist + radius2 <= radius1 && radius1 < MAXRAD) return true; else if( maxrad + dist < MAXRAD) return true; return false; } void OgreSharedRuns::destroy() { if(parent != 0) parent->destroy(); OgreIlluminationManager::getSingleton().sharedRunSplit(this, child1, child2); ((OgreSharedRuns*)child1)->fireRunChanges(); ((OgreSharedRuns*)child2)->fireRunChanges(); child1->unbindParent(); child2->unbindAndKillParent(); } void OgreSharedRuns::addRenderablesToQueue(RenderQueue* rq) { if(child1 != 0) //node { ((OgreSharedRuns*)child1)->addRenderablesToQueue(rq); ((OgreSharedRuns*)child2)->addRenderablesToQueue(rq); } else //leaf { std::map::iterator it = renderables.begin(); std::map::iterator itend = renderables.end(); while(it != itend) { if((*it).first->isVisible()) rq->addRenderable(((*it).first)->getRenderable()); it++; } } } void OgreSharedRuns::notifyCamera(Camera* cam) { if(child1 != 0) //node { ((OgreSharedRuns*)child1)->notifyCamera(cam); ((OgreSharedRuns*)child2)->notifyCamera(cam); } else { std::map::iterator it = renderables.begin(); std::map::iterator itend = renderables.end(); while(it != itend) { OgreRenderable* rend = (*it).first; if((*it).first->isVisible()) rend->notifyCamera(cam); it++; } } } void OgreSharedRuns::findSharedRootsForType(RenderingRunType runType, std::vector& roots) { if(hasOwnRun(runType)) { roots.push_back(this); } if(child1 != 0) ((OgreSharedRuns*)child1)->findSharedRootsForType(runType, roots); if(child2 != 0) ((OgreSharedRuns*)child2)->findSharedRootsForType(runType, roots); }