void RadixSortNULLVector() { Vector* vec = NULL; RadixSort(vec, 1); printf("SortNULLVector..................OK\n"); }
int main() { //SqList L; //CreateSqList(L, "SqList_Data.txt"); //InsertSort(L); //BInsertSort(L); //TwoInsertSort(L); //int dlta[30] = { 2, 1 }; //ShellSort(L, dlta, 2); //QuickSort(L); //SelectSort(L); //InverseSq(L); //HeapSort(L); //MergeSort(L); //ListTraverse_Sq(L, display_Sq); //DestroyList_Sq(L); /*SLinkListType SL; CreateLinkList(SL, "SqList_Data.txt"); TableInsertSort(SL); Arrange(SL); for (int i = 1; i <= SL.length; i++) { printf("%d ", SL.r[i].key); }*/ SLList L; CreateRadixSort(L, "RADIX_DATA.txt"); RadixSort(L); for (int i = L.r[0].next; i; i = L.r[i].next) { printf("%d ", L.r[i].keys[2] * 100 + L.r[i].keys[1] * 10 + L.r[i].keys[0]); } printf("\n"); system("pause"); return 0; }
void main() { SLList L; cout<<"基数排序(链式存储).cpp"<<endl<<"============="<<endl<<endl; creatExample(L); RadixSort(L); }
void main() { int n=10,r=10,d=2; int i,j,k; RecType *p; char a[MAXE][MAXD]; int b[]={75,23,98,44,57,12,29,64,38,82}; for (i=0;i<n;i++) /*将b[i]转换成字符串*/ { k=b[i]; for (j=0;j<d;j++) /*例如b[0]=75,转换后a[0][0]='7',a[0][1]='5'*/ { a[i][j]=k%10+'0'; k=k/10; } a[i][j]='\0'; } CreateLink(p,a,n); printf("\n"); printf(" 初始关键字\t"); /*输出初始关键字序列*/ DispLink(p); RadixSort(p,10,2); printf(" 最终结果\t"); /*输出最终结果*/ DispLink(p); printf("\n"); }
int main(void) { // Note: Since LENGTH is #defined, we don't need to do this dynamically... int i, *array = malloc(sizeof(int) * LENGTH); // Seed the random number generator. srand(time(NULL)); // Populate our array with random numbers on the range [0, 99]. for (i = 0; i < LENGTH; i++) array[i] = rand() % 100; // Print the unsorted array. printf("Unsorted array:\n"); printArray(array, LENGTH); // Sort the array. RadixSort(array, LENGTH); // Print the sorted array. printf("Sorted array:\n"); printArray(array, LENGTH); return 0; }
void test_radix_sort_with_three_element(void){ int array[3]={30,188,2}; int largestNum = getLargestNum(&array[0],3); int sigNum = getSignificantNum(largestNum); RadixSort(&array[0],3,sigNum); TEST_ASSERT_EQUAL(2,array[0]); TEST_ASSERT_EQUAL(30,array[1]); TEST_ASSERT_EQUAL(188,array[2]); }
void main() /*main function*/ { SLList L; printf("RadixSort.cpp \n"); printf("============= \n"); InitExample(&L); /*For example*/ RadixSort(&L); /*RadixSort */ /*cout<<endl; */ getch(); }
void test_simple_number(void){ int array[4] = {3,4,1,2}; int largestNum = getLargestNum(&array[0],4); int sigNum = getSignificantNum(largestNum); RadixSort(&array[0],4,sigNum); TEST_ASSERT_EQUAL(1,array[0]); TEST_ASSERT_EQUAL(2,array[1]); TEST_ASSERT_EQUAL(3,array[2]); TEST_ASSERT_EQUAL(4,array[3]); }
void test_radix_sort_with_five_element(void){ int array[5]={3,30,188,2,1945}; int largestNum = getLargestNum(&array[0],5); int sigNum = getSignificantNum(largestNum); RadixSort(&array[0],5,sigNum); TEST_ASSERT_EQUAL(2,array[0]); TEST_ASSERT_EQUAL(3,array[1]); TEST_ASSERT_EQUAL(30,array[2]); TEST_ASSERT_EQUAL(188,array[3]); TEST_ASSERT_EQUAL(1945,array[4]); }
void RadixSortEmptyVector() { Vector* vec = NULL; vec = VectorCreate(100, 100); RadixSort(vec, 1); printf("SortEmptyVector..................OK\n"); VectorDestroy(vec); }
int main() { int num[20]; ini(num,20); print(num, 20); //BubbleSort(num, 20); //InsertionSort(num, 20); //MergeSort(num, 0, 19); //BucketSort(num, 20); RadixSort(num, 20); print(num, 20); system("pause"); return 0; }
int main() { int arrData[10] = {2, 46, 5, 17, 2, 3, 99, 12, 66, 21}; printf("[********** Before RadixSort **********]\n"); Output(arrData, sizeof(arrData) / sizeof(int)); RadixSort(arrData, sizeof(arrData) / sizeof(int), 10); printf("[********** After RadixSort **********]\n"); Output(arrData, sizeof(arrData) / sizeof(int)); return 0; }
auto TestRadixSortingInternal(const std::vector<TElem> &data) { // verify the algorithm auto sample = data; RadixSort(sample.begin(), sample.end()); if (!std::is_sorted(sample.begin(), sample.end(), std::less<TElem>())) { throw std::runtime_error("algorithm not working"); } // evaluate the algorithm using clock = std::chrono::high_resolution_clock; std::vector<std::vector<TElem>> testbench(TestRepetition, data); auto first_tick = clock::now(); for (size_t i = 0; i < TestRepetition; ++i) { auto &target = testbench[i]; RadixSort(std::begin(target), std::end(target)); } auto last_tick = clock::now(); return std::chrono::duration_cast<microseconds_t>(last_tick - first_tick) / TestRepetition; }
void main() { DataType d[N]={268,126,63,730,587,184}; SList L; InitList(&L,d,N); printf("待排序元素个数是%d个,关键字个数为%d个\n",L.length,L.keynum); printf("排序前的元素:\n"); PrintList2(L); printf("排序前的元素的存放位置:\n"); PrintList(L); RadixSort(&L); printf("排序后元素的存放位置:\n"); PrintList(L); system("pause"); }
int main(int argc, char *argv[]) { if (argc == 1) { printf("%s\n", L_NAME); printf("usage: ./quick [data_size] [data_init type]\n"); printf(" data_init type : random, sorted, reverse, xorshift\n"); exit(1); } if (argc != 3) { printf("Error! The number of argument is wrong.\n"); exit(1); } DATANUM = atoi(argv[1])*1024*1024; data = (int*)malloc(sizeof(int)*DATANUM); temp = (int*)malloc(sizeof(int)*DATANUM); radix = (int*)malloc(sizeof(int)*DATANUM); int i; long long start; long long end; /* ----- Initialization ----- */ printf("# sort elements n = %d\n", DATANUM); data_init(argv[2]); for (i = 0; i < SHOWNUM; i++) printf("%d ", data[i]); printf("\n"); /* ----- Measurement of Sort Process Time ----- */ int radix_max = 1000000000; start = get_time(); RadixSort(data, DATANUM, radix_max); end = get_time(); /* ----- Show Results ----- */ for (i = 0; i < SHOWNUM; i++) printf("%d ", data[i]); printf("\n"); printf("# elasped time:%9.3f sec\n", (end - start)/1000000.0); free(data); free(temp); free(radix); return 0; }
int main() { /*int input[10] = { 23,12,4,775,245,67,2,3,18,3}; quicksort(input, 0, 9); for (int i = 0 ; i < 10; i++) printf("%d, ",input[i]);*/ char* input[16] = {"COW", "DOG","SEA", "RUG", "ROW", "MOB", "BOX", "TAB", "BAR", "EAR", "TAR", "DIG", "BIG", "TEA", "NOW", "FOX"}; RadixSort(input, 16, 3); return 0; }
void Algo10_11_main() { RedType d[N]={{278,1},{109,2},{63,3},{930,4},{589,5},{184,6},{505,7},{269,8},{8,9},{83,10}}; SLList l; int *adr; InitList(l,d,N); printf("排序前(next域还没赋值):\n"); print(l); RadixSort(l); printf("排序后(静态链表):\n"); print(l); adr=(int*)malloc((l.recnum)*sizeof(int)); Sort(l,adr); Rearrange(l,adr); printf("排序后(重排记录):\n"); print(l); }
int main() { int n, i; int a[MAX]; printf("请输入数目\n"); scanf("%d", &n); n = n > MAX ? MAX : n; printf("按顺序输入数据\n"); for(i = 0;i < n;i++){ scanf("%d", &a[i]); } RadixSort(a, n); for(i = 0;i < n;i++){ printf("%d ", a[i]); } return 0; }
void test_radix_sort_with_many_elements(void){ int array[13]={3,30,188,2,1945,4444,12394,11,90,1,345,39384,119282}; int largestNum = getLargestNum(&array[0],13); int sigNum = getSignificantNum(largestNum); RadixSort(&array[0],13,sigNum); TEST_ASSERT_EQUAL(1,array[0]); TEST_ASSERT_EQUAL(2,array[1]); TEST_ASSERT_EQUAL(3,array[2]); TEST_ASSERT_EQUAL(11,array[3]); TEST_ASSERT_EQUAL(30,array[4]); TEST_ASSERT_EQUAL(90,array[5]); TEST_ASSERT_EQUAL(188,array[6]); TEST_ASSERT_EQUAL(345,array[7]); TEST_ASSERT_EQUAL(1945,array[8]); TEST_ASSERT_EQUAL(4444,array[9]); TEST_ASSERT_EQUAL(12394,array[10]); TEST_ASSERT_EQUAL(39384,array[11]); TEST_ASSERT_EQUAL(119282,array[12]); }
void MassiveRadixSortTest() { int vectorSize, i, j; int num1, num2; Vector* vec; srand(time(NULL)); for(j = 0; j < RUNS; j++) { vectorSize = rand() % MAX_VECTOR_SIZE; vec = VectorCreate(vectorSize, 100); for(i = 0; i < vectorSize; i++) { VectorAdd(vec, rand() % MAX_NUMBER); } RadixSort(vec, 3); VectorDelete(vec, &num1); for(i = 0; i < vectorSize - 1; i++) { VectorDelete(vec, &num2); if(num2 > num1) { printf("MassiveSortTest..................FAIL\n"); VectorDestroy(vec); return; } num1 = num2; } VectorDestroy(vec); } printf("MassiveSortTest..................OK\n"); }
int testRadixSort(int* arr, int size) { if(arr == NULL) { return -1; } printf("RadixSort\nbefore:"); for(int i = 0; i < MAX_ARR_NUM; ++i) { arr[i] = rand() % MAX_NUM; printf("%d ,", arr[i]); } printf("\nafter:"); RadixSort(arr, MAX_ARR_NUM, 10); for(int i = 0; i < MAX_ARR_NUM; ++i) { printf("%d ,", arr[i]); } printf("\n"); return 0; }
void SimpleRadixSort() { Vector* vec; int a; vec = VectorCreate(100, 100); VectorAdd(vec, 46); VectorAdd(vec, 2); VectorAdd(vec, 83); VectorAdd(vec, 41); VectorAdd(vec, 102); VectorAdd(vec, 5); VectorAdd(vec, 17); VectorAdd(vec, 31); VectorAdd(vec, 64); VectorAdd(vec, 49); VectorAdd(vec, 18); RadixSort(vec, 3); VectorDelete(vec, &a); VectorDelete(vec, &a); VectorDelete(vec, &a); if(a == 64) { printf("SimpleSort..................OK\n"); } else { printf("SimpleSort..................FAIL\n"); } VectorDestroy(vec); }
void SimpleRadixSortForSingleMember() { Vector* vec; int a; vec = VectorCreate(100, 100); VectorAdd(vec, 5); RadixSort(vec, 1); VectorDelete(vec, &a); if(a == 5) { printf("SimpleSortForSingleMember..................OK\n"); } else { printf("SimpleSortForSingleMember..................FAIL\n"); } VectorDestroy(vec); }
void SimpleContactSolver::solveContacts(unsigned numContacts, CUDABuffer * contactBuf, CUDABuffer * pairBuf, void * objectData) { #if DISABLE_COLLISION_RESOLUTION return; #endif if(numContacts < 1) return; #if 0 svlg.writeInt2( pairBuf, numContacts, "pair", CudaDbgLog::FAlways); #endif const unsigned indBufLength = iRound1024(numContacts * 2); m_sortedInd[0]->create(indBufLength * 8); m_sortedInd[1]->create(indBufLength * 8); void * bodyContactHash = m_sortedInd[0]->bufferOnDevice(); void * pairs = pairBuf->bufferOnDevice(); /* * for either side of each contact pair, set * key: body index * velue: contact index * n x 2 hash * sort by body index to put the same body together */ simpleContactSolverWriteContactIndex((KeyValuePair *)bodyContactHash, (uint *)pairs, numContacts * 2, indBufLength); void * tmp = m_sortedInd[1]->bufferOnDevice(); RadixSort((KeyValuePair *)bodyContactHash, (KeyValuePair *)tmp, indBufLength, 30); #if 0 svlg.writeHash( m_sortedInd[0], numContacts * 2, "body-contact", CudaDbgLog::FAlways); #endif /* * for each hash, find the index of contact pair * set the indirection from contact pair to hash index */ m_splitPair->create(numContacts * 8); void * splits = m_splitPair->bufferOnDevice(); const unsigned splitBufLength = numContacts * 2; simpleContactSolverComputeSplitBufLoc((uint2 *)splits, (uint2 *)pairs, (KeyValuePair *)bodyContactHash, splitBufLength); #if 0 svlg.writeInt2( m_splitPair, numContacts, "splitpair", CudaDbgLog::FAlways); #endif m_bodyCount->create(splitBufLength * 4); void * bodyCount = m_bodyCount->bufferOnDevice(); simpleContactSolverCountBody((uint *)bodyCount, (KeyValuePair *)bodyContactHash, splitBufLength); #if 0 // num iterattions by max contacts per object // todo ignore static object count int mxcount = 0; max<int>(mxcount, (int *)bodyCount, splitBufLength); int numiterations = mxcount + 3; #else int numiterations = 9; #endif m_splitInverseMass->create(splitBufLength * 4); void * splitMass = m_splitInverseMass->bufferOnDevice(); CudaNarrowphase::CombinedObjectBuffer * objectBuf = (CudaNarrowphase::CombinedObjectBuffer *)objectData; void * pos = objectBuf->m_pos->bufferOnDevice(); void * vel = objectBuf->m_vel->bufferOnDevice(); void * mass = objectBuf->m_mass->bufferOnDevice(); void * linearImpulse = objectBuf->m_linearImpulse->bufferOnDevice(); void * ind = objectBuf->m_ind->bufferOnDevice(); void * perObjPointStart = objectBuf->m_pointCacheLoc->bufferOnDevice(); void * perObjectIndexStart = objectBuf->m_indexCacheLoc->bufferOnDevice(); m_bodyTetInd->create(4* 4 * numContacts *2); simpleContactSolverComputeSplitInverseMass((float *)splitMass, (uint2 *)splits, (uint2 *)pairs, (float *)mass, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, (uint *)bodyCount, (uint4 *)m_bodyTetInd->bufferOnDevice(), numContacts * 2); #if 0 // svlg.writeFlt( m_splitInverseMass, // numContacts, // "masstensor", CudaDbgLog::FAlways); svlg.writeUInt( objectBuf->m_pointCacheLoc, 2, "pstart", CudaDbgLog::FAlways); svlg.writeUInt( objectBuf->m_indexCacheLoc, 2, "istart", CudaDbgLog::FAlways); #endif m_constraint->create(numContacts * 64); m_contactLinearVelocity->create(numContacts * 2 * 12); void * constraint = m_constraint->bufferOnDevice(); void * contactLinearVel = m_contactLinearVelocity->bufferOnDevice(); void * contacts = contactBuf->bufferOnDevice(); contactconstraint::prepareNoPenetratingContact((ContactConstraint *)constraint, (float3 *)contactLinearVel, (uint2 *)splits, (uint2 *)pairs, (float3 *)pos, (float3 *)vel, (float3 *)linearImpulse, (float *)splitMass, (ContactData *)contacts, (uint4 *)m_bodyTetInd->bufferOnDevice(), numContacts * 2); CudaBase::CheckCudaError("jacobi solver prepare constraint"); #if 0 svlg.writeUInt( m_bodyTetInd, numContacts * 8, "tet", CudaDbgLog::FAlways); #endif #if 0 svlg.writeFlt( contactBuf, numContacts * 12, "contact", CudaDbgLog::FAlways); #endif #if 0 svlg.writeStruct(m_constraint, numContacts, "constraint", constraintDesc, 64, CudaDbgLog::FAlways); // svlg.writeVec3(m_contactLinearVelocity, numContacts * 2, // "contact_vel", CudaDbgLog::FAlways); #endif m_deltaLinearVelocity->create(nextPow2(splitBufLength * 12)); m_deltaAngularVelocity->create(nextPow2(splitBufLength * 12)); void * deltaLinVel = m_deltaLinearVelocity->bufferOnDevice(); void * deltaAngVel = m_deltaAngularVelocity->bufferOnDevice(); simpleContactSolverClearDeltaVelocity((float3 *)deltaLinVel, (float3 *)deltaAngVel, splitBufLength); int i; for(i=0; i< numiterations; i++) { // compute impulse and velocity changes per contact collisionres::resolveCollision((ContactConstraint *)constraint, (float3 *)contactLinearVel, (float3 *)deltaLinVel, (uint2 *)pairs, (uint2 *)splits, (float *)splitMass, (ContactData *)contacts, numContacts * 2); CudaBase::CheckCudaError("jacobi solver resolve collision"); #if 0 unsigned ii = i; svlg.write(ii); #endif #if 0 svlg.writeVec3(m_deltaLinearVelocity, numContacts * 2, "deltaV_b4", CudaDbgLog::FAlways); #endif simpleContactSolverAverageVelocities((float3 *)deltaLinVel, (float3 *)deltaAngVel, (uint *)bodyCount, (KeyValuePair *)bodyContactHash, splitBufLength); CudaBase::CheckCudaError("jacobi solver average velocity"); #if 0 svlg.writeVec3(m_deltaLinearVelocity, numContacts * 2, "deltaV_avg", CudaDbgLog::FAlways); #endif collisionres::resolveFriction((ContactConstraint *)constraint, (float3 *)contactLinearVel, (float3 *)deltaLinVel, (uint2 *)pairs, (uint2 *)splits, (float *)splitMass, (ContactData *)contacts, numContacts * 2); CudaBase::CheckCudaError("jacobi solver resolve friction"); simpleContactSolverAverageVelocities((float3 *)deltaLinVel, (float3 *)deltaAngVel, (uint *)bodyCount, (KeyValuePair *)bodyContactHash, splitBufLength); CudaBase::CheckCudaError("jacobi solver average velocity"); } // 2 tet per contact, 4 pnt per tet, key is pnt index, value is tet index in split const unsigned pntHashBufLength = iRound1024(numContacts * 2 * 4); // std::cout<<"\n pntHashBufLength"<<pntHashBufLength // <<" numContact"<<numContacts; m_pntTetHash[0]->create(pntHashBufLength * 8); m_pntTetHash[1]->create(pntHashBufLength * 8); void * pntTetHash = m_pntTetHash[0]->bufferOnDevice(); simpleContactSolverWritePointTetHash((KeyValuePair *)pntTetHash, (uint2 *)pairs, (uint2 *)splits, (uint *)bodyCount, (uint4 *)m_bodyTetInd->bufferOnDevice(), numContacts * 2, pntHashBufLength); CudaBase::CheckCudaError(// CudaBase::Synchronize(), "jacobi solver point-tetra hash"); void * intermediate = m_pntTetHash[1]->bufferOnDevice(); RadixSort((KeyValuePair *)pntTetHash, (KeyValuePair *)intermediate, pntHashBufLength, 24); #if 0 svlg.writeHash(m_pntTetHash[1], numContacts * 2, "pnttet_hash", CudaDbgLog::FAlways); #endif contactsolver::updateImpulse((float3 *)linearImpulse, (float3 *)deltaLinVel, (float3 *)deltaAngVel, (KeyValuePair *)pntTetHash, (uint2 *)pairs, (uint2 *)splits, (ContactConstraint *)constraint, (ContactData *)contacts, (float3 *)pos, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, numContacts * 2 * 4); CudaBase::CheckCudaError(// CudaBase::Synchronize(), "jacobi solver update velocity"); }
BVHBuildNode *BVHAccel::HLBVHBuild( MemoryArena &arena, const std::vector<BVHPrimitiveInfo> &primitiveInfo, int *totalNodes, std::vector<std::shared_ptr<Primitive>> &orderedPrims) const { // Compute bounding box of all primitive centroids Bounds3f bounds; for (const BVHPrimitiveInfo &pi : primitiveInfo) bounds = Union(bounds, pi.centroid); // Compute Morton indices of primitives std::vector<MortonPrimitive> mortonPrims(primitiveInfo.size()); ParallelFor([&](int i) { // Initialize _mortionPrims[i]_ for _i_th primitive constexpr int mortonBits = 10; constexpr int mortonScale = 1 << mortonBits; mortonPrims[i].primitiveIndex = primitiveInfo[i].primitiveNumber; Vector3f centroidOffset = bounds.Offset(primitiveInfo[i].centroid); mortonPrims[i].mortonCode = EncodeMorton3(centroidOffset * mortonScale); }, primitiveInfo.size(), 512); // Radix sort primitive Morton indices RadixSort(&mortonPrims); // Create LBVH treelets at bottom of BVH // Find intervals of primitives for each treelet std::vector<LBVHTreelet> treeletsToBuild; for (int start = 0, end = 1; end <= (int)mortonPrims.size(); ++end) { uint32_t mask = 0b00111111111111000000000000000000; if (end == (int)mortonPrims.size() || ((mortonPrims[start].mortonCode & mask) != (mortonPrims[end].mortonCode & mask))) { // Add entry to _treeletsToBuild_ for this treelet int nPrimitives = end - start; int maxBVHNodes = 2 * nPrimitives; BVHBuildNode *nodes = arena.Alloc<BVHBuildNode>(maxBVHNodes, false); treeletsToBuild.push_back({start, nPrimitives, nodes}); start = end; } } // Create LBVHs for treelets in parallel std::atomic<int> atomicTotal(0), orderedPrimsOffset(0); orderedPrims.resize(primitives.size()); ParallelFor([&](int i) { // Generate _i_th LBVH treelet int nodesCreated = 0; const int firstBitIndex = 29 - 12; LBVHTreelet &tr = treeletsToBuild[i]; tr.buildNodes = emitLBVH(tr.buildNodes, primitiveInfo, &mortonPrims[tr.startIndex], tr.nPrimitives, &nodesCreated, orderedPrims, &orderedPrimsOffset, firstBitIndex); atomicTotal += nodesCreated; }, treeletsToBuild.size()); *totalNodes = atomicTotal; // Create and return SAH BVH from LBVH treelets std::vector<BVHBuildNode *> finishedTreelets; finishedTreelets.reserve(treeletsToBuild.size()); for (LBVHTreelet &treelet : treeletsToBuild) finishedTreelets.push_back(treelet.buildNodes); return buildUpperSAH(arena, finishedTreelets, 0, finishedTreelets.size(), totalNodes); }
int main(){ ArrayInit(array); ArrayView(array); RadixSort(array); ArrayView(array); }
BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primitiveInfo, int *totalNodes, CONST_VECTOR_OBJECT &orderedPrims ) { // Compute bounding box of all primitive centroids CBBOX bounds; bounds.Reset(); for( unsigned int i = 0; i < primitiveInfo.size(); ++i ) bounds.Union( primitiveInfo[i].centroid ); // Compute Morton indices of primitives std::vector<MortonPrimitive> mortonPrims( primitiveInfo.size() ); for( int i = 0; i < (int)primitiveInfo.size(); ++i ) { // Initialize _mortonPrims[i]_ for _i_th primitive const int mortonBits = 10; const int mortonScale = 1 << mortonBits; wxASSERT( primitiveInfo[i].primitiveNumber < (int)primitiveInfo.size() ); mortonPrims[i].primitiveIndex = primitiveInfo[i].primitiveNumber; const SFVEC3F centroidOffset = bounds.Offset( primitiveInfo[i].centroid ); wxASSERT( (centroidOffset.x >= 0.0f) && (centroidOffset.x <= 1.0f) ); wxASSERT( (centroidOffset.y >= 0.0f) && (centroidOffset.y <= 1.0f) ); wxASSERT( (centroidOffset.z >= 0.0f) && (centroidOffset.z <= 1.0f) ); mortonPrims[i].mortonCode = EncodeMorton3( centroidOffset * SFVEC3F( (float)mortonScale ) ); } // Radix sort primitive Morton indices RadixSort( &mortonPrims ); // Create LBVH treelets at bottom of BVH // Find intervals of primitives for each treelet std::vector<LBVHTreelet> treeletsToBuild; for( int start = 0, end = 1; end <= (int)mortonPrims.size(); ++end ) { const uint32_t mask = 0b00111111111111000000000000000000; if( (end == (int)mortonPrims.size()) || ( (mortonPrims[start].mortonCode & mask) != (mortonPrims[end].mortonCode & mask) ) ) { // Add entry to _treeletsToBuild_ for this treelet const int numPrimitives = end - start; const int maxBVHNodes = 2 * numPrimitives; // !TODO: implement a memory arena BVHBuildNode *nodes = static_cast<BVHBuildNode *>( _mm_malloc( maxBVHNodes * sizeof( BVHBuildNode ), L1_CACHE_LINE_SIZE ) ); m_addresses_pointer_to_mm_free.push_back( nodes ); for( int i = 0; i < maxBVHNodes; ++i ) { nodes[i].bounds.Reset(); nodes[i].firstPrimOffset = 0; nodes[i].nPrimitives = 0; nodes[i].splitAxis = 0; nodes[i].children[0] = NULL; nodes[i].children[1] = NULL; } LBVHTreelet tmpTreelet; tmpTreelet.startIndex = start; tmpTreelet.numPrimitives = numPrimitives; tmpTreelet.buildNodes = nodes; treeletsToBuild.push_back( tmpTreelet ); start = end; } } // Create LBVHs for treelets in parallel int atomicTotal = 0; int orderedPrimsOffset = 0; orderedPrims.resize( m_primitives.size() ); for( int index = 0; index < (int)treeletsToBuild.size(); ++index ) { // Generate _index_th LBVH treelet int nodesCreated = 0; const int firstBit = 29 - 12; LBVHTreelet &tr = treeletsToBuild[index]; wxASSERT( tr.startIndex < (int)mortonPrims.size() ); tr.buildNodes = emitLBVH( tr.buildNodes, primitiveInfo, &mortonPrims[tr.startIndex], tr.numPrimitives, &nodesCreated, orderedPrims, &orderedPrimsOffset, firstBit ); atomicTotal += nodesCreated; } *totalNodes = atomicTotal; // Initialize _finishedTreelets_ with treelet root node pointers std::vector<BVHBuildNode *> finishedTreelets; finishedTreelets.reserve( treeletsToBuild.size() ); for( int index = 0; index < (int)treeletsToBuild.size(); ++index ) finishedTreelets.push_back( treeletsToBuild[index].buildNodes ); // Create and return SAH BVH from LBVH treelets return buildUpperSAH( finishedTreelets, 0, finishedTreelets.size(), totalNodes ); }
void SimpleContactSolver::solveContacts(unsigned numContacts, CUDABuffer * contactBuf, CUDABuffer * pairBuf, void * objectData) { #if DISABLE_COLLISION_RESOLUTION return; #endif if(numContacts < 1) return; m_numContacts = numContacts; const unsigned indBufLength = iRound1024(numContacts * 2); m_sortedInd[0]->create(indBufLength * 8); m_sortedInd[1]->create(indBufLength * 8); void * bodyContactHash = m_sortedInd[0]->bufferOnDevice(); void * pairs = pairBuf->bufferOnDevice(); simpleContactSolverWriteContactIndex((KeyValuePair *)bodyContactHash, (uint *)pairs, numContacts * 2, indBufLength); void * tmp = m_sortedInd[1]->bufferOnDevice(); RadixSort((KeyValuePair *)bodyContactHash, (KeyValuePair *)tmp, indBufLength, 30); m_splitPair->create(numContacts * 8); void * splits = m_splitPair->bufferOnDevice(); const unsigned splitBufLength = numContacts * 2; simpleContactSolverComputeSplitBufLoc((uint2 *)splits, (uint2 *)pairs, (KeyValuePair *)bodyContactHash, splitBufLength); m_bodyCount->create(splitBufLength * 4); void * bodyCount = m_bodyCount->bufferOnDevice(); simpleContactSolverCountBody((uint *)bodyCount, (KeyValuePair *)bodyContactHash, splitBufLength); int mxcount = 0; max<int>(mxcount, (int *)bodyCount, splitBufLength); // if(mxcount>9) std::cout<<" max count per contact "<<mxcount; int numiterations = mxcount + 3; m_splitInverseMass->create(splitBufLength * 4); void * splitMass = m_splitInverseMass->bufferOnDevice(); CudaNarrowphase::CombinedObjectBuffer * objectBuf = (CudaNarrowphase::CombinedObjectBuffer *)objectData; void * pos = objectBuf->m_pos->bufferOnDevice(); void * vel = objectBuf->m_vel->bufferOnDevice(); void * mass = objectBuf->m_mass->bufferOnDevice(); void * ind = objectBuf->m_ind->bufferOnDevice(); void * perObjPointStart = objectBuf->m_pointCacheLoc->bufferOnDevice(); void * perObjectIndexStart = objectBuf->m_indexCacheLoc->bufferOnDevice(); simpleContactSolverComputeSplitInverseMass((float *)splitMass, (uint2 *)splits, (uint2 *)pairs, (float *)mass, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, (uint *)bodyCount, splitBufLength); m_constraint->create(numContacts * 64); void * constraint = m_constraint->bufferOnDevice(); void * contacts = contactBuf->bufferOnDevice(); simpleContactSolverSetContactConstraint((ContactConstraint *)constraint, (uint2 *)splits, (uint2 *)pairs, (float3 *)pos, (float3 *)vel, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, (float *)splitMass, (ContactData *)contacts, numContacts * 2); CudaBase::CheckCudaError("jacobi solver set constraint"); m_deltaLinearVelocity->create(nextPow2(splitBufLength * 12)); m_deltaAngularVelocity->create(nextPow2(splitBufLength * 12)); void * deltaLinVel = m_deltaLinearVelocity->bufferOnDevice(); void * deltaAngVel = m_deltaAngularVelocity->bufferOnDevice(); simpleContactSolverClearDeltaVelocity((float3 *)deltaLinVel, (float3 *)deltaAngVel, splitBufLength); /* const unsigned scanBufLength = iRound1024(numContacts * 2); m_bodyCount->create(scanBufLength * 4); m_scanBodyCount[0]->create(scanBufLength * 4); m_scanBodyCount[1]->create(scanBufLength * 4); void * scanResult = m_scanBodyCount[0]->bufferOnDevice(); void * scanIntermediate = m_scanBodyCount[1]->bufferOnDevice(); scanExclusive((uint *)scanResult, (uint *)bodyCount, (uint *)scanIntermediate, scanBufLength / 1024, 1024); const unsigned numSplitBodies = ScanUtil::getScanResult(m_bodyCount, m_scanBodyCount[0], scanBufLength); */ int i; for(i=0; i< numiterations; i++) { // compute impulse and velocity changes per contact simpleContactSolverSolveContactWoJ((ContactConstraint *)constraint, (float3 *)deltaLinVel, (float3 *)deltaAngVel, (uint2 *)pairs, (uint2 *)splits, (float *)splitMass, (ContactData *)contacts, (float3 *)pos, (float3 *)vel, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, numContacts * 2); CudaBase::CheckCudaError("jacobi solver solve impulse"); simpleContactSolverAverageVelocities((float3 *)deltaLinVel, (float3 *)deltaAngVel, (uint *)bodyCount, (KeyValuePair *)bodyContactHash, splitBufLength); CudaBase::CheckCudaError("jacobi solver average velocity"); } // 2 tet per contact, 4 pnt per tet, key is pnt index, value is tet index in split const unsigned pntHashBufLength = iRound1024(numContacts * 2 * 4); // std::cout<<"\n pntHashBufLength"<<pntHashBufLength // <<" numContact"<<numContacts; m_pntTetHash[0]->create(pntHashBufLength * 8); m_pntTetHash[1]->create(pntHashBufLength * 8); void * pntTetHash = m_pntTetHash[0]->bufferOnDevice(); simpleContactSolverWritePointTetHash((KeyValuePair *)pntTetHash, (uint2 *)pairs, (uint2 *)splits, (uint *)bodyCount, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, numContacts * 2, pntHashBufLength); CudaBase::CheckCudaError(CudaBase::Synchronize(), "jacobi solver point-tetra hash"); void * intermediate = m_pntTetHash[1]->bufferOnDevice(); RadixSort((KeyValuePair *)pntTetHash, (KeyValuePair *)intermediate, pntHashBufLength, 24); #if 0 svlg.writeHash(m_pntTetHash[1], numContacts * 2, "pnttet_hash", CudaDbgLog::FAlways); #endif simpleContactSolverUpdateVelocity((float3 *)vel, (float3 *)deltaLinVel, (float3 *)deltaAngVel, (KeyValuePair *)pntTetHash, (uint2 *)pairs, (uint2 *)splits, (ContactConstraint *)constraint, (ContactData *)contacts, (float3 *)pos, (uint4 *)ind, (uint * )perObjPointStart, (uint * )perObjectIndexStart, numContacts * 2 * 4); CudaBase::CheckCudaError(CudaBase::Synchronize(), "jacobi solver update velocity"); }