// create a particle mesh by fitting points on an implicit surface defined by a signed distance field public ParticleMesh(Func <Vector3, float> dist_func, Vector3 domain_hsize, Vector3 domain_offset, int particle_count, float quality) { // store stuff Vector3 p; float D; // hard-limit on sample count, to avoid infinite sampling when the distance function is positive everywhere int sample_limit = particle_count * 1000; // divide once float thickness = 1.0f / quality; // preallocate position container points = new List <Vector3>(particle_count); // particle-fitting int samples = 0; int i = 0; while (i < particle_count && samples < sample_limit) { // generate random position inside bounding volume p.x = Lib.FastRandomFloat() * domain_hsize.x + domain_offset.x; p.y = Lib.FastRandomFloat() * domain_hsize.y + domain_offset.y; p.z = Lib.FastRandomFloat() * domain_hsize.z + domain_offset.z; // calculate signed distance D = dist_func(p); if (D <= 0.0f) // if inside { // this displays the exact radiation field border if (D <= 0.0 && D > -thickness) { points.Add(p); ++i; } } // count samples ++samples; } // some feedback on the samples going above the limit if (i < particle_count) { Lib.Log("particle-fitting reached hard limit at " + Lib.HumanReadablePerc((double)i / (double)particle_count)); } }