void a4_render_thread(Image* img, unsigned int ystart, unsigned int yskip, unsigned int width, unsigned int height, std::shared_ptr<SceneNode> root, const Matrix4x4 unproject, const Point3D eye, const Colour ambient, const std::list<std::shared_ptr<Light>> lights, unsigned int recurse_level, unsigned int aa_samples, unsigned int shadow_samples, unsigned int glossy_samples, Image* bgimg) { // Seed the rng and set the uniform distribution object std::mt19937 gen(std::chrono::system_clock::now().time_since_epoch().count()); std::uniform_real_distribution<double> uniform_distribution(0, 1); std::function<double()> uniform = std::bind(uniform_distribution, std::ref(gen)); int one_percent = width * height * 0.01; int pixel_count = 0; glossy_samples = (glossy_samples == 0) ? 1 : glossy_samples; shadow_samples = (shadow_samples == 0) ? 1 : shadow_samples; aa_samples = (aa_samples == 0) ? 1 : aa_samples; for (unsigned int y = ystart; y < height; y += yskip) { for (unsigned int x = 0; x < width; x++) { // Background colour. a4_trace_ray returns this if no intersections Colour bg = bgimg->empty() ? ((x+y) & 0x10) ? (double)y/height * Colour(1.0, 1.0, 1.0) : Colour(0.0, 0.0, 0.0) : a4_get_background_colour(*bgimg, x, y, img->width(), img->height()); // Cast a ray into the scene and get the colour returned Colour colour(0.0, 0.0, 0.0); // For antialiasing, divide the "pixel" into a n by n grid and cast rays from a random point within each grid box for(unsigned int p = 0; p < aa_samples; p++) { for(unsigned int q = 0; q < aa_samples; q++) { // Unproject the pixel to the projection plane double e = uniform(); Point3D pixel ((double)x + ((double)p + e) / (double)aa_samples, (double)y - ((double)q + e) / (double)aa_samples, 0.0); Point3D p = unproject * pixel; // Create the ray with origin at the eye point Ray ray(eye, p-eye); colour = colour + a4_trace_ray(ray, root, lights, ambient, bg, uniform, recurse_level, shadow_samples, glossy_samples); } } // Of course, have to divide the colour by the number of samples taken double n = aa_samples * aa_samples; colour = Colour(colour.R() / n, colour.G() / n, colour.B() / n); (*img)(x, y, 0) = colour.R(); (*img)(x, y, 1) = colour.G(); (*img)(x, y, 2) = colour.B(); if(++pixel_count >= one_percent) { { std::lock_guard<std::mutex> lock(progress_mut); progress++; } progress_cond.notify_one(); pixel_count = 0; } } } }
int main(const int argc, const char* const argv[]) { if (argc > 3) { std::cerr << err << "\n At most two arguments are allowed " "(the seed for the random-number generator and the number of elements).\n"; return errcode_parameter; } const int seed = (argc == 1) ? default_seed : boost::lexical_cast<int>(argv[1]); const unsigned int N = (argc < 3) ? default_N : boost::lexical_cast<unsigned int>(argv[2]); vec_t V(N); typedef boost::uniform_int<> uniform_distribution_type; uniform_distribution_type uniform_distribution(0,std::numeric_limits<int>::max()); // is this correct??? typedef boost::variate_generator<base_generator_type&, uniform_distribution_type> generator_type; generator_type rand_gen(base_rand_gen, uniform_distribution); typedef boost::random_number_generator<generator_type> RandomNumberGenerator; RandomNumberGenerator rg(rand_gen); set_random(seed); std::cout << "Underlying random sequence:\n"; for (long n = V.size(); n > 1; --n) std::cout << rg(n) << " "; std::cout << "\n\n"; typedef boost::random_number_generator<base_generator_type> RandomNumberGeneratorWOVariate; RandomNumberGeneratorWOVariate rg_wo_variate(base_rand_gen); set_random(seed); std::cout << "Underlying random sequence (boost::random_number_generator using just boost::mt19937):\n"; for (long n = V.size(); n > 1; --n) std::cout << rg_wo_variate(n) << " "; std::cout << "\n\n"; set_random(seed); std::cout << "Underlying random sequence (randn):\n"; for (long n = V.size(); n > 1; --n) std::cout << ::randn(n) << " "; std::cout << "\n\n"; initialise(V); set_random(seed); std::random_shuffle(V.begin(), V.end(), rg); std::cout << "std::random_shuffle:\n"; output(V); initialise(V); set_random(seed); ::random_shuffle_libcpp(V.begin(), V.end(), rg); std::cout << "std::random_shuffle_libcpp:\n"; output(V); initialise(V); set_random(seed); ::random_shuffle(V.begin(), V.end(), rg); std::cout << "::random_shuffle:\n"; output(V); }
// MIS: sampling light source glm::vec3 BidirectionalIntegrator::MIS_SampleLight(Intersection &intersection, Ray &r, Geometry* &light) { if(Number_Light == 0) return glm::vec3(0); // Direct light estimator: sample Light source glm::vec3 sum_light_sample(0); for(int i = 0; i < Number_Light; i++) { float u = uniform_distribution(generator); float v = uniform_distribution(generator); Intersection lightSample = light->SampleOnGeometrySurface(u, v, intersection.point + 1e-3f * intersection.normal); //Intersection lightSample = light->RandomSampleOnSurface(u,v); glm::vec3 wj = glm::normalize(lightSample.point - intersection.point); glm::vec3 wo = - r.direction; glm::vec3 P = intersection.point; glm::vec3 N = intersection.normal; float pdf_light = light->RayPDF(intersection, Ray(P + float(1e-3)*N, wj)); Intersection lightIntersection = intersection_engine->GetIntersection(Ray(P + float(1e-3)*N, wj)); float temp, pdf_brdf; glm::vec3 wo_local = intersection.ToLocalNormalCoordinate(wo); glm::vec3 wj_local = intersection.ToLocalNormalCoordinate(wj); glm::vec3 F = intersection.object_hit->material->EvaluateScatteredEnergy(intersection, wo_local, wj_local, pdf_brdf); // reach light directly && pdf(wj) > 0 if(lightIntersection.t > 0 && lightIntersection.object_hit == light && pdf_light > 0 && pdf_brdf > 0) { glm::vec3 Ld = light->material->EvaluateScatteredEnergy(lightSample, wo, -wj, temp); float W = PowerHeuristic(pdf_light, float(Number_Light), pdf_brdf, float(Number_BRDF)); // cause shadow in center sum_light_sample = sum_light_sample + W * F * Ld * float(fabs(glm::dot(wj, N))) / pdf_light; } } return sum_light_sample / float(Number_Light); }
void random_points_on_mesh( const int n, const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, Eigen::MatrixXd & X) { X.resize(n,3); // Compute Area: Eigen::MatrixXd all_area; Eigen::MatrixXd cum_area; igl::doublearea(V, F, all_area); igl::cumsum(all_area, 1, cum_area); cum_area.array().rowwise() /= cum_area.row(cum_area.rows()-1).array(); // Uniform Random inspired by C++ library std::default_random_engine random_generator; std::uniform_real_distribution<double> uniform_distribution(0.0, 1.0); for(int i = 0; i < X.rows(); i ++) { // Find x: double threshold = uniform_distribution(random_generator); int ind = find_index(cum_area, threshold); Eigen::RowVectorXd v0 = V.row(F(ind, 0)); Eigen::RowVectorXd v1 = V.row(F(ind, 1)); Eigen::RowVectorXd v2 = V.row(F(ind, 2)); double alpha = uniform_distribution(random_generator); double beta = uniform_distribution(random_generator); if (alpha + beta > 1) { alpha = 1 - alpha; beta = 1 - beta; } X.row(i) = v0 + alpha*(v1 - v0) + beta*(v2 - v0); } }
std::vector<PathNode> BidirectionalIntegrator::generateLightPath(Geometry* &light) { std::vector<PathNode> lightPath; lightPath.clear(); Intersection lightSample = light->RandomSampleOnSurface(uniform_distribution(generator),uniform_distribution(generator)); Ray r(lightSample.point, lightSample.point - light->transform.position()); Intersection isx = intersection_engine->GetIntersection(r); int depth = 0; while(isx.t > 0 && depth < max_depth) { // store pathnode on the light path PathNode node; node.isx = isx; node.dirIn_world = -r.direction; node.dirIn_local = isx.ToLocalNormalCoordinate(-r.direction); node.F = isx.object_hit->material->SampleAndEvaluateScatteredEnergy(isx,node.dirIn_local,node.dirOut_local,node.pdf); node.dirOut_world = isx.ToWorldNormalCoordinate(node.dirOut_local); if(node.pdf != 0) lightPath.push_back(node); else break; //update r r = Ray(isx.point + glm::sign(glm::dot(node.dirOut_world,isx.normal)) * isx.normal*1e-3f, node.dirOut_world); // update isx and depth info depth++; isx = intersection_engine->GetIntersection(r); } return lightPath; }
int main(void) { int listen_on_socket, client_socket; // listen on sock_fd, new connection on client_socket struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1, rv, rate = 5; char s[INET6_ADDRSTRLEN]; struct timespec sleepTime = {5, 0};//10000000 char * IP = "10.10.66.90"; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(IP, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through the linked list servinfo returned by getaddrinfo, stop as soon as the binding succeeds. for(p = servinfo; p != NULL; p = p->ai_next) { if ((listen_on_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("client: socket"); continue; } if (setsockopt(listen_on_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(listen_on_socket, p->ai_addr, p->ai_addrlen) == -1) { close(listen_on_socket); perror("client: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "client: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // release servinfo when we are done using it. if (listen(listen_on_socket, BACKLOG) == -1) { perror("listen"); exit(1); } sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } printf("client: waiting for connections...\n"); // Accept while(1) { sin_size = sizeof their_addr; client_socket = accept(listen_on_socket, (struct sockaddr *)&their_addr, &sin_size); if (client_socket == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("client: got connection from %s\n", s); if (!fork()) { // this is the child process close(listen_on_socket); // child doesn't need the listener // if (send(client_socket, "Hello, world!", 13, 0) == -1) // perror("send"); ///////////////////////////////////////////////////////////// FILE *input = fopen("Schedule.png", "rb"); int a; while(fread(&a, sizeof(int), 1, input) && !feof(input)) { send(client_socket, &a, sizeof(a),0); sleepTime.tv_sec = rate; //nanosleep(&sleepTime, NULL); rate = uniform_distribution(0, 10); printf("%d\n", rate); } a = -1; send(client_socket, &a, sizeof(a), 0); fclose(input); char ackn[100]; int numbytes; if ((numbytes = recv(client_socket, ackn, sizeof(ackn)-1, 0)) == -1) { perror("receiving error."); } ackn[numbytes] = '\0'; printf("%s\n", ackn); ///////////////////////////////////////////////////////////// close(client_socket); exit(0); } close(client_socket); // parent doesn't need this } return 0; }
int main() { std::vector<int> vec(10); std::cout << "iota:" << '\n'; boost::iota(vec, 1); for (auto e : vec) std::cout << e << " "; std::cout << '\n'; std::cout << "reversed:" << '\n'; for (auto e : vec | boost::adaptors::reversed) std::cout << e << " "; std::cout << '\n'; std::cout << "sums:" << '\n'; std::vector<int> sums(10); boost::partial_sum(vec, begin(sums)); for (auto e : sums) std::cout << e << " "; std::cout << '\n'; // perhaps as exercise? std::cout << "evens:" << '\n'; std::vector<int> evens(10); boost::fill(evens, 2); // std::vector<int> evens(10, 2); boost::partial_sum(evens, begin(evens)); for (auto e : evens) std::cout << e << " "; std::cout << '\n'; boost::partial_sum(evens | boost::adaptors::reversed, begin(evens)); for (auto e : evens) std::cout << e << " "; std::cout << '\n'; // perhaps as exercise? std::cout << "factorials:" << '\n'; std::vector<int> factorials(10); boost::partial_sum(vec, begin(factorials), std::multiplies<int>()); for (auto e : factorials) std::cout << e << " "; std::cout << '\n'; std::cout << "die:" << '\n'; std::random_device random_device; std::default_random_engine random_engine(random_device()); int a = 1, b = 6; std::uniform_int_distribution<int> uniform_distribution(a, b); auto die = std::bind(uniform_distribution, random_engine); std::cout << die() << '\n'; std::cout << "die throws:" << '\n'; std::vector<int> die_throws(10); boost::generate(die_throws, die); // readability: "generate die_throws using die [duh]" for (auto e : die_throws) std::cout << e << " "; std::cout << '\n'; std::cout << "die throws, from #2 to #5:" << '\n'; for (auto e : die_throws | boost::adaptors::sliced(2, 5)) std::cout << e << " "; std::cout << '\n'; auto count_unique_low = boost::count_if( die_throws | boost::adaptors::uniqued, [](int result) { return result <= 3; } ); auto count_unique_high = boost::count_if( die_throws | boost::adaptors::uniqued, [](int result) { return result > 3; } ); std::cout << "count_unique_low = " << count_unique_low << '\n'; std::cout << "count_unique_high = " << count_unique_high << '\n'; /* std::vector<int> v; boost::push_front(v, boost::istream_range<int>(std::cin)); for (auto e : v) std::cout << e << " "; std::cout << '\n'; */ std::vector<int> v; boost::push_back(v, boost::irange(100, 200, 3)); // first, last, step-size for (auto e : v) std::cout << e << " "; std::cout << '\n'; }