#include "RenderSimulator.h" #include "KdTree.h" #include "ViewCellBsp.h" #include "ViewCell.h" void SimulationStatistics::Print(ostream &app) const { app << "===== Simulation statistics ===============\n"; app << setprecision(4); app << "#N_CTIME ( Simulation time [s] )\n" << Time() << " \n"; app << "#MAX_COST ( maximal cost of a view cell )\n" << maxCost << "\n"; app << "#MIN_COST ( minimal cost of a view cell )\n" << minCost << "\n"; app << "#AVG_RENDER_TIME ( average render time )\n" << avgRenderTime << "\n"; app << "#AVG_RENDER_TIME_NO_OVERHEAD ( average render time without overhead )\n" << avgRtWithoutOverhead << "\n"; app << "===== END OF Simulation statistics ==========\n"; } RenderSimulator::RenderSimulator() {} RenderSimulator::RenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed): mObjRenderCost(objRenderCost), mVcOverhead(vcOverhead), mMoveSpeed(moveSpeed) { } /***************************************************** * class ViewCellRenderSimulator implementation * *****************************************************/ BspViewCellRenderSimulator::BspViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, BspTree *bspTree): RenderSimulator(objRenderCost, vcOverhead, moveSpeed), mBspTree(bspTree) { } Real BspViewCellRenderSimulator::SimulateRendering() { mStat.Reset(); mStat.Start(); Real renderTime = 0; // overhead for loading the PVS of the view cells float loadPvsOverhead = 0; // probability that view point lies in a view cell float pInVcTotal = 0; // total probability that a view cell border is crossed const float pCrossVcTotal = mBspTree->GetBoundingBox().SurfaceArea(); // collect all view cells ViewCellContainer viewCells; mBspTree->CollectViewCells(viewCells); ViewCellContainer::const_iterator it, it_end = viewCells.end(); // surface area substitute for probability PolygonContainer geom; for (it = viewCells.begin(); it != it_end; ++ it) { // compute view cell area mBspTree->ConstructGeometry(dynamic_cast(*it), geom); const float area = Polygon3::GetArea(geom); CLEAR_CONTAINER(geom); // area substitute for view point probability float pInVc = area; // compute render time of PVS times probability that view point is in view cell float vcCost = pInVc * RenderPvs(*(*it), mObjRenderCost); //Debug << "p: " << pInVc << " rendercost: " << RenderPvs(*(*it), mObjRenderCost) << endl; renderTime += vcCost; if (vcCost > mStat.maxCost) mStat.maxCost = vcCost; else if (vcCost < mStat.minCost) mStat.minCost = vcCost; // probability that a view cell border is crossed float pCrossVc = area * mMoveSpeed; // crossing the border of a view cell is also depending on the move speed loadPvsOverhead += pCrossVc * mVcOverhead; pInVcTotal += pInVc; } renderTime /= pInVcTotal; loadPvsOverhead /= pCrossVcTotal; mStat.avgRtWithoutOverhead = renderTime; mStat.avgRenderTime = renderTime + loadPvsOverhead; mStat.Stop(); return renderTime + loadPvsOverhead; } Real BspViewCellRenderSimulator::RenderPvs(ViewCell &viewCell, float objRenderTime) const { return viewCell.GetPvs().GetSize() * objRenderTime; } /******************************************************** * class KdLeafRenderSimulator implementation * *******************************************************/ KdViewCellRenderSimulator::KdViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, KdTree *kdTree): RenderSimulator(objRenderCost, vcOverhead, moveSpeed), mKdTree(kdTree) { } Real KdViewCellRenderSimulator::SimulateRendering() { //mKdTree->CollectLeavesPvs(); mStat.Reset(); mStat.Start(); // total render time Real renderTime = 0; // overhead for loading a view cell float loadPvsOverhead = 0; // probability that view point lies in a view cell float pInVcTotal = 0;//mKdTree->GetBox().GetVolume(); // total probability that a view cell border is crossed const float pCrossVcTotal = mKdTree->GetBox().SurfaceArea(); vector leaves; mKdTree->CollectLeaves(leaves); AxisAlignedBox3 box; vector::const_iterator it, it_end = leaves.end(); for (it = leaves.begin(); it != it_end; ++ it) { box = mKdTree->GetBox(*it); // volume substitute for view point probability float pInVc = 0; if (0) pInVc = box.GetVolume(); else pInVc = box.SurfaceArea(); float vcCost = pInVc * RenderPvs(*it, mObjRenderCost); renderTime += vcCost; if (vcCost > mStat.maxCost) mStat.maxCost = vcCost; else if (vcCost < mStat.minCost) mStat.minCost = vcCost; // probability that a view cell border is crossed const float pCrossVc = box.SurfaceArea() * mMoveSpeed; loadPvsOverhead += pCrossVc * mVcOverhead; pInVcTotal += pInVc; } renderTime /= pInVcTotal; loadPvsOverhead /= pCrossVcTotal; mStat.avgRtWithoutOverhead = renderTime; mStat.avgRenderTime = renderTime + loadPvsOverhead; mStat.maxCost /= pCrossVcTotal; mStat.minCost /= pCrossVcTotal; mStat.Stop(); return renderTime + loadPvsOverhead; } Real KdViewCellRenderSimulator::RenderPvs(KdLeaf *leaf, float objRenderTime) const { return leaf->mKdPvs.GetSize() * objRenderTime; }