Color getApproxColor(Furniture& item, Image<Color>& texture){ //Calcuate Bounding Box and Rotate According to Angle (Radians) float x_c = item.getPos().x; float y_c = item.getPos().y; int max_x, max_y, min_x, min_y, totalPixels; max_x = (int) (x_c + DESK_LENGTH/2.0); min_x = (int) (x_c - DESK_WIDTH/2.0); max_y = (int) (y_c + DESK_LENGTH/2.0); min_y = (int) (y_c - DESK_WIDTH/2.0); // Make a black pixel that I will add to Color colorSum(0,0,0); // Check if we are inrange of our texture image if(!(inRange(max_x,max_y) && inRange(min_x, min_y))){ return colorSum; } // colors unsigned int red = 0; unsigned int gre = 0; unsigned int blu = 0; // Pixels totalPixels = 0; // for all pixles in that square range add to colorSum for(int x = min_x; x < max_x; x++){ for(int y = min_y; y < max_y; y++){ Color curPixel = texture.GetPixel(x,y); red += (int)curPixel.r; gre += (int)curPixel.b; blu += (int)curPixel.g; totalPixels++; } }//for // Find the average color red = ((double)red) / totalPixels; gre = ((double)gre) / totalPixels; blu = ((double)blu) / totalPixels; colorSum.r = (unsigned char)red; colorSum.g = (unsigned char)gre; colorSum.b = (unsigned char)blu; return colorSum; }
rgbColor whittedRayTracer::_L(ray& r, const int& depth) const{ if(depth > MAX_DEPTH){ return rgbColor(0.f); } const intersection isect = parent.intersect(r); //return rgbColor(0, isect.debugInfo / 1e8, 0); if(!isect.hit){ return rgbColor(0.f); }else if(isect.li != NULL){ return isect.li->L(r); } material& mat = isect.li ? *isect.li->getMaterial().get() : *isect.s->getMaterial().get(); const vec3& normal = isect.shadingNormal; const bsdf& bsdf = mat.getBsdf(isect.uv); const vec3 wo = worldToBsdf(-r.direction, isect); bxdfType sampledType; rgbColor colorSum(0.f); if(isect.s->getMaterial()->isEmissive()){ return mat.Le(); } // Diffuse calculations. float lightPdf = 0.f; for(int i=0; i<parent.numLights(); ++i){ const light& li = parent.getLight(i); if(li.isPointSource()){ vec3 lightDir; const rgbColor Li = li.sampleL(r.origin, lightDir, sampleUniform(), sampleUniform(), lightPdf); const float lightDist = norm(lightDir); lightDir = normalize(lightDir); // Test for shadowing early. ray shadowRay(r.origin, lightDir); shadowRay.tMax = lightDist; if(!parent.intersectB(shadowRay)){ const vec3 wi = worldToBsdf(lightDir, isect); const rgbColor f = bsdf.f(wo, wi, bxdfType(DIFFUSE | GLOSSY | REFLECTION)) + mat.Le(); colorSum += f * dot(normal, lightDir) * (Li / lightPdf); } }else{ rgbColor areaContrib(0.f); for(int j=0; j<areaSamples; ++j){ vec3 lightDir; const rgbColor Li = li.sampleL(r.origin, lightDir, sampleUniform(), sampleUniform(), lightPdf); ray shadowRay(r.origin, normalize(lightDir)); shadowRay.tMax = norm(lightDir) + EPSILON; if(!parent.intersectB(shadowRay) && li.intersect(shadowRay).hit){ lightDir = normalize(lightDir); const vec3 wi = worldToBsdf(lightDir, isect); const rgbColor f = bsdf.f(wo, wi, bxdfType(DIFFUSE | GLOSSY | REFLECTION)) + mat.Le(); areaContrib += f * dot(normal, lightDir) * (Li / lightPdf); } } colorSum += areaContrib / (float)areaSamples; } } // Trace specular rays. vec3 specDir; float pdf; const rgbColor fr = bsdf.sampleF(sampleUniform(), sampleUniform(), sampleUniform(), wo, specDir, bxdfType(GLOSSY | SPECULAR | REFLECTION), sampledType, pdf); if(!fr.isBlack()){ specDir = bsdfToWorld(specDir, isect); ray r2(r.origin, specDir); colorSum += (fr / pdf) * _L(r2, depth+1) * abs(dot(specDir, normal)); } const rgbColor ft = bsdf.sampleF(sampleUniform(), sampleUniform(), sampleUniform(), wo, specDir, bxdfType(GLOSSY | SPECULAR | TRANSMISSION), sampledType, pdf); if(!ft.isBlack()){ specDir = bsdfToWorld(specDir, isect); ray r2(r.origin, specDir); colorSum += (ft / pdf) * _L(r2, depth+1) * abs(dot(specDir, normal)); } if(!isFinite(colorSum.avg())) { return ERROR_COLOR; } else { return colorSum; } }