예제 #1
0
        // 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));
            }
        }