| 183 | }; |
| 184 | |
| 185 | int CreateClusters(Vec3* particles, const float* priority, int numParticles, std::vector<int>& outClusterOffsets, std::vector<int>& outClusterIndices, std::vector<Vec3>& outClusterPositions, float radius, float smoothing = 0.0f) |
| 186 | { |
| 187 | std::vector<Seed> seeds; |
| 188 | std::vector<Cluster> clusters; |
| 189 | |
| 190 | // flags a particle as belonging to at least one cluster |
| 191 | std::vector<bool> used(numParticles, false); |
| 192 | |
| 193 | // initialize seeds |
| 194 | for (int i = 0; i < numParticles; ++i) |
| 195 | { |
| 196 | Seed s; |
| 197 | s.index = i; |
| 198 | s.priority = priority[i]; |
| 199 | |
| 200 | seeds.push_back(s); |
| 201 | } |
| 202 | |
| 203 | // sort seeds on priority |
| 204 | std::stable_sort(seeds.begin(), seeds.end()); |
| 205 | |
| 206 | SweepAndPrune sap(particles, numParticles); |
| 207 | |
| 208 | while (seeds.size()) |
| 209 | { |
| 210 | // pick highest unused particle from the seeds list |
| 211 | Seed seed = seeds.back(); |
| 212 | seeds.pop_back(); |
| 213 | |
| 214 | if (!used[seed.index]) |
| 215 | { |
| 216 | Cluster c; |
| 217 | |
| 218 | sap.QuerySphere(Vec3(particles[seed.index]), radius, c.indices); |
| 219 | |
| 220 | // mark overlapping particles as used so they are removed from the list of potential cluster seeds |
| 221 | for (int i=0; i < int(c.indices.size()); ++i) |
| 222 | used[c.indices[i]] = true; |
| 223 | |
| 224 | c.mean = CalculateMean(particles, &c.indices[0], int(c.indices.size())); |
| 225 | |
| 226 | clusters.push_back(c); |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | if (smoothing > 0.0f) |
| 231 | { |
| 232 | for (int i = 0; i < int(clusters.size()); ++i) |
| 233 | { |
| 234 | Cluster& c = clusters[i]; |
| 235 | |
| 236 | // clear cluster indices |
| 237 | c.indices.resize(0); |
| 238 | |
| 239 | // calculate cluster particles using cluster mean and smoothing radius |
| 240 | sap.QuerySphere(c.mean, smoothing, c.indices); |
| 241 | |
| 242 | c.mean = CalculateMean(particles, &c.indices[0], int(c.indices.size())); |
no test coverage detected