BBox NURBS::WorldBound() const { if (!isHomogeneous) { // Compute world-space bound of non-homogeneous NURBS float *pp = P; Point pt = ObjectToWorld(Point(pp[0], pp[1], pp[2])); BBox bound = pt; for (int i = 0; i < nu*nv; ++i, pp += 3) { pt = ObjectToWorld(Point(pp[0], pp[1], pp[2])); bound = Union(bound, pt); } return bound; } else { // Compute world-space bound of homogeneous NURBS float *pp = P; Point pt = ObjectToWorld(Point(pp[0]/pp[3], pp[1]/pp[3], pp[2]/pp[3])); BBox bound = pt; for (int i = 0; i < nu*nv; ++i, pp += 4) { pt = ObjectToWorld(Point(pp[0]/pp[3], pp[1]/pp[3], pp[2]/pp[3])); bound = Union(bound, pt); } return bound; } }
void csPortalContainer::CheckMovable () { Prepare (); const csMovable& cmovable = meshwrapper->GetCsMovable (); if (movable_nr == cmovable.GetUpdateNumber ()) return; const csReversibleTransform movtrans = cmovable.GetFullTransform (); ObjectToWorld (cmovable, movtrans); }
void SurfacePointsRenderer::Render(const Scene &scene) { // Declare shared variables for Poisson point generation BBox octBounds = scene.WorldBound(); octBounds.Expand(.001f * powf(octBounds.Volume(), 1.f/3.f)); Octree<SurfacePoint> pointOctree(octBounds); // Create scene bounding sphere to catch rays that leave the scene Point sceneCenter; float sceneRadius; scene.WorldBound().BoundingSphere(&sceneCenter, &sceneRadius); Transform ObjectToWorld(Translate(sceneCenter - Point(0,0,0))); Transform WorldToObject(Inverse(ObjectToWorld)); Reference<Shape> sph = new Sphere(&ObjectToWorld, &WorldToObject, true, sceneRadius, -sceneRadius, sceneRadius, 360.f); //Reference<Material> nullMaterial = Reference<Material>(NULL); Material nullMaterial; GeometricPrimitive sphere(sph, nullMaterial, NULL); int maxFails = 2000, repeatedFails = 0, maxRepeatedFails = 0; if (PbrtOptions.quickRender) maxFails = max(10, maxFails / 10); int totalPathsTraced = 0, totalRaysTraced = 0, numPointsAdded = 0; ProgressReporter prog(maxFails, "Depositing samples"); // Launch tasks to trace rays to find Poisson points PBRT_SUBSURFACE_STARTED_RAYS_FOR_POINTS(); vector<Task *> tasks; RWMutex *mutex = RWMutex::Create(); int nTasks = NumSystemCores(); for (int i = 0; i < nTasks; ++i) tasks.push_back(new SurfacePointTask(scene, pCamera, time, i, minDist, maxFails, *mutex, repeatedFails, maxRepeatedFails, totalPathsTraced, totalRaysTraced, numPointsAdded, sphere, pointOctree, points, prog)); EnqueueTasks(tasks); WaitForAllTasks(); for (uint32_t i = 0; i < tasks.size(); ++i) delete tasks[i]; RWMutex::Destroy(mutex); prog.Done(); PBRT_SUBSURFACE_FINISHED_RAYS_FOR_POINTS(totalRaysTraced, numPointsAdded); if (filename != "") { // Write surface points to file FILE *f = fopen(filename.c_str(), "w"); if (!f) { Error("Unable to open output file \"%s\" (%s)", filename.c_str(), strerror(errno)); return; } fprintf(f, "# points generated by SurfacePointsRenderer\n"); fprintf(f, "# position (x,y,z), normal (x,y,z), area, rayEpsilon\n"); for (u_int i = 0; i < points.size(); ++i) { const SurfacePoint &sp = points[i]; fprintf(f, "%g %g %g %g %g %g %g %g\n", sp.p.x, sp.p.y, sp.p.z, sp.n.x, sp.n.y, sp.n.z, sp.area, sp.rayEpsilon); } fclose(f); } }
void csPortalContainer::GetBoundingSpheres (iRenderView* rview, csReversibleTransform* tr_o2c, csVector3* camera_origin, csSphere& world_sphere, csSphere& cam_sphere) { iCamera* camera = rview->GetCamera (); const csReversibleTransform& camtrans = camera->GetTransform (); const csMovable& cmovable = meshwrapper->GetCsMovable (); if (movable_nr != cmovable.GetUpdateNumber ()) { const csReversibleTransform movtrans = cmovable.GetFullTransform (); ObjectToWorld (cmovable, movtrans); } csSphere sphere; sphere.SetCenter (object_bbox.GetCenter ()); sphere.SetRadius (object_radius); uint8 local_t2c[sizeof(csReversibleTransform)]; if (tr_o2c == 0) { #include "csutil/custom_new_disable.h" tr_o2c = new (local_t2c) csReversibleTransform; #include "csutil/custom_new_enable.h" } *tr_o2c = camtrans; if (!movable_identity) { const csReversibleTransform movtrans = cmovable.GetFullTransform (); *tr_o2c /= movtrans; world_sphere = movtrans.This2Other (sphere); } else { world_sphere = sphere; } cam_sphere = tr_o2c->Other2This (sphere); if (camera_origin) *camera_origin = cam_sphere.GetCenter (); }
void CreateRadianceProbes::Render(const Scene *scene) { // Compute scene bounds and initialize probe integrators if (bbox.pMin.x > bbox.pMax.x) bbox = scene->WorldBound(); surfaceIntegrator->Preprocess(scene, camera, this); volumeIntegrator->Preprocess(scene, camera, this); Sample *origSample = new Sample(NULL, surfaceIntegrator, volumeIntegrator, scene); // Compute sampling rate in each dimension Vector delta = bbox.pMax - bbox.pMin; int nProbes[3]; for (int i = 0; i < 3; ++i) nProbes[i] = max(1, Ceil2Int(delta[i] / probeSpacing)); // Allocate SH coefficient vector pointers for sample points int count = nProbes[0] * nProbes[1] * nProbes[2]; Spectrum **c_in = new Spectrum *[count]; for (int i = 0; i < count; ++i) c_in[i] = new Spectrum[SHTerms(lmax)]; // Compute random points on surfaces of scene // Create scene bounding sphere to catch rays that leave the scene Point sceneCenter; float sceneRadius; scene->WorldBound().BoundingSphere(&sceneCenter, &sceneRadius); Transform ObjectToWorld(Translate(sceneCenter - Point(0,0,0))); Transform WorldToObject(Inverse(ObjectToWorld)); Reference<Shape> sph = new Sphere(&ObjectToWorld, &WorldToObject, true, sceneRadius, -sceneRadius, sceneRadius, 360.f); Reference<Material> nullMaterial = Reference<Material>(NULL); GeometricPrimitive sphere(sph, nullMaterial, NULL); vector<Point> surfacePoints; uint32_t nPoints = 32768, maxDepth = 32; surfacePoints.reserve(nPoints + maxDepth); Point pCamera = camera->CameraToWorld(camera->shutterOpen, Point(0, 0, 0)); surfacePoints.push_back(pCamera); RNG rng; while (surfacePoints.size() < nPoints) { // Generate random path from camera and deposit surface points Point pray = pCamera; Vector dir = UniformSampleSphere(rng.RandomFloat(), rng.RandomFloat()); float rayEpsilon = 0.f; for (uint32_t i = 0; i < maxDepth; ++i) { Ray ray(pray, dir, rayEpsilon, INFINITY, time); Intersection isect; if (!scene->Intersect(ray, &isect) && !sphere.Intersect(ray, &isect)) break; surfacePoints.push_back(ray(ray.maxt)); DifferentialGeometry &hitGeometry = isect.dg; pray = isect.dg.p; rayEpsilon = isect.rayEpsilon; hitGeometry.nn = Faceforward(hitGeometry.nn, -ray.d); dir = UniformSampleSphere(rng.RandomFloat(), rng.RandomFloat()); dir = Faceforward(dir, hitGeometry.nn); } } // Launch tasks to compute radiance probes at sample points vector<Task *> tasks; ProgressReporter prog(count, "Radiance Probes"); for (int i = 0; i < count; ++i) tasks.push_back(new CreateRadProbeTask(i, nProbes, time, bbox, lmax, includeDirectInProbes, includeIndirectInProbes, nIndirSamples, prog, origSample, surfacePoints, scene, this, c_in[i])); EnqueueTasks(tasks); WaitForAllTasks(); for (uint32_t i = 0; i < tasks.size(); ++i) delete tasks[i]; prog.Done(); // Write radiance probe coefficients to file FILE *f = fopen(filename.c_str(), "w"); if (f) { if (fprintf(f, "%d %d %d\n", lmax, includeDirectInProbes?1:0, includeIndirectInProbes?1:0) < 0 || fprintf(f, "%d %d %d\n", nProbes[0], nProbes[1], nProbes[2]) < 0 || fprintf(f, "%f %f %f %f %f %f\n", bbox.pMin.x, bbox.pMin.y, bbox.pMin.z, bbox.pMax.x, bbox.pMax.y, bbox.pMax.z) < 0) { Error("Error writing radiance file \"%s\" (%s)", filename.c_str(), strerror(errno)); exit(1); } for (int i = 0; i < nProbes[0] * nProbes[1] * nProbes[2]; ++i) { for (int j = 0; j < SHTerms(lmax); ++j) { fprintf(f, " "); if (c_in[i][j].Write(f) == false) { Error("Error writing radiance file \"%s\" (%s)", filename.c_str(), strerror(errno)); exit(1); } fprintf(f, "\n"); } fprintf(f, "\n"); } fclose(f); } for (int i = 0; i < nProbes[0] * nProbes[1] * nProbes[2]; ++i) delete[] c_in[i]; delete[] c_in; delete origSample; }