internal static void SelfSweep <T>(BucketSlices bucket, T processor) where T : struct, IFindPairsProcessor { int count = bucket.xmins.Length; for (int i = 0; i < count - 1; i++) { for (int j = i + 1; j < count && bucket.xmins[j] <= bucket.xmaxs[i]; j++) { float4 less = new float4(bucket.yzminmaxs[i].z, bucket.yzminmaxs[j].z, bucket.yzminmaxs[i].w, bucket.yzminmaxs[j].w); float4 more = new float4(bucket.yzminmaxs[j].x, bucket.yzminmaxs[i].x, bucket.yzminmaxs[j].y, bucket.yzminmaxs[i].y); bool4 tests = less < more; if (math.bitmask(tests) == 0) { processor.Execute(new FindPairsResult { bodyA = bucket.bodies[i], bodyB = bucket.bodies[j], bodyAIndex = i, bodyBIndex = j, }); } } } }
internal static void BipartiteSweep <T>(BucketSlices bucketA, BucketSlices bucketB, T processor) where T : struct, IFindPairsProcessor { int countA = bucketA.xmins.Length; int countB = bucketB.xmins.Length; if (countA == 0 || countB == 0) { return; } //Check for b starting in a's x range int bstart = 0; for (int i = 0; i < countA; i++) { //Advance to b.xmin >= a.xmin //Include equals case by stopping when equal while (bstart < countB && bucketB.xmins[bstart] < bucketA.xmins[i]) { bstart++; } if (bstart >= countB) { break; } for (int j = bstart; j < countB && bucketB.xmins[j] <= bucketA.xmaxs[i]; j++) { float4 less = new float4(bucketA.yzminmaxs[i].z, bucketB.yzminmaxs[j].z, bucketA.yzminmaxs[i].w, bucketB.yzminmaxs[j].w); float4 more = new float4(bucketB.yzminmaxs[j].x, bucketA.yzminmaxs[i].x, bucketB.yzminmaxs[j].y, bucketA.yzminmaxs[i].y); bool4 tests = less < more; if (math.bitmask(tests) == 0) { processor.Execute(new FindPairsResult { bodyA = bucketA.bodies[i], bodyB = bucketB.bodies[j], bodyAIndex = i, bodyBIndex = j, }); } } } //Check for a starting in b's x range int astart = 0; for (int i = 0; i < countB; i++) { //Advance to a.xmin > b.xmin //Exclude equals case this time by continuing if equal while (astart < countA && bucketA.xmins[astart] <= bucketB.xmins[i]) { astart++; } if (astart >= countA) { break; } for (int j = astart; j < countA && bucketA.xmins[j] <= bucketB.xmaxs[i]; j++) { float4 less = new float4(bucketB.yzminmaxs[i].z, bucketA.yzminmaxs[j].z, bucketB.yzminmaxs[i].w, bucketA.yzminmaxs[j].w); float4 more = new float4(bucketA.yzminmaxs[j].x, bucketB.yzminmaxs[i].x, bucketA.yzminmaxs[j].y, bucketB.yzminmaxs[i].y); bool4 tests = less < more; if (math.bitmask(tests) == 0) { processor.Execute(new FindPairsResult { bodyA = bucketA.bodies[j], bodyB = bucketB.bodies[i], bodyAIndex = i, bodyBIndex = j, }); } } } }