/////////////////////////////////////////////////////////////// returns split position for second array start relative to permute ptr
| 377 | //////////////////////////////////////////////////////////////////// |
| 378 | // returns split position for second array start relative to permute ptr |
| 379 | PxU32 split(PxU32* permute, PxU32 clusterSize) |
| 380 | { |
| 381 | if(clusterSize <= 1) |
| 382 | return 0; |
| 383 | if(clusterSize == 2) |
| 384 | return 1; |
| 385 | |
| 386 | PxI32 minCount = clusterSize >= 4 ? 2 : 1; |
| 387 | PxI32 splitStartL = minCount; // range=[startL->endL) |
| 388 | PxI32 splitEndL = PxI32(clusterSize-minCount); |
| 389 | PxI32 splitStartR = PxI32(clusterSize-splitStartL); // range=(endR<-startR], startR > endR |
| 390 | PxI32 splitEndR = PxI32(clusterSize-splitEndL); |
| 391 | PX_ASSERT(splitEndL-splitStartL == splitStartR-splitEndR); |
| 392 | PX_ASSERT(splitStartL <= splitEndL); |
| 393 | PX_ASSERT(splitStartR >= splitEndR); |
| 394 | PX_ASSERT(splitEndR >= 1); |
| 395 | PX_ASSERT(splitEndL < PxI32(clusterSize)); |
| 396 | |
| 397 | // pick the best axis with some splitting metric |
| 398 | // axis index is X=0, Y=1, Z=2 |
| 399 | PxF32 minMetric[3]; |
| 400 | PxU32 minMetricSplit[3]; |
| 401 | const PxU32* ranks3[3] = { xRanks, yRanks, zRanks }; |
| 402 | const PxU32* orders3[3] = { xOrder, yOrder, zOrder }; |
| 403 | for(PxU32 coordIndex = 0; coordIndex <= 2; coordIndex++) |
| 404 | { |
| 405 | SortBoundsPredicate sortPredicateLR(coordIndex, allBounds); |
| 406 | |
| 407 | const PxU32* rank = ranks3[coordIndex]; |
| 408 | const PxU32* order = orders3[coordIndex]; |
| 409 | |
| 410 | // build ranks in tempPermute |
| 411 | if(clusterSize == nbTotalBounds) // AP: about 4% perf gain from this optimization |
| 412 | { |
| 413 | // if this is a full cluster sort, we already have it done |
| 414 | for(PxU32 i = 0; i < clusterSize; i ++) |
| 415 | tempPermute[i] = order[i]; |
| 416 | } else |
| 417 | { |
| 418 | // sort the tempRanks |
| 419 | for(PxU32 i = 0; i < clusterSize; i ++) |
| 420 | tempRanks[i] = rank[permute[i]]; |
| 421 | Ps::sort(tempRanks, clusterSize); |
| 422 | for(PxU32 i = 0; i < clusterSize; i ++) // convert back from ranks to indices |
| 423 | tempPermute[i] = order[tempRanks[i]]; |
| 424 | } |
| 425 | |
| 426 | // we consider overlapping intervals for minimum sum of metrics |
| 427 | // left interval is from splitStartL up to splitEndL |
| 428 | // right interval is from splitStartR down to splitEndR |
| 429 | |
| 430 | |
| 431 | // first compute the array metricL |
| 432 | Vec3V boundsLmn = allBounds[tempPermute[0]].mn; // init with 0th bound |
| 433 | Vec3V boundsLmx = allBounds[tempPermute[0]].mx; // init with 0th bound |
| 434 | PxI32 ii; |
| 435 | for(ii = 1; ii < splitStartL; ii++) // sweep right to include all bounds up to splitStartL-1 |
| 436 | { |
no test coverage detected