GLvoid insertPolice(){ // FOR PER TUTTE LE NAVETTE DELLA POLIZIA numPoliceDraw=0; // se il numero di polizia รจ minore di 2 se ne disegna un'altra fuori dalla sfera dello sfondo // questo per evitare che i movimenti (laser, satelliti) siano troppo veloci me=g_camera.getPos(); for(int i=0;i<NUM_POLICE;i++){ dist=distance(police[i].pos,me); if(dist<=DIST_RADAR && police[i].life>0){ //if(police[i].life>0){ if ( (isIllegal() || police[i].life<100) ) { // la polizia si muove solo se abbiamo commerciato illegalmente o gli stiamo sparando setPosDir(&police[i]); } drawPolice(policeModel,police[i].pos,police[i].dir); numPoliceDraw++; //drawShield(police[i].pos,radShootPolice); if( (isIllegal() || police[i].life<100) && police[i].dirCorr){ if(abs(clock()-policeClock)>=CLOCKS_PER_SEC*1) { newPoliceLaser(i); policeClock=clock(); glutPostRedisplay(); } //newEnemyLaser(i); } } } while (numPoliceDraw<2){ // disegno tante navette fuori dalla sfera dello sfondo extraPos=pointDir(me, g_camera.getUp(), 1200); drawPolice(policeModel,extraPos,g_camera.getUp()); numPoliceDraw++; } }
void run(PassRunner* runner, Module* module) override { // for each illegal export, we must export a legalized stub instead for (auto& ex : module->exports) { if (ex->kind == ExternalKind::Function) { // if it's an import, ignore it if (auto* func = module->checkFunction(ex->value)) { if (isIllegal(func)) { auto legalName = makeLegalStub(func, module); ex->value = legalName; } } } } // for each illegal import, we must call a legalized stub instead std::vector<Import*> newImports; // add them at the end, to not invalidate the iter for (auto& im : module->imports) { if (im->kind == ExternalKind::Function && isIllegal(im->functionType)) { Name funcName; auto* legal = makeLegalStub(im.get(), module, funcName); illegalToLegal[im->name] = funcName; newImports.push_back(legal); } } if (illegalToLegal.size() > 0) { for (auto* im : newImports) { module->addImport(im); } // fix up imports: call_import of an illegal must be turned to a call of a legal struct FixImports : public WalkerPass<PostWalker<FixImports, Visitor<FixImports>>> { bool isFunctionParallel() override { return true; } Pass* create() override { return new FixImports(illegalToLegal); } std::map<Name, Name>* illegalToLegal; FixImports(std::map<Name, Name>* illegalToLegal) : illegalToLegal(illegalToLegal) {} void visitCallImport(CallImport* curr) { auto iter = illegalToLegal->find(curr->target); if (iter == illegalToLegal->end()) return; if (iter->second == getFunction()->name) return; // inside the stub function itself, is the one safe place to do the call replaceCurrent(Builder(*getModule()).makeCall(iter->second, curr->operands, curr->type)); } }; PassRunner passRunner(module); passRunner.add<FixImports>(&illegalToLegal); passRunner.run(); } }
vector<vec3f> IptTracer::renderPixels(const Camera& camera) { if (!usePPM) { lightPathNum = totPathNum * pathRatio; interPathNum = totPathNum * (1.f - pathRatio); partialPathNum = interPathNum; mergeIterations = maxDepth; useWeight = true; } else { lightPathNum = totPathNum; interPathNum = totPathNum; partialPathNum = interPathNum; mergeIterations = 0; useWeight = false; } cameraPathNum = pixelNum; useUniformInterSampler = (useUniformSur && useUniformVol); vector<vec3f> pixelColors(camera.width * camera.height, vec3f(0, 0, 0)); vector<omp_lock_t> pixelLocks(pixelColors.size()); volMask.resize(camera.width * camera.height); preprocessEmissionSampler(); preprocessOtherSampler(useUniformSur); preprocessVolumeSampler(useUniformVol , mergeRadius * 0.1f); for(int i=0; i<pixelLocks.size(); i++) { omp_init_lock(&pixelLocks[i]); } omp_lock_t cmdLock; omp_init_lock(&cmdLock); if (gatherRadius < 1e-6f) gatherRadius = mergeRadius; Real r0 = mergeRadius; Real gr0 = gatherRadius; totArea = renderer->scene.getTotalArea(); totVol = renderer->scene.getTotalVolume(); printf("scene: totArea = %.8f, totVol = %.8f\n" , totArea , totVol); // abandon surface //totArea = 0.f; if (totVol > 1e-6f && totArea > 1e-6f) partialPathNum = interPathNum / 2; unsigned startTime = clock(); for(unsigned s=0; s<=spp; s++) { partPathMergeIndex.resize(interPathNum); partialSubPathList.clear(); /* float shrinkRatio; if (totVol > 1e-6f) shrinkRatio = powf(((float)s + alpha) / ((float)s + 1.f) , 1.f / 3.f); else shrinkRatio = powf(((float)s + alpha) / ((float)s + 1.f) , 1.f / 2.f); if (s > 0) mergeRadius *= shrinkRatio; */ float base; if (useUniformInterSampler) base = (float)s + 1.f; else base = (float)s; if (totVol > 1e-6f) { mergeRadius = r0 * powf(powf(max(base , 1.f) , alpha - 1.f) , 1.f / 3.f); gatherRadius = gr0 * powf(powf(max(base , 1.f) , alpha - 1.f) , 1.f / 3.f); } else { mergeRadius = r0 * powf(powf(max(base , 1.f) , alpha - 1.f) , 1.f / 2.f); gatherRadius = gr0 * powf(powf(max(base , 1.f) , alpha - 1.f) , 1.f / 2.f); } mergeRadius = r0; mergeRadius = std::max(mergeRadius , 1e-7f); gatherRadius = std::max(gatherRadius , 1e-7f); printf("mergeRadius = %.8f, gatherRadius = %.8f\n" , mergeRadius , gatherRadius); vector<vec3f> singleImageColors(pixelColors.size(), vec3f(0, 0, 0)); string cmd; unsigned t = clock(); vector<Path*> lightPathList(lightPathNum , NULL); vector<Path*> interPathList(interPathNum, NULL); interMergeKernel = 1.f / (M_PI * mergeRadius * mergeRadius * (Real)partialPathNum); lightMergeKernel = 1.f / (M_PI * mergeRadius * mergeRadius * (Real)lightPathNum); interGatherKernel = 1.f / (M_PI * gatherRadius * gatherRadius * (Real)partialPathNum); lightGatherKernel = 1.f / (M_PI * gatherRadius * gatherRadius * (Real)lightPathNum); if (!renderer->scene.usingGPU()) { genLightPaths(cmdLock , lightPathList , (s == 0)); if (!useUniformInterSampler) { if (!useUniformSur) renderer->scene.beginUpdateOtherSampler(s); if (!useUniformVol) renderer->scene.beginUpdateVolumeSampler(s); for (int i = 0; i < partialSubPathList.size(); i++) { IptPathState& lightState = partialSubPathList[i]; if (lightState.ray->contactObject && !useUniformSur) { renderer->scene.updateOtherSampler(lightState.ray->contactObject->objectIndex , lightState.ray->contactObjectTriangleID , s , lightState.throughput / (Real)lightPathNum); } else if (lightState.ray->insideObject && lightState.ray->insideObject->isVolumetric() && !lightState.ray->contactObject && !useUniformVol) { vec3f thr = lightState.throughput; renderer->scene.updateVolumeSampler(lightState.ray->insideObject->objectIndex , lightState.ray->origin , s , thr / (Real)lightPathNum); } } if (!useUniformSur) renderer->scene.endUpdateOtherSampler(); if (!useUniformVol) renderer->scene.endUpdateVolumeSampler(); /* Scene::SurfaceSampler *interSampler = renderer->scene.otherSurfaceSampler; fprintf(fp , "totWeight = %.8f\n" , interSampler->totalWeight); for (int i = 0; i < interSampler->targetObjects.size(); i++) { SceneObject *obj = interSampler->targetObjects[i]; fprintf(fp , "======= objId = %d , totEnergy = %.8f , weight = %.8f =======\n" , obj->objectIndex , obj->totalEnergy , obj->weight); for (int j = 0; j < obj->getTriangleNum(); j++) { fprintf(fp , "triId = %d , e = %.8f\n" , j , obj->energyDensity[j]); } } Scene::VolumeSampler *interVolSampler = renderer->scene.volumeSampler; fprintf(fp , "totWeight = %.8f\n" , interVolSampler->totalWeight); for (int i = 0; i < interVolSampler->targetObjects.size(); i++) { SceneObject *obj = interVolSampler->targetObjects[i]; fprintf(fp , "======= objId = %d , totEnergy = %.8f , weight = %.8f =======\n" , obj->objectIndex , obj->countHashGrid->sumWeights , obj->volumeWeight); for (int j = 0; j < obj->countHashGrid->effectiveWeights.size(); j++) { fprintf(fp , "cellIndex = %d , e = %.8f\n" , obj->countHashGrid->effectiveIndex[j] , obj->countHashGrid->effectiveWeights[j]); } } */ if (s == 0) continue; } if (!usePPM) genIntermediatePaths(cmdLock , interPathList); printf("lightPhotonNum = %d, partialPhotonNum = %d\n" , lightPhotonNum , partialPhotonNum); mergePartialPaths(cmdLock); PointKDTree<IptPathState> partialSubPaths(partialSubPathList); for (int i = 0; i < partialPhotonNum; i++) { IptPathState& subPath = partialSubPathList[i]; if ((useUniformInterSampler && s == 0) || (!useUniformInterSampler && s == 1)) { vec3f contrib; if (i < lightPhotonNum) { //contrib = subPath.throughput; //fprintf(fp1 , "==============\n"); //fprintf(fp1 , "dirContrib=(%.8f,%.8f,%.8f), pathNum = %.1lf\n" , contrib.x , contrib.y , contrib.z , subPath.mergedPath); } else { contrib = subPath.indirContrib; if (intensity(contrib) < 1e-6f) continue; fprintf(fp , "==============\n"); fprintf(fp , "indirContrib=(%.8f,%.8f,%.8f), pathNum = %.1lf\n" , contrib.x , contrib.y , contrib.z , subPath.mergedPath); } } } #pragma omp parallel for for(int p=0; p<cameraPathNum; p++) { //fprintf(fp2 , "========== pixel id = %d ==========\n" , p); Path eyePath; sampleMergePath(eyePath , camera.generateRay(p) , 0); singleImageColors[p] += colorByRayMarching(eyePath , partialSubPaths , p); // abandon all the rest! /* samplePath(eyePath, camera.generateRay(p)); if (eyePath.size() <= 1) continue; IptPathState cameraState; bool lastSpecular = 1; Real lastPdfW = 1.f; cameraState.throughput = vec3f(1.f) / (eyePath[0].originProb * eyePath[0].directionProb * eyePath[1].originProb); cameraState.index = eyePath.front().pixelID; vector<float> weights; //fprintf(fp , "===================\n"); //for (int i = 0; i < eyePath.size(); i++) //{ // fprintf(fp , "l=%d, bsdf=(%.8f,%.8f,%.8f), originPdf=%.8f, dirPdf=%.8f\n" , i , eyePath[i].color.x , // eyePath[i].color.y , eyePath[i].color.z , eyePath[i].originProb , eyePath[i].directionProb); //} int nonSpecLength = 0; vector<vec3f> mergeContribs; mergeContribs.clear(); float weightFactor = 1.f; vec3f colorHitLight(0.f); int N = maxDepth; nonSpecLength = 0; for(unsigned i = 1; i < eyePath.size(); i++) //for (unsigned i = 1; i < 2; i++) { vec3f colorGlbIllu(0.f) , colorDirIllu(0.f); Real dist = std::max((eyePath[i].origin - eyePath[i - 1].origin).length() , 1e-5f); cameraState.throughput *= eyePath[i - 1].getRadianceDecay(dist); if (eyePath[i].contactObject && eyePath[i].contactObject->emissive()) { vec3f contrib = ((SceneEmissiveObject*)(eyePath[i].contactObject))->getColor(); float dirPdfA = eyePath[i].contactObject->getEmissionWeight() / eyePath[i].contactObject->totalArea; float mis = 1.f; if (i > 1 && !lastSpecular) { float cosine = eyePath[i].getContactNormal().dot(-eyePath[i - 1].direction); float dist = (eyePath[i].origin - eyePath[i - 1].origin).length(); float dirPdfW = dirPdfA * dist * dist / abs(cosine); mis = lastPdfW / (lastPdfW + dirPdfW); //fprintf(fp , "==================\n"); //fprintf(fp , "thr=(%.6f,%.6f,%.6f), contrib=(%.6f,%.6f,%.6f), pdfA=%.6f, pdfW=%.6f, lastPdfW=%.6f, cosine=%.6f, mis=%.6f\n" , // cameraState.throughput[0] , cameraState.throughput[1] , cameraState.throughput[2] , contrib[0] , // contrib[1] , contrib[2] , dirPdfA , dirPdfW , lastPdfW , cosine , mis); } colorHitLight = cameraState.throughput * contrib * mis; if (N > 0) weightFactor = 1.f - (Real)nonSpecLength / (Real)N; else weightFactor = 1.f; singleImageColors[cameraState.index] += colorHitLight * weightFactor; break; } //if (N == 0) // printf("%d , error\n" , i); cameraState.pos = eyePath[i].origin; cameraState.lastRay = &eyePath[i - 1]; cameraState.ray = &eyePath[i]; if (eyePath[i].directionSampleType == Ray::RANDOM) { // mis with colorHitLight colorDirIllu = colorByConnectingLights(eyePath[i - 1] , eyePath[i]) * cameraState.throughput; weightFactor = 1.f - ((Real)nonSpecLength + 1.f) / (Real)N; colorDirIllu *= weightFactor; colorGlbIllu = colorByMergingPaths(cameraState , partialSubPaths); mergeContribs.push_back(colorDirIllu + colorGlbIllu / (Real)N); } lastSpecular = (eyePath[i].directionSampleType == Ray::DEFINITE); lastPdfW = eyePath[i].directionProb; if (eyePath[i].directionSampleType == Ray::RANDOM) { nonSpecLength++; if (nonSpecLength == N) break; // PPM, eye path length is 1 } if (eyePath[i].direction.length() < 0.5f) break; if (i >= eyePath.size() - 1) break; cameraState.throughput *= (eyePath[i].color * eyePath[i].getCosineTerm()) / (eyePath[i + 1].originProb * eyePath[i].directionProb); //fprintf(fp , "l=%d, thr=(%.8f,%.8f,%.8f), bsdf=(%.8f,%.8f,%.8f), cos=%.8f, prob=%.8f\n" , // i , cameraState.throughput[0] , cameraState.throughput[1] , cameraState.throughput[2] , // bsdfFactor[0] , bsdfFactor[1] , bsdfFactor[2] , eyePath[i].getCosineTerm() , eyePath[i].directionProb); } for (int i = 0; i < mergeContribs.size(); i++) { singleImageColors[cameraState.index] += mergeContribs[i]; } */ } } else { vector<Path> lightPathListGPU , interPathListGPU , eyePathListGPU; vector<Ray> eyeRayList(cameraPathNum); vector<Ray> lightRayList(lightPathNum); vector<Ray> interRayList(interPathNum); #pragma omp parallel for for (int p = 0; p < lightPathNum; p++) lightRayList[p] = genEmissiveSurfaceSample(true , false); lightPathListGPU = samplePathList(lightRayList); movePaths(cmdLock , lightPathListGPU , lightPathList); genLightPaths(cmdLock , lightPathList , (s == 0)); if (!usePPM) { #pragma omp parallel for for (int p = 0; p < interPathNum; p++) interRayList[p] = genIntermediateSamples(renderer->scene); interPathListGPU = samplePathList(interRayList); movePaths(cmdLock , interPathListGPU , interPathList); genIntermediatePaths(cmdLock , interPathList); } printf("lightPhotonNum = %d, partialPhotonNum = %d\n" , lightPhotonNum , partialPhotonNum); mergePartialPaths(cmdLock); PointKDTree<IptPathState> partialSubPaths(partialSubPathList); #pragma omp parallel for for (int p = 0; p < cameraPathNum; p++) eyeRayList[p] = camera.generateRay(p); eyePathListGPU = sampleMergePathList(eyeRayList); #pragma omp parallel for for(int p=0; p<cameraPathNum; p++) { Path eyePath; eyePath = eyePathListGPU[p]; /* fprintf(fp , "==================\n"); for (int i = 0; i < eyePath.size(); i++) { fprintf(fp , "c = (%.8f,%.8f,%.8f), dir = (%.8f,%.8f,%.8f), cos = %.8f, dirPdf = %.8f, oriPdf = %.8f\n" , eyePath[i].color.x , eyePath[i].color.y , eyePath[i].color.z , eyePath[i].direction.x , eyePath[i].direction.y , eyePath[i].direction.z , eyePath[i].getCosineTerm() , eyePath[i].directionProb , eyePath[i].originProb); } */ //sampleMergePath(eyePath , camera.generateRay(p , true) , 0); singleImageColors[p] += colorByRayMarching(eyePath , partialSubPaths , p); } } printf("done calculation, release memory\n"); if(cmd == "exit") return pixelColors; for(int i=0; i<pixelColors.size(); i++) { if (!isIllegal(singleImageColors[i])) { if (useUniformInterSampler) { pixelColors[i] *= (Real)s / ((Real)s + 1.f); pixelColors[i] += singleImageColors[i] / ((Real)s + 1.f); } else { pixelColors[i] *= ((Real)s - 1.f) / ((Real)s); pixelColors[i] += singleImageColors[i] / ((Real)s); } } else { fprintf(err , "(%.8f,%.8f,%.8f) occurs in iter %d\n" , singleImageColors[i].x , singleImageColors[i].y , singleImageColors[i].z , s); continue; } } if (!renderer->scene.usingGPU()) { for (int i = 0; i < lightPathNum; i++) { if (lightPathList[i]) delete lightPathList[i]; } for (int i = 0; i < interPathNum; i++) { if (interPathList[i]) delete interPathList[i]; } } else { for (int i = 0; i < lightPathNum; i++) lightPathList[i] = NULL; for (int i = 0; i < interPathNum; i++) interPathList[i] = NULL; } printf("Iter: %d IterTime: %ds TotalTime: %ds\n", s, (clock()-t)/1000, clock()/1000); if ((useUniformInterSampler && s == 0) || (!useUniformInterSampler && s == 1)) { for (int y = camera.height - 1; y >= 0; y--) { for (int x = 0; x < camera.width; x++) { if (volMask[y * camera.width + x]) fprintf(fm , "1 "); else fprintf(fm , "0 "); } fprintf(fm , "\n"); } } //if (clock() / 1000 >= lastTime) if (s % outputIter == 0 && !isDebug) { unsigned nowTime = (clock() - startTime) / 1000; showCurrentResult(pixelColors , &nowTime , &s); //showCurrentResult(pixelColors , &lastTime , &s); //lastTime += timeInterval; } else showCurrentResult(pixelColors); } for(int i=0; i<pixelLocks.size(); i++) { omp_destroy_lock(&pixelLocks[i]); } omp_destroy_lock(&cmdLock); return pixelColors; }