| 254 | } |
| 255 | |
| 256 | void NvFlexExtTearClothMesh(NvFlexExtAsset* asset, float maxStrain, int maxSplits, NvFlexExtTearingParticleClone* particleCopies, int* numParticleCopies, int maxCopies, NvFlexExtTearingMeshEdit* triangleEdits, int* numTriangleEdits, int maxEdits) |
| 257 | { |
| 258 | FlexExtTearingClothAsset* tearable = (FlexExtTearingClothAsset*)asset; |
| 259 | |
| 260 | std::vector<ClothMesh::TriangleUpdate> edits; |
| 261 | std::vector<ClothMesh::VertexCopy> copies; |
| 262 | |
| 263 | int splits = 0; |
| 264 | |
| 265 | maxCopies = Min(maxCopies, tearable->maxParticles-tearable->numParticles); |
| 266 | |
| 267 | // iterate over all edges and tear if beyond maximum strain |
| 268 | for (int i=0; i < tearable->numSprings && int(copies.size()) < maxCopies && splits < maxSplits; ++i) |
| 269 | { |
| 270 | int a = tearable->springIndices[i*2+0]; |
| 271 | int b = tearable->springIndices[i*2+1]; |
| 272 | |
| 273 | Vec3 p = Vec3(&tearable->particles[a*4]); |
| 274 | Vec3 q = Vec3(&tearable->particles[b*4]); |
| 275 | |
| 276 | // check strain and break if greater than max threshold |
| 277 | if (Length(p-q) > tearable->springRestLengths[i]*maxStrain) |
| 278 | { |
| 279 | // skip fixed particles |
| 280 | if (Vec4(&tearable->particles[a*4]).w == 0.0f) |
| 281 | continue; |
| 282 | |
| 283 | if (Vec4(&tearable->particles[b*4]).w == 0.0f) |
| 284 | continue; |
| 285 | |
| 286 | // choose vertex of edge to split |
| 287 | const int splitIndex = Randf() > 0.5f ? a : b; |
| 288 | const Vec3 splitPlane = Normalize(p-q); // todo: use plane perpendicular to normal and edge.. |
| 289 | |
| 290 | std::vector<int> adjacentTriangles; |
| 291 | std::vector<int> adjacentVertices; |
| 292 | |
| 293 | const int newIndex = tearable->mMesh->SplitVertex((Vec4*)tearable->particles, splitIndex, splitPlane, adjacentTriangles, adjacentVertices, edits, copies, maxCopies-int(copies.size())); |
| 294 | |
| 295 | if (newIndex != -1) |
| 296 | { |
| 297 | ++splits; |
| 298 | |
| 299 | // separate each adjacent vertex if it is now singular |
| 300 | for (int s=0; s < int(adjacentVertices.size()); ++s) |
| 301 | { |
| 302 | const int adjacentVertex = adjacentVertices[s]; |
| 303 | |
| 304 | tearable->mMesh->SeparateVertex(adjacentVertex, edits, copies, maxCopies-int(copies.size())); |
| 305 | } |
| 306 | |
| 307 | // also test the new vertex which can become singular |
| 308 | tearable->mMesh->SeparateVertex(newIndex, edits, copies, maxCopies-int(copies.size())); |
| 309 | } |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | // update asset particle count |
no test coverage detected