void preprocess(const Scene *scene) { /* Create a sample generator for the preprocess step */ Sampler *sampler = static_cast<Sampler *>( NoriObjectFactory::createInstance("independent", PropertyList())); Emitter* distantsDisk = scene->getDistantEmitter(); if(distantsDisk != nullptr ) { float lngstDir = scene->getBoundingBox().getLongestDirection(); distantsDisk->setMaxRadius(lngstDir); } /* Allocate memory for the photon map */ m_photonMap = std::unique_ptr<PhotonMap>(new PhotonMap()); m_photonMap->reserve(m_photonCount); /* Estimate a default photon radius */ if (m_photonRadius == 0) m_photonRadius = scene->getBoundingBox().getExtents().norm() / 500.0f; int storedPhotons = 0; const std::vector<Emitter *> lights = scene->getEmitters(); int nLights = lights.size(); Color3f tp(1.0f, 1.0f, 1.0f); cout << "Starting to create "<< m_photonCount << " photons!" << endl; int percentDone= 0; int onePercent = int(floor(m_photonCount / 100.0)); // create the expected number of photons while(storedPhotons < m_photonCount) { //uniformly sample 1 light (assuming that we only have area lights) int var = int(std::min(sampler->next1D()*nLights, float(nLights) - 1.0f)); const areaLight* curLight = static_cast<const areaLight *> (lights[var]); //sample a photon Photon curPhoton; Vector3f unQuantDir(0.0f,0.0f,0.0f); curLight->samplePhoton(sampler, curPhoton, 1, nLights, unQuantDir); Color3f alpha = curPhoton.getPower(); Color3f tp(1.0f, 1.0f, 1.0f); //trace the photon Intersection its; Ray3f photonRay(curPhoton.getPosition(), unQuantDir); m_shootedRays++; if (scene->rayIntersect(photonRay, its)) { while(true) { const BSDF* curBSDF = its.mesh->getBSDF(); if (curBSDF->isDiffuse()) { //store the photon m_photonMap->push_back(Photon( its.p /* Position */, -photonRay.d /* Direction*/, tp * alpha /* Power */ )); storedPhotons++; } if(!(storedPhotons < m_photonCount)) break; BSDFQueryRecord query = BSDFQueryRecord(its.toLocal(-photonRay.d), Vector3f(0.0f), EMeasure::ESolidAngle); Color3f fi = curBSDF->sample(query, sampler->next2D()); if(fi.maxCoeff() == 0.0f) break; tp *= fi; Vector3f wo = its.toWorld(query.wo); photonRay = Ray3f(its.p, wo); //ray escapes the scene if (!scene->rayIntersect(photonRay, its)) break; //stop critirium russian roulette float q = tp.maxCoeff(); if(q < sampler->next1D()) break; tp /= q; } } if(onePercent != 0) { if(storedPhotons % onePercent == 0){ int percent = int(floor(storedPhotons / onePercent)); if(percent % 10 == 0 && percentDone != percent){ percentDone = percent; cout << percent << "%" << endl; } } } } /* Build the photon map */ m_photonMap->build(); }
// ====================================================================== // During ray tracing, when a diffuse (or partially diffuse) object is // hit, gather the nearby photons to approximate indirect illumination bool comparePhotons(const Photon& p1,const Photon& p2) { double dis1 = (p1.getPosition()-p1.getPoint()).Length(); double dis2 = (p2.getPosition()-p2.getPoint()).Length(); return dis1<dis2; }
void GameScreen::calculatePath() { /* std::map<int, std::shared_ptr<Equipment>>::iterator it_on_grid = tool_manager.equipments_on_grid_.begin(); for(; it_on_grid!=tool_manager.equipments_on_grid_.end(); it_on_grid ++) { (*it_on_grid).second->lightOff(); } */ for(int i = 0; i != GameScreen::tool_manager.my_targets_.size(); i++) { GameScreen::tool_manager.my_targets_[i]->lightOff(); } GameScreen::tool_manager.my_targets_[0]->lightOff(); sf::FloatRect windowRect(MARGIN, MARGIN, GRID_WIDTH*(BLOCK_SIZE), GRID_HEIGHT*(BLOCK_SIZE)); if(lightPaths.size() == 0) { for(int i = 0; i != tool_manager.my_lasers_.size(); i++) { std::vector<Photon> lightPath; lightPath.push_back(tool_manager.my_lasers_[i].getPhoton()); lightPaths.push_back(lightPath); } } for(int i = 0; i != lightPaths.size(); i++) { Photon current = lightPaths[i].back(); while(current.getVelocity() != 0.0 && windowRect.contains(current.getPosition())) { Photon nextPhoton = current; int idx = nextPhoton.getIndex(); if(tool_manager.equipments_on_grid_.count(idx) > 0) { tool_manager.equipments_on_grid_[idx]->reaction(nextPhoton, lightPaths); lightPaths[i].push_back(nextPhoton); } else { nextPhoton.myMove(); lightPaths[i].push_back(nextPhoton); } current = nextPhoton; } } bool isAllHit = true; /* it_on_grid = tool_manager.equipments_on_grid_.begin(); for(; it_on_grid!=tool_manager.equipments_on_grid_.end(); it_on_grid ++) { if(!(*it_on_grid).second->isHit()) { isAllHit = false; break; } } */ for(int i = 0; i != GameScreen::tool_manager.my_targets_.size(); i++) { if(!GameScreen::tool_manager.my_targets_[0]->isHit()) { isAllHit = false; break; } } if(isAllHit) { std::cout<<"all hit"<<std::endl; } }